Subversion Repository Public Repository

Nextrek

Diff Revisions 1085 vs 1086 for /s2s/data/19D5B266K1082A4D01S85D0E17BE2BBA69F8.json

Diff revisions: vs.
  @@ -6,10 +6,10 @@
6 6 "name": "Object_Base",
7 7 "type": "game_script",
8 8 "order": 0,
9 - "content": "# ===================================================================\n#\n# Script: Object_Base\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\nclass Object_Base\n ###*\n * Called if this object instance is restored from a data-bundle. It can be used\n * re-assign event-handler, anonymous functions, etc.\n * \n * @method onDataBundleRestore.\n * @param Object data - The data-bundle\n * @param gs.ObjectCodecContext context - The codec-context.\n ###\n onDataBundleRestore: (data, context) ->\n if @id\n window[\"$\"+@id] = this\n \n \n #\n # Gets or sets the group the object belongs to.\n #\n # @property group\n # @type string\n #\n @accessors \"group\", \n set: (g) -> \n @group_ = g\n gs.ObjectManager.current?.addToGroup(this, g)\n \n get: -> @group_\n \n #\n # Gets or sets the order-index of the object. The lower the index, the\n # earlier the object will be updated in a list of sub-objects.\n #\n # @property order\n # @type number\n #\n @accessors \"order\",\n set: (o) ->\n if o != @order_\n @order_ = o\n @parent?.needsSort = true\n get: -> @order_\n \n #\n # Gets or sets if an objects needs an update. If true, the parent will update\n # the object in the next update and resets the needsUpdate property back\n # to false.\n #\n # @property needsUpdate\n # @type boolean\n #\n @accessors \"needsUpdate\", \n set: (v) ->\n @needsUpdate_ = v\n \n parent = @parent\n while parent\n parent.needsUpdate_ = yes\n parent = parent.parent\n \n #if v\n # @parent?.needsUpdate = yes\n #if v\n # for object in @subObjects\n # object.needsUpdate_ = v\n if v\n @requestSubUpdate()\n get: -> return @needsUpdate_ || SceneManager.scene.preparing\n \n requestSubUpdate: ->\n for object in @subObjects\n if object\n object.needsUpdate_ = yes\n object.requestSubUpdate()\n \n return null\n #\n # Gets or sets if an object needs a full update. A full update triggers\n # an update for all sub-objects recursively. \n #\n # @property needsFullUpdate\n # @type boolean\n #\n @accessors \"needsFullUpdate\", \n set: (v) ->\n @needsUpdate = v\n if v\n for object in @subObjects\n object.needsFullUpdate = v\n get: -> @needsUpdate_\n \n ###*\n * The base class for all game objects. A game object itself doesn't implement\n * any game logic but uses components and sub-objects for that.\n *\n * @module gs\n * @class Object_Base\n * @memberof gs\n * @constructor\n ###\n constructor: () ->\n ###*\n * @property subObjects\n * @type gs.Object_Base[]\n * @default []\n * A list of game-objects grouped under this game object.\n ###\n @subObjects = []\n \n ###*\n * @property components\n * @type gs.Component[]\n * @default []\n * A list of components defining the logic/behavior and appearance of the game object.\n ###\n @components = []\n \n ###*\n * @property componentsById\n * @type Object\n * @default []\n * All associated components by their ID.\n ###\n @componentsById = {}\n \n ###*\n * @property disposed\n * @type boolean\n * @default false\n * Indicates if the game object id disposed. A disposed game object cannot be used anymore.\n ###\n @disposed = no\n \n ###*\n * @property active\n * @default true\n * Indicates if the game object is active. An inactive game object will not be updated.\n ###\n @active = yes\n \n @input = no\n \n ###*\n * @property id\n * @type string\n * @default null\n * The game object's UID (Unique ID)\n ###\n @id = null \n \n ###*\n * @property group\n * @default null\n * @type string\n * The game object's group. To get all object's of a specific group the gs.ObjectManager.objectsByGroup property can be used.\n ###\n @group = null \n \n ###*\n * @property parent\n * @type gs.Object_Base\n * @default null\n * The parent object if the game object is a sub-object of another game object.\n ###\n @parent = null\n \n ###*\n * @property order\n * @type number\n * @default 0\n * Controls the update-order. The smaller the value the earlier the game object is updated before other game objects are updated.\n ###\n @order = 0\n \n ###*\n * @property rIndex\n * @type number\n * @default 0\n * Holds the render-index if the game object has a graphical representation on screen. The render-index is the\n * index of the game object's graphic-object(gs.GraphicObject) in the current list of graphic-objects. The render-index\n * is read-only. Setting the render-index to a certain value has no effect.\n ###\n @rIndex = 0\n \n ###*\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the list of sub-objects needs to be sorted by order because of a change.\n ###\n @needsSort = yes\n \n ###*\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the UI object needs to be updated.\n ###\n @needsUpdate = yes\n \n ###*\n * @property initialized\n * @type boolean\n * @default true\n * Indicates if the game object and its components have been initialized.\n ###\n @initialized = no\n \n ###*\n * @property customData\n * @type Object\n * @default {}\n * A custom data object which can be used to add any custom data/fields to the game\n * object. It is an empty object by default.\n ###\n @customData = {}\n \n \n gs.ObjectManager.current?.registerObject(this)\n \n ###*\n * Disposes the object with all its components and sub-objects. A disposed object will be\n * removed from the parent automatically.\n *\n * @method dispose\n ###\n dispose: ->\n if not @disposed\n @disposed = yes\n @disposeComponents()\n @disposeObjects()\n \n gs.ObjectManager.current?.unregisterObject(this)\n \n return null\n \n ###*\n * Disposes all sub-objects.\n *\n * @method disposeObjects\n * @protected\n ###\n disposeObjects: ->\n for subObject in @subObjects\n subObject?.dispose?()\n \n ###*\n * Disposes all components\n *\n * @method disposeComponents\n * @protected\n ###\n disposeComponents: ->\n for component in @components\n component?.dispose?()\n \n ###*\n * Calls setup-routine on all components.\n *\n * @method setup\n ###\n setup: ->\n for component in @components\n component.setup() if not component?.isSetup\n \n @initialized = yes\n return null\n \n ###*\n * Deserializes components from a data-bundle object.\n * \n * @method componentsFromDataBundle\n * @param {Object} data The data-bundle object.\n ###\n componentsFromDataBundle: (data) ->\n if data?.components\n for component in data.components\n componentObject = new gs[component.className](component)\n @addComponent(componentObject)\n delete data.components\n \n return null\n \n ###*\n * Serializes components of a specified type to a data-bundle. A component\n * needs to implement the toDataBundle method for correct serialization.\n *\n * @method componentsToDataBundle\n * @param {String} type - A component class name.\n * @return A data bundle.\n ###\n componentsToDataBundle: (type) ->\n components = []\n for component in @components\n if component instanceof type\n continue unless component.toDataBundle?\n bundle = component.toDataBundle()\n bundle.className = component.constructor.name\n components.push(bundle)\n return components\n \n ###*\n * Starts a full-refresh on all sub-objects\n *\n * @method fullRefresh\n ###\n fullRefresh: ->\n for object in @subObjects\n if object\n object.needsUpdate = yes\n object.fullRefresh()\n \n return null\n \n ###*\n * Updates the object with all parent- and sub-objects. \n *\n * @method fullUpdate\n ###\n fullUpdate: ->\n parent = this\n while parent != null\n parent.update()\n parent = parent.parent\n \n for object in @subObjects\n object?.update()\n \n ###*\n * Updates the object and all its components. This method is\n * called automatically by the parent or ObjectManager so in regular it is \n * not necessary to call it manually.\n *\n * @method update\n ###\n update: ->\n return if !@active\n i = 0\n while i < @components.length\n component = @components[i]\n if not component.disposed\n component.update()\n i++\n else\n @components.splice(i, 1)\n\n\n if @input then Input.clear()\n @input = no\n \n return null\n \n ###*\n * Searches for the first component with the specified class name.\n *\n * @method findComponent\n * @param {String} name The class name of the component.\n * @return {Component} The component or null if a component with the specified class name cannot be found.\n ###\n findComponent: (name) -> @components.first (v) -> v.constructor.name == name\n \n ###*\n * Searches for all components with the specified class name.\n *\n * @method findComponents\n * @param {String} name The class name of the components.\n * @return {Array} The components or null if no component with the specified class name has been found.\n ###\n findComponents: (name) -> @components.where (v) -> v.constructor.name == name\n \n ###*\n * Searches for the component with the specified ID.\n *\n * @method findComponentById\n * @param {String} id The unique identifier of the component.\n * @return {Component} The component or null if a component with the specified ID cannot be found.\n ###\n findComponentById: (id) -> @componentsById[id]\n \n ###*\n * Adds an object to the list of sub-objects.\n *\n * @method addObject\n * @param {Object_Base} object The object which should be added.\n ###\n addObject: (object) ->\n gs.ObjectManager.current?.remove(object)\n object.parent?.removeObject(object)\n object.parent = this\n @subObjects.push(object)\n @needsSort = yes\n @needsUpdate = yes\n \n if object.id?\n gs.ObjectManager.current.setObjectById(object, object.id)\n \n ###*\n * Inserts an object into the list of sub-objects at the specified index.\n *\n * @method insertObject\n * @param {Object_Base} object The object which should be inserted.\n * @param {Number} index The index.\n ###\n insertObject:(object, index) ->\n gs.ObjectManager.current.remove(object)\n object.parent?.removeObject(object)\n object.parent = this\n @subObjects.splice(index, 0, object)\n \n if object.id?\n gs.ObjectManager.current.setObjectById(object, object.id)\n \n ###*\n * Sets sub-object at the specified index.\n *\n * @method setObject\n * @param {Object_Base} object The object.\n * @param {Number} index The index.\n ###\n setObject: (object, index) ->\n if object\n gs.ObjectManager.current.remove(object)\n object.parent?.removeObject(object)\n object.parent = this\n \n @subObjects[index] = object\n \n if object?.id?\n gs.ObjectManager.current.setObjectById(object, object.id)\n \n ###*\n * Removes the specified object from the list of sub-objects.\n *\n * @method removeObject\n * @param {Object_Base} object The object which should be removed.\n ###\n removeObject: (object) ->\n @subObjects.remove(object)\n object.parent = null\n @needsUpdate = yes\n \n ###*\n * Erases the object at the specified index. The list size\n * will not be changed but the the value at the index will be set to null.\n *\n * @method eraseObject\n * @param {Number} object The object which should be erased.\n ###\n eraseObject: (index) ->\n object = @subObjects[index]\n object?.parent = null\n @subObjects[index] = null\n \n ###*\n * Adds the specified component to the object.\n *\n * @method addComponent\n * @param {Component} component The component\n * @param {String} id An optional unique identifier for the component.\n ###\n addComponent: (component, id) ->\n if not @components.contains(component)\n component.object = this\n @components.push(component)\n if id?\n @componentsById[id] = component\n ###*\n * Inserts a component at the specified index.\n *\n * @method insertComponent\n * @param {Component} component The component.\n * @param {Number} index The index.\n * @param {String} id An optional unique identifier for the component.\n ### \n insertComponent: (component, index, id) ->\n @components.remove(component)\n component.object = this\n @components.splice(index, 0, component)\n if id?\n @componentsById[id] = component\n \n ###*\n * Removes a component from the object.\n *\n * @method removeComponent\n * @param {Component} component The component to remove.\n ### \n removeComponent: (component) -> \n @components.remove(component)\n if id?\n delete @componentsById[id]\n\ngs.Object_Base = Object_Base",
9 + "content": "# ===================================================================\n#\n# Script: Object_Base\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\nclass Object_Base\n ###*\n * Called if this object instance is restored from a data-bundle. It can be used\n * re-assign event-handler, anonymous functions, etc.\n * \n * @method onDataBundleRestore.\n * @param Object data - The data-bundle\n * @param gs.ObjectCodecContext context - The codec-context.\n ###\n onDataBundleRestore: (data, context) ->\n if @id\n window[\"$\"+@id] = this\n \n \n #\n # Gets or sets the group the object belongs to.\n #\n # @property group\n # @type string\n #\n @accessors \"group\", \n set: (g) -> \n @group_ = g\n gs.ObjectManager.current?.addToGroup(this, g)\n \n get: -> @group_\n \n #\n # Gets or sets the order-index of the object. The lower the index, the\n # earlier the object will be updated in a list of sub-objects.\n #\n # @property order\n # @type number\n #\n @accessors \"order\",\n set: (o) ->\n if o != @order_\n @order_ = o\n @parent?.needsSort = true\n get: -> @order_\n \n #\n # Gets or sets if an objects needs an update. If true, the parent will update\n # the object in the next update and resets the needsUpdate property back\n # to false.\n #\n # @property needsUpdate\n # @type boolean\n #\n @accessors \"needsUpdate\", \n set: (v) ->\n @needsUpdate_ = v\n \n parent = @parent\n while parent\n parent.needsUpdate_ = yes\n parent = parent.parent\n \n #if v\n # @parent?.needsUpdate = yes\n #if v\n # for object in @subObjects\n # object.needsUpdate_ = v\n if v\n @requestSubUpdate()\n get: -> return @needsUpdate_ || SceneManager.scene.preparing\n \n requestSubUpdate: ->\n for object in @subObjects\n if object\n object.needsUpdate_ = yes\n object.requestSubUpdate()\n \n return null\n #\n # Gets or sets if an object needs a full update. A full update triggers\n # an update for all sub-objects recursively. \n #\n # @property needsFullUpdate\n # @type boolean\n #\n @accessors \"needsFullUpdate\", \n set: (v) ->\n @needsUpdate = v\n if v\n for object in @subObjects\n object.needsFullUpdate = v\n get: -> @needsUpdate_\n \n ###*\n * The base class for all game objects. A game object itself doesn't implement\n * any game logic but uses components and sub-objects for that.\n *\n * @module gs\n * @class Object_Base\n * @memberof gs\n * @constructor\n ###\n constructor: () ->\n ###*\n * @property subObjects\n * @type gs.Object_Base[]\n * @default []\n * A list of game-objects grouped under this game object.\n ###\n @subObjects = []\n \n ###*\n * @property components\n * @type gs.Component[]\n * @default []\n * A list of components defining the logic/behavior and appearance of the game object.\n ###\n @components = []\n \n ###*\n * @property componentsById\n * @type Object\n * @default []\n * All associated components by their ID.\n ###\n @componentsById = {}\n \n ###*\n * @property disposed\n * @type boolean\n * @default false\n * Indicates if the game object id disposed. A disposed game object cannot be used anymore.\n ###\n @disposed = no\n \n ###*\n * @property active\n * @default true\n * Indicates if the game object is active. An inactive game object will not be updated.\n ###\n @active = yes\n \n @input = no\n \n ###*\n * @property id\n * @type string\n * @default null\n * The game object's UID (Unique ID)\n ###\n @id = null \n \n ###*\n * @property group\n * @default null\n * @type string\n * The game object's group. To get all object's of a specific group the gs.ObjectManager.objectsByGroup property can be used.\n ###\n @group = null \n \n ###*\n * @property parent\n * @type gs.Object_Base\n * @default null\n * The parent object if the game object is a sub-object of another game object.\n ###\n @parent = null\n \n ###*\n * @property order\n * @type number\n * @default 0\n * Controls the update-order. The smaller the value the earlier the game object is updated before other game objects are updated.\n ###\n @order = 0\n \n ###*\n * @property rIndex\n * @type number\n * @default 0\n * Holds the render-index if the game object has a graphical representation on screen. The render-index is the\n * index of the game object's graphic-object(gs.GraphicObject) in the current list of graphic-objects. The render-index\n * is read-only. Setting the render-index to a certain value has no effect.\n ###\n @rIndex = 0\n \n ###*\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the list of sub-objects needs to be sorted by order because of a change.\n ###\n @needsSort = yes\n \n ###*\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the UI object needs to be updated.\n ###\n @needsUpdate = yes\n \n ###*\n * @property initialized\n * @type boolean\n * @default true\n * Indicates if the game object and its components have been initialized.\n ###\n @initialized = no\n \n ###*\n * @property customData\n * @type Object\n * @default {}\n * A custom data object which can be used to add any custom data/fields to the game\n * object. It is an empty object by default.\n ###\n @customData = {}\n \n \n gs.ObjectManager.current?.registerObject(this)\n \n ###*\n * Disposes the object with all its components and sub-objects. A disposed object will be\n * removed from the parent automatically.\n *\n * @method dispose\n ###\n dispose: ->\n if not @disposed\n @disposed = yes\n @disposeComponents()\n @disposeObjects()\n \n gs.ObjectManager.current?.unregisterObject(this)\n \n return null\n \n ###*\n * Disposes all sub-objects.\n *\n * @method disposeObjects\n * @protected\n ###\n disposeObjects: ->\n for subObject in @subObjects\n subObject?.dispose?()\n \n ###*\n * Disposes all components\n *\n * @method disposeComponents\n * @protected\n ###\n disposeComponents: ->\n for component in @components\n component?.dispose?()\n \n ###*\n * Calls setup-routine on all components.\n *\n * @method setup\n ###\n setup: ->\n for component in @components\n component.setup() if not component?.isSetup\n \n @initialized = yes\n return null\n \n ###*\n * Deserializes components from a data-bundle object.\n * \n * @method componentsFromDataBundle\n * @param {Object} data The data-bundle object.\n ###\n componentsFromDataBundle: (data) ->\n if data?.components\n for component in data.components\n componentObject = new gs[component.className](component)\n @addComponent(componentObject)\n delete data.components\n \n return null\n \n ###*\n * Serializes components of a specified type to a data-bundle. A component\n * needs to implement the toDataBundle method for correct serialization.\n *\n * @method componentsToDataBundle\n * @param {String} type - A component class name.\n * @return A data bundle.\n ###\n componentsToDataBundle: (type) ->\n components = []\n for component in @components\n if component instanceof type\n continue unless component.toDataBundle?\n bundle = component.toDataBundle()\n bundle.className = component.constructor.name\n components.push(bundle)\n return components\n \n ###*\n * Starts a full-refresh on all sub-objects\n *\n * @method fullRefresh\n ###\n fullRefresh: ->\n for object in @subObjects\n if object\n object.needsUpdate = yes\n object.fullRefresh()\n \n return null\n \n ###*\n * Updates the object with all parent- and sub-objects. \n *\n * @method fullUpdate\n ###\n fullUpdate: ->\n parent = this\n while parent != null\n parent.update()\n parent = parent.parent\n \n for object in @subObjects\n object?.update()\n \n ###*\n * Updates the object and all its components. This method is\n * called automatically by the parent or ObjectManager so in regular it is \n * not necessary to call it manually.\n *\n * @method update\n ###\n update: ->\n return if !@active\n i = 0\n while i < @components.length\n component = @components[i]\n if not component.disposed\n component.update()\n i++\n else\n @components.splice(i, 1)\n\n\n if @input then Input.clear()\n @input = no\n \n return null\n \n ###*\n * Searches for the first component with the specified class name.\n *\n * @method findComponent\n * @param {String} name The class name of the component.\n * @return {Component} The component or null if a component with the specified class name cannot be found.\n ###\n findComponent: (name) -> @components.first (v) -> v.constructor.name == name\n \n ###*\n * Searches for all components with the specified class name.\n *\n * @method findComponents\n * @param {String} name The class name of the components.\n * @return {Array} The components or null if no component with the specified class name has been found.\n ###\n findComponents: (name) -> @components.where (v) -> v.constructor.name == name\n \n ###*\n * Searches for the component with the specified ID.\n *\n * @method findComponentById\n * @param {String} id The unique identifier of the component.\n * @return {Component} The component or null if a component with the specified ID cannot be found.\n ###\n findComponentById: (id) -> @componentsById[id]\n \n ###*\n * Searches for the component with the specified name. If multiple components have the\n * same name, it will return the first match.\n *\n * @method findComponentByName\n * @param {String} name The name of the component to find.\n * @return {Component} The component or null if a component with the specified name cannot be found.\n ###\n findComponentByName: (name) -> @components.first (v) -> v.name == name\n \n ###*\n * Searches for components with the specified name.\n *\n * @method findComponentsByName\n * @param {String} name The name of the components to find.\n * @return {Component[]} An array of components matching the specified name or null if no components with the specified name exist.\n ###\n findComponentsByName: (name) -> @components.where (v) -> v.name == name\n \n ###*\n * Adds an object to the list of sub-objects.\n *\n * @method addObject\n * @param {Object_Base} object The object which should be added.\n ###\n addObject: (object) ->\n gs.ObjectManager.current?.remove(object)\n object.parent?.removeObject(object)\n object.parent = this\n @subObjects.push(object)\n @needsSort = yes\n @needsUpdate = yes\n \n if object.id?\n gs.ObjectManager.current.setObjectById(object, object.id)\n \n ###*\n * Inserts an object into the list of sub-objects at the specified index.\n *\n * @method insertObject\n * @param {Object_Base} object The object which should be inserted.\n * @param {Number} index The index.\n ###\n insertObject:(object, index) ->\n gs.ObjectManager.current.remove(object)\n object.parent?.removeObject(object)\n object.parent = this\n @subObjects.splice(index, 0, object)\n \n if object.id?\n gs.ObjectManager.current.setObjectById(object, object.id)\n \n ###*\n * Sets sub-object at the specified index.\n *\n * @method setObject\n * @param {Object_Base} object The object.\n * @param {Number} index The index.\n ###\n setObject: (object, index) ->\n if object\n gs.ObjectManager.current.remove(object)\n object.parent?.removeObject(object)\n object.parent = this\n \n @subObjects[index] = object\n \n if object?.id?\n gs.ObjectManager.current.setObjectById(object, object.id)\n \n ###*\n * Removes the specified object from the list of sub-objects.\n *\n * @method removeObject\n * @param {Object_Base} object The object which should be removed.\n ###\n removeObject: (object) ->\n @subObjects.remove(object)\n object.parent = null\n @needsUpdate = yes\n \n ###*\n * Removes the object at the specified index from the list of sub-objects.\n *\n * @method removeObjectAt\n * @param {number} index The index of the objec to remove.\n ### \n removeObjectAt: (index) ->\n object = @subObjects[index]\n @subObjects.splice(index, 1)\n object.parent = null\n @needsUpdate = yes\n \n ###*\n * Removes all sub-objects.\n *\n * @method removeAllObjects\n ### \n removeAllObjects: ->\n while @subObjects.length > 0\n @removeObjectAt(0)\n \n ###*\n * Erases the object at the specified index. The list size\n * will not be changed but the the value at the index will be set to null.\n *\n * @method eraseObject\n * @param {Number} object The object which should be erased.\n ###\n eraseObject: (index) ->\n object = @subObjects[index]\n object?.parent = null\n @subObjects[index] = null\n \n ###*\n * Adds the specified component to the object.\n *\n * @method addComponent\n * @param {Component} component The component\n * @param {String} id An optional unique identifier for the component.\n ###\n addComponent: (component, id) ->\n if not @components.contains(component)\n component.object = this\n @components.push(component)\n if id?\n @componentsById[id] = component\n ###*\n * Inserts a component at the specified index.\n *\n * @method insertComponent\n * @param {Component} component The component.\n * @param {Number} index The index.\n * @param {String} id An optional unique identifier for the component.\n ### \n insertComponent: (component, index, id) ->\n @components.remove(component)\n component.object = this\n @components.splice(index, 0, component)\n if id?\n @componentsById[id] = component\n \n ###*\n * Removes a component from the object.\n *\n * @method removeComponent\n * @param {Component} component The component to remove.\n ### \n removeComponent: (component) -> \n @components.remove(component)\n if id?\n delete @componentsById[id]\n\ngs.Object_Base = Object_Base",
10 10 "parentId": "A05E7029K45DBA459BSADF4EEC07A526241A",
11 11 "folder": false,
12 - "compiledContent": "var Object_Base;\n\nObject_Base = (function() {\n\n /**\n * Called if this object instance is restored from a data-bundle. It can be used\n * re-assign event-handler, anonymous functions, etc.\n * \n * @method onDataBundleRestore.\n * @param Object data - The data-bundle\n * @param gs.ObjectCodecContext context - The codec-context.\n */\n Object_Base.prototype.onDataBundleRestore = function(data, context) {\n if (this.id) {\n return window[\"$\" + this.id] = this;\n }\n };\n\n Object_Base.accessors(\"group\", {\n set: function(g) {\n var ref;\n this.group_ = g;\n return (ref = gs.ObjectManager.current) != null ? ref.addToGroup(this, g) : void 0;\n },\n get: function() {\n return this.group_;\n }\n });\n\n Object_Base.accessors(\"order\", {\n set: function(o) {\n var ref;\n if (o !== this.order_) {\n this.order_ = o;\n return (ref = this.parent) != null ? ref.needsSort = true : void 0;\n }\n },\n get: function() {\n return this.order_;\n }\n });\n\n Object_Base.accessors(\"needsUpdate\", {\n set: function(v) {\n var parent;\n this.needsUpdate_ = v;\n parent = this.parent;\n while (parent) {\n parent.needsUpdate_ = true;\n parent = parent.parent;\n }\n if (v) {\n return this.requestSubUpdate();\n }\n },\n get: function() {\n return this.needsUpdate_ || SceneManager.scene.preparing;\n }\n });\n\n Object_Base.prototype.requestSubUpdate = function() {\n var j, len, object, ref;\n ref = this.subObjects;\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n if (object) {\n object.needsUpdate_ = true;\n object.requestSubUpdate();\n }\n }\n return null;\n };\n\n Object_Base.accessors(\"needsFullUpdate\", {\n set: function(v) {\n var j, len, object, ref, results;\n this.needsUpdate = v;\n if (v) {\n ref = this.subObjects;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n results.push(object.needsFullUpdate = v);\n }\n return results;\n }\n },\n get: function() {\n return this.needsUpdate_;\n }\n });\n\n\n /**\n * The base class for all game objects. A game object itself doesn't implement\n * any game logic but uses components and sub-objects for that.\n *\n * @module gs\n * @class Object_Base\n * @memberof gs\n * @constructor\n */\n\n function Object_Base() {\n\n /**\n * @property subObjects\n * @type gs.Object_Base[]\n * @default []\n * A list of game-objects grouped under this game object.\n */\n var ref;\n this.subObjects = [];\n\n /**\n * @property components\n * @type gs.Component[]\n * @default []\n * A list of components defining the logic/behavior and appearance of the game object.\n */\n this.components = [];\n\n /**\n * @property componentsById\n * @type Object\n * @default []\n * All associated components by their ID.\n */\n this.componentsById = {};\n\n /**\n * @property disposed\n * @type boolean\n * @default false\n * Indicates if the game object id disposed. A disposed game object cannot be used anymore.\n */\n this.disposed = false;\n\n /**\n * @property active\n * @default true\n * Indicates if the game object is active. An inactive game object will not be updated.\n */\n this.active = true;\n this.input = false;\n\n /**\n * @property id\n * @type string\n * @default null\n * The game object's UID (Unique ID)\n */\n this.id = null;\n\n /**\n * @property group\n * @default null\n * @type string\n * The game object's group. To get all object's of a specific group the gs.ObjectManager.objectsByGroup property can be used.\n */\n this.group = null;\n\n /**\n * @property parent\n * @type gs.Object_Base\n * @default null\n * The parent object if the game object is a sub-object of another game object.\n */\n this.parent = null;\n\n /**\n * @property order\n * @type number\n * @default 0\n * Controls the update-order. The smaller the value the earlier the game object is updated before other game objects are updated.\n */\n this.order = 0;\n\n /**\n * @property rIndex\n * @type number\n * @default 0\n * Holds the render-index if the game object has a graphical representation on screen. The render-index is the\n * index of the game object's graphic-object(gs.GraphicObject) in the current list of graphic-objects. The render-index\n * is read-only. Setting the render-index to a certain value has no effect.\n */\n this.rIndex = 0;\n\n /**\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the list of sub-objects needs to be sorted by order because of a change.\n */\n this.needsSort = true;\n\n /**\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the UI object needs to be updated.\n */\n this.needsUpdate = true;\n\n /**\n * @property initialized\n * @type boolean\n * @default true\n * Indicates if the game object and its components have been initialized.\n */\n this.initialized = false;\n\n /**\n * @property customData\n * @type Object\n * @default {}\n * A custom data object which can be used to add any custom data/fields to the game\n * object. It is an empty object by default.\n */\n this.customData = {};\n if ((ref = gs.ObjectManager.current) != null) {\n ref.registerObject(this);\n }\n }\n\n\n /**\n * Disposes the object with all its components and sub-objects. A disposed object will be\n * removed from the parent automatically.\n *\n * @method dispose\n */\n\n Object_Base.prototype.dispose = function() {\n var ref;\n if (!this.disposed) {\n this.disposed = true;\n this.disposeComponents();\n this.disposeObjects();\n if ((ref = gs.ObjectManager.current) != null) {\n ref.unregisterObject(this);\n }\n }\n return null;\n };\n\n\n /**\n * Disposes all sub-objects.\n *\n * @method disposeObjects\n * @protected\n */\n\n Object_Base.prototype.disposeObjects = function() {\n var j, len, ref, results, subObject;\n ref = this.subObjects;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n subObject = ref[j];\n results.push(subObject != null ? typeof subObject.dispose === \"function\" ? subObject.dispose() : void 0 : void 0);\n }\n return results;\n };\n\n\n /**\n * Disposes all components\n *\n * @method disposeComponents\n * @protected\n */\n\n Object_Base.prototype.disposeComponents = function() {\n var component, j, len, ref, results;\n ref = this.components;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n results.push(component != null ? typeof component.dispose === \"function\" ? component.dispose() : void 0 : void 0);\n }\n return results;\n };\n\n\n /**\n * Calls setup-routine on all components.\n *\n * @method setup\n */\n\n Object_Base.prototype.setup = function() {\n var component, j, len, ref;\n ref = this.components;\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n if (!(component != null ? component.isSetup : void 0)) {\n component.setup();\n }\n }\n this.initialized = true;\n return null;\n };\n\n\n /**\n * Deserializes components from a data-bundle object.\n * \n * @method componentsFromDataBundle\n * @param {Object} data The data-bundle object.\n */\n\n Object_Base.prototype.componentsFromDataBundle = function(data) {\n var component, componentObject, j, len, ref;\n if (data != null ? data.components : void 0) {\n ref = data.components;\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n componentObject = new gs[component.className](component);\n this.addComponent(componentObject);\n }\n delete data.components;\n }\n return null;\n };\n\n\n /**\n * Serializes components of a specified type to a data-bundle. A component\n * needs to implement the toDataBundle method for correct serialization.\n *\n * @method componentsToDataBundle\n * @param {String} type - A component class name.\n * @return A data bundle.\n */\n\n Object_Base.prototype.componentsToDataBundle = function(type) {\n var bundle, component, components, j, len, ref;\n components = [];\n ref = this.components;\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n if (component instanceof type) {\n if (component.toDataBundle == null) {\n continue;\n }\n bundle = component.toDataBundle();\n bundle.className = component.constructor.name;\n components.push(bundle);\n }\n }\n return components;\n };\n\n\n /**\n * Starts a full-refresh on all sub-objects\n *\n * @method fullRefresh\n */\n\n Object_Base.prototype.fullRefresh = function() {\n var j, len, object, ref;\n ref = this.subObjects;\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n if (object) {\n object.needsUpdate = true;\n object.fullRefresh();\n }\n }\n return null;\n };\n\n\n /**\n * Updates the object with all parent- and sub-objects. \n *\n * @method fullUpdate\n */\n\n Object_Base.prototype.fullUpdate = function() {\n var j, len, object, parent, ref, results;\n parent = this;\n while (parent !== null) {\n parent.update();\n parent = parent.parent;\n }\n ref = this.subObjects;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n results.push(object != null ? object.update() : void 0);\n }\n return results;\n };\n\n\n /**\n * Updates the object and all its components. This method is\n * called automatically by the parent or ObjectManager so in regular it is \n * not necessary to call it manually.\n *\n * @method update\n */\n\n Object_Base.prototype.update = function() {\n var component, i;\n if (!this.active) {\n return;\n }\n i = 0;\n while (i < this.components.length) {\n component = this.components[i];\n if (!component.disposed) {\n component.update();\n i++;\n } else {\n this.components.splice(i, 1);\n }\n }\n if (this.input) {\n Input.clear();\n }\n this.input = false;\n return null;\n };\n\n\n /**\n * Searches for the first component with the specified class name.\n *\n * @method findComponent\n * @param {String} name The class name of the component.\n * @return {Component} The component or null if a component with the specified class name cannot be found.\n */\n\n Object_Base.prototype.findComponent = function(name) {\n return this.components.first(function(v) {\n return v.constructor.name === name;\n });\n };\n\n\n /**\n * Searches for all components with the specified class name.\n *\n * @method findComponents\n * @param {String} name The class name of the components.\n * @return {Array} The components or null if no component with the specified class name has been found.\n */\n\n Object_Base.prototype.findComponents = function(name) {\n return this.components.where(function(v) {\n return v.constructor.name === name;\n });\n };\n\n\n /**\n * Searches for the component with the specified ID.\n *\n * @method findComponentById\n * @param {String} id The unique identifier of the component.\n * @return {Component} The component or null if a component with the specified ID cannot be found.\n */\n\n Object_Base.prototype.findComponentById = function(id) {\n return this.componentsById[id];\n };\n\n\n /**\n * Adds an object to the list of sub-objects.\n *\n * @method addObject\n * @param {Object_Base} object The object which should be added.\n */\n\n Object_Base.prototype.addObject = function(object) {\n var ref, ref1;\n if ((ref = gs.ObjectManager.current) != null) {\n ref.remove(object);\n }\n if ((ref1 = object.parent) != null) {\n ref1.removeObject(object);\n }\n object.parent = this;\n this.subObjects.push(object);\n this.needsSort = true;\n this.needsUpdate = true;\n if (object.id != null) {\n return gs.ObjectManager.current.setObjectById(object, object.id);\n }\n };\n\n\n /**\n * Inserts an object into the list of sub-objects at the specified index.\n *\n * @method insertObject\n * @param {Object_Base} object The object which should be inserted.\n * @param {Number} index The index.\n */\n\n Object_Base.prototype.insertObject = function(object, index) {\n var ref;\n gs.ObjectManager.current.remove(object);\n if ((ref = object.parent) != null) {\n ref.removeObject(object);\n }\n object.parent = this;\n this.subObjects.splice(index, 0, object);\n if (object.id != null) {\n return gs.ObjectManager.current.setObjectById(object, object.id);\n }\n };\n\n\n /**\n * Sets sub-object at the specified index.\n *\n * @method setObject\n * @param {Object_Base} object The object.\n * @param {Number} index The index.\n */\n\n Object_Base.prototype.setObject = function(object, index) {\n var ref;\n if (object) {\n gs.ObjectManager.current.remove(object);\n if ((ref = object.parent) != null) {\n ref.removeObject(object);\n }\n object.parent = this;\n }\n this.subObjects[index] = object;\n if ((object != null ? object.id : void 0) != null) {\n return gs.ObjectManager.current.setObjectById(object, object.id);\n }\n };\n\n\n /**\n * Removes the specified object from the list of sub-objects.\n *\n * @method removeObject\n * @param {Object_Base} object The object which should be removed.\n */\n\n Object_Base.prototype.removeObject = function(object) {\n this.subObjects.remove(object);\n object.parent = null;\n return this.needsUpdate = true;\n };\n\n\n /**\n * Erases the object at the specified index. The list size\n * will not be changed but the the value at the index will be set to null.\n *\n * @method eraseObject\n * @param {Number} object The object which should be erased.\n */\n\n Object_Base.prototype.eraseObject = function(index) {\n var object;\n object = this.subObjects[index];\n if (object != null) {\n object.parent = null;\n }\n return this.subObjects[index] = null;\n };\n\n\n /**\n * Adds the specified component to the object.\n *\n * @method addComponent\n * @param {Component} component The component\n * @param {String} id An optional unique identifier for the component.\n */\n\n Object_Base.prototype.addComponent = function(component, id) {\n if (!this.components.contains(component)) {\n component.object = this;\n this.components.push(component);\n if (id != null) {\n return this.componentsById[id] = component;\n }\n }\n };\n\n\n /**\n * Inserts a component at the specified index.\n *\n * @method insertComponent\n * @param {Component} component The component.\n * @param {Number} index The index.\n * @param {String} id An optional unique identifier for the component.\n */\n\n Object_Base.prototype.insertComponent = function(component, index, id) {\n this.components.remove(component);\n component.object = this;\n this.components.splice(index, 0, component);\n if (id != null) {\n return this.componentsById[id] = component;\n }\n };\n\n\n /**\n * Removes a component from the object.\n *\n * @method removeComponent\n * @param {Component} component The component to remove.\n */\n\n Object_Base.prototype.removeComponent = function(component) {\n this.components.remove(component);\n if (typeof id !== \"undefined\" && id !== null) {\n return delete this.componentsById[id];\n }\n };\n\n return Object_Base;\n\n})();\n\ngs.Object_Base = Object_Base;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7O3dCQVFBLG1CQUFBLEdBQXFCLFNBQUMsSUFBRCxFQUFPLE9BQVA7SUFDakIsSUFBRyxJQUFDLENBQUEsRUFBSjthQUNJLE1BQU8sQ0FBQSxHQUFBLEdBQUksSUFBQyxDQUFBLEVBQUwsQ0FBUCxHQUFrQixLQUR0Qjs7RUFEaUI7O0VBV3JCLFdBQUMsQ0FBQSxTQUFELENBQVcsT0FBWCxFQUNJO0lBQUEsR0FBQSxFQUFLLFNBQUMsQ0FBRDtBQUNELFVBQUE7TUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVOzJEQUNjLENBQUUsVUFBMUIsQ0FBcUMsSUFBckMsRUFBMkMsQ0FBM0M7SUFGQyxDQUFMO0lBSUEsR0FBQSxFQUFLLFNBQUE7YUFBRyxJQUFDLENBQUE7SUFBSixDQUpMO0dBREo7O0VBY0EsV0FBQyxDQUFBLFNBQUQsQ0FBVyxPQUFYLEVBQ0k7SUFBQSxHQUFBLEVBQUssU0FBQyxDQUFEO0FBQ0QsVUFBQTtNQUFBLElBQUcsQ0FBQSxLQUFLLElBQUMsQ0FBQSxNQUFUO1FBQ0ksSUFBQyxDQUFBLE1BQUQsR0FBVTtnREFDSCxDQUFFLFNBQVQsR0FBcUIsY0FGekI7O0lBREMsQ0FBTDtJQUlBLEdBQUEsRUFBSyxTQUFBO2FBQUcsSUFBQyxDQUFBO0lBQUosQ0FKTDtHQURKOztFQWVBLFdBQUMsQ0FBQSxTQUFELENBQVcsYUFBWCxFQUNJO0lBQUEsR0FBQSxFQUFLLFNBQUMsQ0FBRDtBQUNELFVBQUE7TUFBQSxJQUFDLENBQUEsWUFBRCxHQUFnQjtNQUVoQixNQUFBLEdBQVMsSUFBQyxDQUFBO0FBQ1YsYUFBTSxNQUFOO1FBQ0ksTUFBTSxDQUFDLFlBQVAsR0FBc0I7UUFDdEIsTUFBQSxHQUFTLE1BQU0sQ0FBQztNQUZwQjtNQVNBLElBQUcsQ0FBSDtlQUNJLElBQUMsQ0FBQSxnQkFBRCxDQUFBLEVBREo7O0lBYkMs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LFNBQUMsS0FBRDtBQUNULFFBQUE7SUFBQSxNQUFBLEdBQVMsSUFBQyxDQUFBLFVBQVcsQ0FBQSxLQUFBOztNQUNyQixNQUFNLENBQUUsTUFBUixHQUFpQjs7V0FDakIsSUFBQyxDQUFBLFVBQVcsQ0FBQSxLQUFBLENBQVosR0FBcUI7RUFIWjs7O0FBS2I7Ozs7Ozs7O3dCQU9BLFlBQUEsR0FBYyxTQUFDLFNBQUQsRUFBWSxFQUFaO0lBQ1YsSUFBRyxDQUFJLElBQUMsQ0FBQSxVQUFVLENBQUMsUUFBWixDQUFxQixTQUFyQixDQUFQO01BQ0ksU0FBUyxDQUFDLE1BQVYsR0FBbUI7TUFDbkIsSUFBQyxDQUFBLFVBQVUsQ0FBQyxJQUFaLENBQWlCLFNBQWpCO01BQ0EsSUFBRyxVQUFIO2VBQ0ksSUFBQyxDQUFBLGNBQWUsQ0FBQSxFQUFBLENBQWhCLEdBQXNCLFVBRDFCO09BSEo7O0VBRFU7OztBQU1kOzs7Ozs7Ozs7d0JBUUEsZUFBQSxHQUFpQixTQUFDLFNBQUQsRUFBWSxLQUFaLEVBQW1CLEVBQW5CO0lBQ2IsSUFBQyxDQUFBLFVBQVUsQ0FBQyxNQUFaLENBQW1CLFNBQW5CO0lBQ0EsU0FBUyxDQUFDLE1BQVYsR0FBbUI7SUFDbkIsSUFBQyxDQUFBLFVBQVUsQ0FBQyxNQUFaLENBQW1CLEtBQW5CLEVBQTBCLENBQTFCLEVBQTZCLFNBQTdCO0lBQ0EsSUFBRyxVQUFIO2FBQ0ksSUFBQyxDQUFBLGNBQWUsQ0FBQSxFQUFBLENBQWhCLEdBQXNCLFVBRDFCOztFQUphOzs7QUFPakI7Ozs7Ozs7d0JBTUEsZUFBQSxHQUFpQixTQUFDLFNBQUQ7SUFDYixJQUFDLENBQUEsVUFBVSxDQUFDLE1BQVosQ0FBbUIsU0FBbkI7SUFDQSxJQUFHLHdDQUFIO2FBQ0ksT0FBTyxJQUFDLENBQUEsY0FBZSxDQUFBLEVBQUEsRUFEM0I7O0VBRmE7Ozs7OztBQUtyQixFQUFFLENBQUMsV0FBSCxHQUFpQiIsInNvdXJjZXNDb250ZW50IjpbIiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuI1xuIyAgIFNjcmlwdDogT2JqZWN0X0Jhc2VcbiNcbiMgICAkJENPUFlSSUdIVCQkXG4jXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmNsYXNzIE9iamVjdF9CYXNlXG4gICAgIyMjKlxuICAgICogQ2FsbGVkIGlmIHRoaXMgb2JqZWN0IGluc3RhbmNlIGlzIHJlc3RvcmVkIGZyb20gYSBkYXRhLWJ1bmRsZS4gSXQgY2FuIGJlIHVzZWRcbiAgICAqIHJlLWFzc2lnbiBldmVudC1oYW5kbGVyLCBhbm9ueW1vdXMgZnVuY3Rpb25zLCBldGMuXG4gICAgKiBcbiAgICAqIEBtZXRob2Qgb25EYXRhQnVuZGxlUmVzdG9yZS5cbiAgICAqIEBwYXJhbSBPYmplY3QgZGF0YSAtIFRoZSBkYXRhLWJ1bmRsZVxuICAgICogQHBhcmFtIGdzLk9iamVjdENvZGVjQ29udGV4dCBjb250ZXh0IC0gVGhlIGNvZGVjLWNvbnRleHQuXG4gICAgIyMjXG4gICAgb25EYXRhQnVuZGxlUmVzdG9yZTogKGRhdGEsIGNvbnRleHQpIC0+XG4gICAgICAgIGlmIEBpZFxuICAgICAgICAgICAgd2luZG93W1wiJFwiK0BpZF0gPSB0aGlzXG4gICAgICAgICAgICBcbiAgICBcbiAgICAjXG4gICAgIyBHZXRzIG9yIHNldHMgdGhlIGdyb3VwIHRoZSBvYmplY3QgYmVsb25ncyB0by5cbiAgICAjXG4gICAgIyBAcHJvcGVydHkgZ3JvdXBcbiAgICAjIEB0eXBlIHN0cmluZ1xuICAgICNcbiAgICBAYWNjZXNzb3JzIFwiZ3JvdXBcIiwgXG4gICAgICAgIHNldDogKGcpIC0+IFxuICAgICAgICAgICAgQGdyb3VwXyA9IGdcbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8uYWRkVG9Hcm91cCh0aGlzLCBnKVxuICAgICAgICAgICAgXG4gICAgICAgIGdldDogLT4gQGdyb3VwX1xuICAgICAgICBcbiAgICAjXG4gICAgIyBHZXRzIG9yIHNldHMgdGhlIG9yZGVyLWluZGV4IG9mIHRoZSBvYmplY3QuIFRoZSBsb3dlciB0aGUgaW5kZXgsIHRoZVxuICAgICMgZWFybGllciB0aGUgb2JqZWN0IHdpbGwgYmUgdXBkYXRlZCBpbiBhIGxpc3Qgb2Ygc3ViLW9iamVjdHMuXG4gICAgI1xuICAgICMgQHByb3BlcnR5IG9yZGVyXG4gICAgIyBAdHlwZSBudW1iZXJcbiAgICAjXG4gICAgQGFjY2Vzc29ycyBcIm9yZGVyXCIsXG4gICAgICAgIHNldDogKG8pIC0+XG4gICAgICAgICAgICBpZiBvICE9IEBvcmRlcl9cbiAgICAgICAgICAgICAgICBAb3JkZXJfID0gb1xuICAgICAgICAgICAgICAgIEBwYXJlbnQ/Lm5lZWRzU29ydCA9IHRydWVcbiAgICAgICAgZ2V0OiAtPiBAb3JkZXJfXG4gICAgICAgIFxuICAgICNcbiAgICAjIEdldHMgb3Igc2V0cyBpZiBhbiBvYmplY3RzIG5lZWRzIGFuIHVwZGF0ZS4gSWYgdHJ1ZSwgdGhlIHBhcmVudCB3aWxsIHVwZGF0ZVxuICAgICMgdGhlIG9iamVjdCBpbiB0aGUgbmV4dCB1cGRhdGUgYW5kIHJlc2V0cyB0aGUgbmVlZHNVcGRhdGUgcHJvcGVydHkgYmFja1xuICAgICMgdG8gZmFsc2UuXG4gICAgI1xuICAgICMgQHByb3BlcnR5IG5lZWRzVXBkYXRlXG4gICAgIyBAdHlwZSBib29sZWFuXG4gICAgI1xuICAgIEBhY2Nlc3NvcnMgXCJuZWVkc1VwZGF0ZVwiLCBcbiAgICAgICAgc2V0OiAodikgLT5cbiAgICAgICAgICAgIEBuZWVkc1VwZGF0ZV8gPSB2XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHBhcmVudCA9IEBwYXJlbnRcbiAgICAgICAgICAgIHdoaWxlIHBhcmVudFxuICAgICAgICAgICAgICAgIHBhcmVudC5uZWVkc1VwZGF0ZV8gPSB5ZXNcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAjaWYgdlxuICAgICAgICAgICAgIyAgICBAcGFyZW50Py5uZWVkc1VwZGF0ZSA9IHllc1xuICAgICAgICAgICAgI2lmIHZcbiAgICAgICAgICAgICMgICAgZm9yIG9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgIyAgICAgICAgb2JqZWN0Lm5lZWRzVXBkYXRlXyA9IHZcbiAgICAgICAgICAgIGlmIHZcbiAgICAgICAgICAgICAgICBAcmVxdWVzdFN1YlVwZGF0ZSgpXG4gICAgICAgIGdldDogLT4gcmV0dXJuIEBuZWVkc1VwZGF0ZV8gfHwgU2NlbmVNYW5hZ2VyLnNjZW5lLnByZXBhcmluZ1xuICAgICAgICBcbiAgICByZXF1ZXN0U3ViVXBkYXRlOiAtPlxuICAgICAgICBmb3Igb2JqZWN0IGluIEBzdWJPYmplY3RzXG4gICAgICAgICAgICBpZiBvYmplY3RcbiAgICAgICAgICAgICAgICBvYmplY3QubmVlZHNVcGRhdGVfID0geWVzXG4gICAgICAgICAgICAgICAgb2JqZWN0LnJlcXVlc3RTdWJVcGRhdGUoKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgICNcbiAgICAjIEdldHMgb3Igc2V0cyBpZiBhbiBvYmplY3QgbmVlZHMgYSBmdWxsIHVwZGF0ZS4gQSBmdWxsIHVwZGF0ZSB0cmlnZ2Vyc1xuICAgICMgYW4gdXBkYXRlIGZvciBhbGwgc3ViLW9iamVjdHMgcmVjdXJzaXZlbHkuIFxuICAgICNcbiAgICAjIEBwcm9wZXJ0eSBuZWVkc0Z1bGxVcGRhdGVcbiAgICAjIEB0eXBlIGJvb2xlYW5cbiAgICAjXG4gICAgQGFjY2Vzc29ycyBcIm5lZWRzRnVsbFVwZGF0ZVwiLCBcbiAgICAgICAgc2V0OiAodikgLT5cbiAgICAgICAgICAgIEBuZWVkc1VwZGF0ZSA9IHZcbiAgICAgICAgICAgIGlmIHZcbiAgICAgICAgICAgICAgICBmb3Igb2JqZWN0IGluIEBzdWJPYmplY3RzXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5uZWVkc0Z1bGxVcGRhdGUgPSB2XG4gICAgICAgIGdldDogLT4gQG5lZWRzVXBkYXRlX1xuICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogVGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBnYW1lIG9iamVjdHMuIEEgZ2FtZSBvYmplY3QgaXRzZWxmIGRvZXNuJ3QgaW1wbGVtZW50XG4gICAgKiBhbnkgZ2FtZSBsb2dpYyBidXQgdXNlcyBjb21wb25lbnRzIGFuZCBzdWItb2JqZWN0cyBmb3IgdGhhdC5cbiAgICAqXG4gICAgKiBAbW9kdWxlIGdzXG4gICAgKiBAY2xhc3MgT2JqZWN0X0Jhc2VcbiAgICAqIEBtZW1iZXJvZiBnc1xuICAgICogQGNvbnN0cnVjdG9yXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6ICgpIC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgc3ViT2JqZWN0c1xuICAgICAgICAqIEB0eXBlIGdzLk9iamVjdF9CYXNlW11cbiAgICAgICAgKiBAZGVmYXVsdCBbXVxuICAgICAgICAqIEEgbGlzdCBvZiBnYW1lLW9iamVjdHMgZ3JvdXBlZCB1bmRlciB0aGlzIGdhbWUgb2JqZWN0LlxuICAgICAgICAjIyNcbiAgICAgICAgQHN1Yk9iamVjdHMgPSBbXVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBjb21wb25lbnRzXG4gICAgICAgICogQHR5cGUgZ3MuQ29tcG9uZW50W11cbiAgICAgICAgKiBAZGVmYXVsdCBbXVxuICAgICAgICAqIEEgbGlzdCBvZiBjb21wb25lbnRzIGRlZmluaW5nIHRoZSBsb2dpYy9iZWhhdmlvciBhbmQgYXBwZWFyYW5jZSBvZiB0aGUgZ2FtZSBvYmplY3QuXG4gICAgICAgICMjI1xuICAgICAgICBAY29tcG9uZW50cyA9IFtdXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGNvbXBvbmVudHNCeUlkXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICogQGRlZmF1bHQgW11cbiAgICAgICAgKiBBbGwgYXNzb2NpYXRlZCBjb21wb25lbnRzIGJ5IHRoZWlyIElELlxuICAgICAgICAjIyNcbiAgICAgICAgQGNvbXBvbmVudHNCeUlkID0ge31cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgZGlzcG9zZWRcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGdhbWUgb2JqZWN0IGlkIGRpc3Bvc2VkLiBBIGRpc3Bvc2VkIGdhbWUgb2JqZWN0IGNhbm5vdCBiZSB1c2VkIGFueW1vcmUuXG4gICAgICAgICMjI1xuICAgICAgICBAZGlzcG9zZWQgPSBub1xuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBhY3RpdmVcbiAgICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBnYW1lIG9iamVjdCBpcyBhY3RpdmUuIEFuIGluYWN0aXZlIGdhbWUgb2JqZWN0IHdpbGwgbm90IGJlIHVwZGF0ZWQuXG4gICAgICAgICMjI1xuICAgICAgICBAYWN0aXZlID0geWVzXG4gICAgICAgIFxuICAgICAgICBAaW5wdXQgPSBub1xuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBpZFxuICAgICAgICAqIEB0eXBlIHN0cmluZ1xuICAgICAgICAqIEBkZWZhdWx0IG51bGxcbiAgICAgICAgKiBUaGUgZ2FtZSBvYmplY3QncyBVSUQgKFVuaXF1ZSBJRClcbiAgICAgICAgIyMjXG4gICAgICAgIEBpZCA9IG51bGwgXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGdyb3VwXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIEB0eXBlIHN0cmluZ1xuICAgICAgICAqIFRoZSBnYW1lIG9iamVjdCdzIGdyb3VwLiBUbyBnZXQgYWxsIG9iamVjdCdzIG9mIGEgc3BlY2lmaWMgZ3JvdXAgdGhlIGdzLk9iamVjdE1hbmFnZXIub2JqZWN0c0J5R3JvdXAgcHJvcGVydHkgY2FuIGJlIHVzZWQuXG4gICAgICAgICMjI1xuICAgICAgICBAZ3JvdXAgPSBudWxsIFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBwYXJlbnRcbiAgICAgICAgKiBAdHlwZSBncy5PYmplY3RfQmFzZVxuICAgICAgICAqIEBkZWZhdWx0IG51bGxcbiAgICAgICAgKiBUaGUgcGFyZW50IG9iamVjdCBpZiB0aGUgZ2FtZSBvYmplY3QgaXMgYSBzdWItb2JqZWN0IG9mIGFub3RoZXIgZ2FtZSBvYmplY3QuXG4gICAgICAgICMjI1xuICAgICAgICBAcGFyZW50ID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBvcmRlclxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAqIEBkZWZhdWx0IDBcbiAgICAgICAgKiBDb250cm9scyB0aGUgdXBkYXRlLW9yZGVyLiBUaGUgc21hbGxlciB0aGUgdmFsdWUgdGhlIGVhcmxpZXIgdGhlIGdhbWUgb2JqZWN0IGlzIHVwZGF0ZWQgYmVmb3JlIG90aGVyIGdhbWUgb2JqZWN0cyBhcmUgdXBkYXRlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBvcmRlciA9IDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgckluZGV4XG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQGRlZmF1bHQgMFxuICAgICAgICAqIEhvbGRzIHRoZSByZW5kZXItaW5kZXggaWYgdGhlIGdhbWUgb2JqZWN0IGhhcyBhIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvbiBzY3JlZW4uIFRoZSByZW5kZXItaW5kZXggaXMgdGhlXG4gICAgICAgICogaW5kZXggb2YgdGhlIGdhbWUgb2JqZWN0J3MgZ3JhcGhpYy1vYmplY3QoZ3MuR3JhcGhpY09iamVjdCkgaW4gdGhlIGN1cnJlbnQgbGlzdCBvZiBncmFwaGljLW9iamVjdHMuIFRoZSByZW5kZXItaW5kZXhcbiAgICAgICAgKiBpcyByZWFkLW9ubHkuIFNldHRpbmcgdGhlIHJlbmRlci1pbmRleCB0byBhIGNlcnRhaW4gdmFsdWUgaGFzIG5vIGVmZmVjdC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBySW5kZXggPSAwXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IG5lZWRzU29ydFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzIG5lZWRzIHRvIGJlIHNvcnRlZCBieSBvcmRlciBiZWNhdXNlIG9mIGEgY2hhbmdlLlxuICAgICAgICAjIyNcbiAgICAgICAgQG5lZWRzU29ydCA9IHllc1xuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBuZWVkc1NvcnRcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgVUkgb2JqZWN0IG5lZWRzIHRvIGJlIHVwZGF0ZWQuXG4gICAgICAgICMjI1xuICAgICAgICBAbmVlZHNVcGRhdGUgPSB5ZXNcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgaW5pdGlhbGl6ZWRcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgZ2FtZSBvYmplY3QgYW5kIGl0cyBjb21wb25lbnRzIGhhdmUgYmVlbiBpbml0aWFsaXplZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBpbml0aWFsaXplZCA9IG5vXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGN1c3RvbURhdGFcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgKiBAZGVmYXVsdCB7fVxuICAgICAgICAqIEEgY3VzdG9tIGRhdGEgb2JqZWN0IHdoaWNoIGNhbiBiZSB1c2VkIHRvIGFkZCBhbnkgY3VzdG9tIGRhdGEvZmllbGRzIHRvIHRoZSBnYW1lXG4gICAgICAgICogb2JqZWN0LiBJdCBpcyBhbiBlbXB0eSBvYmplY3QgYnkgZGVmYXVsdC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBjdXN0b21EYXRhID0ge31cbiAgICAgICAgXG4gICAgICAgIFxuICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQ/LnJlZ2lzdGVyT2JqZWN0KHRoaXMpXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIERpc3Bvc2VzIHRoZSBvYmplY3Qgd2l0aCBhbGwgaXRzIGNvbXBvbmVudHMgYW5kIHN1Yi1vYmplY3RzLiBBIGRpc3Bvc2VkIG9iamVjdCB3aWxsIGJlXG4gICAgKiByZW1vdmVkIGZyb20gdGhlIHBhcmVudCBhdXRvbWF0aWNhbGx5LlxuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZVxuICAgICMjI1xuICAgIGRpc3Bvc2U6IC0+XG4gICAgICAgIGlmIG5vdCBAZGlzcG9zZWRcbiAgICAgICAgICAgIEBkaXNwb3NlZCA9IHllc1xuICAgICAgICAgICAgQGRpc3Bvc2VDb21wb25lbnRzKClcbiAgICAgICAgICAgIEBkaXNwb3NlT2JqZWN0cygpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQ/LnVucmVnaXN0ZXJPYmplY3QodGhpcylcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIERpc3Bvc2VzIGFsbCBzdWItb2JqZWN0cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGRpc3Bvc2VPYmplY3RzXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjXG4gICAgZGlzcG9zZU9iamVjdHM6IC0+XG4gICAgICAgIGZvciBzdWJPYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgIHN1Yk9iamVjdD8uZGlzcG9zZT8oKVxuICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgYWxsIGNvbXBvbmVudHNcbiAgICAqXG4gICAgKiBAbWV0aG9kIGRpc3Bvc2VDb21wb25lbnRzXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjXG4gICAgZGlzcG9zZUNvbXBvbmVudHM6IC0+XG4gICAgICAgIGZvciBjb21wb25lbnQgaW4gQGNvbXBvbmVudHNcbiAgICAgICAgICAgIGNvbXBvbmVudD8uZGlzcG9zZT8oKVxuICAgICAgIFxuICAgICMjIypcbiAgICAqIENhbGxzIHNldHVwLXJvdXRpbmUgb24gYWxsIGNvbXBvbmVudHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXR1cFxuICAgICMjI1xuICAgIHNldHVwOiAtPlxuICAgICAgICBmb3IgY29tcG9uZW50IGluIEBjb21wb25lbnRzXG4gICAgICAgICAgICBjb21wb25lbnQuc2V0dXAoKSBpZiBub3QgY29tcG9uZW50Py5pc1NldHVwXG4gICAgICAgICAgICBcbiAgICAgICAgQGluaXRpYWxpemVkID0geWVzXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIERlc2VyaWFsaXplcyBjb21wb25lbnRzIGZyb20gYSBkYXRhLWJ1bmRsZSBvYmplY3QuXG4gICAgKiBcbiAgICAqIEBtZXRob2QgY29tcG9uZW50c0Zyb21EYXRhQnVuZGxlXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSBUaGUgZGF0YS1idW5kbGUgb2JqZWN0LlxuICAgICMjI1xuICAgIGNvbXBvbmVudHNGcm9tRGF0YUJ1bmRsZTogKGRhdGEpIC0+XG4gICAgICAgIGlmIGRhdGE/LmNvbXBvbmVudHNcbiAgICAgICAgICAgIGZvciBjb21wb25lbnQgaW4gZGF0YS5jb21wb25lbnRzXG4gICAgICAgICAgICAgICAgY29tcG9uZW50T2JqZWN0ID0gbmV3IGdzW2NvbXBvbmVudC5jbGFzc05hbWVdKGNvbXBvbmVudClcbiAgICAgICAgICAgICAgICBAYWRkQ29tcG9uZW50KGNvbXBvbmVudE9iamVjdClcbiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLmNvbXBvbmVudHNcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogU2VyaWFsaXplcyBjb21wb25lbnRzIG9mIGEgc3BlY2lmaWVkIHR5cGUgdG8gYSBkYXRhLWJ1bmRsZS4gQSBjb21wb25lbnRcbiAgICAqIG5lZWRzIHRvIGltcGxlbWVudCB0aGUgdG9EYXRhQnVuZGxlIG1ldGhvZCBmb3IgY29ycmVjdCBzZXJpYWxpemF0aW9uLlxuICAgICpcbiAgICAqIEBtZXRob2QgY29tcG9uZW50c1RvRGF0YUJ1bmRsZVxuICAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBBIGNvbXBvbmVudCBjbGFzcyBuYW1lLlxuICAgICogQHJldHVybiBBIGRhdGEgYnVuZGxlLlxuICAgICMjI1xuICAgIGNvbXBvbmVudHNUb0RhdGFCdW5kbGU6ICh0eXBlKSAtPlxuICAgICAgICBjb21wb25lbnRzID0gW11cbiAgICAgICAgZm9yIGNvbXBvbmVudCBpbiBAY29tcG9uZW50c1xuICAgICAgICAgICAgaWYgY29tcG9uZW50IGluc3RhbmNlb2YgdHlwZVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlIHVubGVzcyBjb21wb25lbnQudG9EYXRhQnVuZGxlP1xuICAgICAgICAgICAgICAgIGJ1bmRsZSA9IGNvbXBvbmVudC50b0RhdGFCdW5kbGUoKVxuICAgICAgICAgICAgICAgIGJ1bmRsZS5jbGFzc05hbWUgPSBjb21wb25lbnQuY29uc3RydWN0b3IubmFtZVxuICAgICAgICAgICAgICAgIGNvbXBvbmVudHMucHVzaChidW5kbGUpXG4gICAgICAgIHJldHVybiBjb21wb25lbnRzXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIFN0YXJ0cyBhIGZ1bGwtcmVmcmVzaCBvbiBhbGwgc3ViLW9iamVjdHNcbiAgICAqXG4gICAgKiBAbWV0aG9kIGZ1bGxSZWZyZXNoXG4gICAgIyMjXG4gICAgZnVsbFJlZnJlc2g6IC0+XG4gICAgICAgIGZvciBvYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgIGlmIG9iamVjdFxuICAgICAgICAgICAgICAgIG9iamVjdC5uZWVkc1VwZGF0ZSA9IHllc1xuICAgICAgICAgICAgICAgIG9iamVjdC5mdWxsUmVmcmVzaCgpXG4gICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICBcbiAgICAjIyMqXG4gICAgKiBVcGRhdGVzIHRoZSBvYmplY3Qgd2l0aCBhbGwgcGFyZW50LSBhbmQgc3ViLW9iamVjdHMuIFxuICAgICpcbiAgICAqIEBtZXRob2QgZnVsbFVwZGF0ZVxuICAgICMjI1xuICAgIGZ1bGxVcGRhdGU6IC0+XG4gICAgICAgIHBhcmVudCA9IHRoaXNcbiAgICAgICAgd2hpbGUgcGFyZW50ICE9IG51bGxcbiAgICAgICAgICAgIHBhcmVudC51cGRhdGUoKVxuICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudFxuICAgICAgICAgICAgXG4gICAgICAgIGZvciBvYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgIG9iamVjdD8udXBkYXRlKClcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogVXBkYXRlcyB0aGUgb2JqZWN0IGFuZCBhbGwgaXRzIGNvbXBvbmVudHMuIFRoaXMgbWV0aG9kIGlzXG4gICAgKiBjYWxsZWQgYXV0b21hdGljYWxseSBieSB0aGUgcGFyZW50IG9yIE9iamVjdE1hbmFnZXIgc28gaW4gcmVndWxhciBpdCBpcyBcbiAgICAqIG5vdCBuZWNlc3NhcnkgdG8gY2FsbCBpdCBtYW51YWxseS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHVwZGF0ZVxuICAgICMjI1xuICAgIHVwZGF0ZTogLT5cbiAgICAgICAgcmV0dXJuIGlmICFAYWN0aXZlXG4gICAgICAgIGkgPSAwXG4gICAgICAgIHdoaWxlIGkgPCBAY29tcG9uZW50cy5sZW5ndGhcbiAgICAgICAgICAgIGNvbXBvbmVudCA9IEBjb21wb25lbnRzW2ldXG4gICAgICAgICAgICBpZiBub3QgY29tcG9uZW50LmRpc3Bvc2VkXG4gICAgICAgICAgICAgICAgY29tcG9uZW50LnVwZGF0ZSgpXG4gICAgICAgICAgICAgICAgaSsrXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgQGNvbXBvbmVudHMuc3BsaWNlKGksIDEpXG5cblxuICAgICAgICBpZiBAaW5wdXQgdGhlbiBJbnB1dC5jbGVhcigpXG4gICAgICAgIEBpbnB1dCA9IG5vXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWUuXG4gICAgKlxuICAgICogQG1ldGhvZCBmaW5kQ29tcG9uZW50XG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgY29tcG9uZW50LlxuICAgICogQHJldHVybiB7Q29tcG9uZW50fSBUaGUgY29tcG9uZW50IG9yIG51bGwgaWYgYSBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWUgY2Fubm90IGJlIGZvdW5kLlxuICAgICMjI1xuICAgIGZpbmRDb21wb25lbnQ6IChuYW1lKSAtPiBAY29tcG9uZW50cy5maXJzdCAodikgLT4gdi5jb25zdHJ1Y3Rvci5uYW1lID09IG5hbWVcbiAgICBcbiAgICAjIyMqXG4gICAgKiBTZWFyY2hlcyBmb3IgYWxsIGNvbXBvbmVudHMgd2l0aCB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWUuXG4gICAgKlxuICAgICogQG1ldGhvZCBmaW5kQ29tcG9uZW50c1xuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIGNsYXNzIG5hbWUgb2YgdGhlIGNvbXBvbmVudHMuXG4gICAgKiBAcmV0dXJuIHtBcnJheX0gVGhlIGNvbXBvbmVudHMgb3IgbnVsbCBpZiBubyBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWUgaGFzIGJlZW4gZm91bmQuXG4gICAgIyMjXG4gICAgZmluZENvbXBvbmVudHM6IChuYW1lKSAtPiBAY29tcG9uZW50cy53aGVyZSAodikgLT4gdi5jb25zdHJ1Y3Rvci5uYW1lID09IG5hbWVcbiAgICBcbiAgICAjIyMqXG4gICAgKiBTZWFyY2hlcyBmb3IgdGhlIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgSUQuXG4gICAgKlxuICAgICogQG1ldGhvZCBmaW5kQ29tcG9uZW50QnlJZFxuICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgY29tcG9uZW50LlxuICAgICogQHJldHVybiB7Q29tcG9uZW50fSBUaGUgY29tcG9uZW50IG9yIG51bGwgaWYgYSBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIElEIGNhbm5vdCBiZSBmb3VuZC5cbiAgICAjIyNcbiAgICBmaW5kQ29tcG9uZW50QnlJZDogKGlkKSAtPiBAY29tcG9uZW50c0J5SWRbaWRdXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyBhbiBvYmplY3QgdG8gdGhlIGxpc3Qgb2Ygc3ViLW9iamVjdHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBhZGRPYmplY3RcbiAgICAqIEBwYXJhbSB7T2JqZWN0X0Jhc2V9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBhZGRlZC5cbiAgICAjIyNcbiAgICBhZGRPYmplY3Q6IChvYmplY3QpIC0+XG4gICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8ucmVtb3ZlKG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudD8ucmVtb3ZlT2JqZWN0KG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgQHN1Yk9iamVjdHMucHVzaChvYmplY3QpXG4gICAgICAgIEBuZWVkc1NvcnQgPSB5ZXNcbiAgICAgICAgQG5lZWRzVXBkYXRlID0geWVzXG4gICAgXG4gICAgICAgIGlmIG9iamVjdC5pZD9cbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudC5zZXRPYmplY3RCeUlkKG9iamVjdCwgb2JqZWN0LmlkKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBJbnNlcnRzIGFuIG9iamVjdCBpbnRvIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAgKlxuICAgICogQG1ldGhvZCBpbnNlcnRPYmplY3RcbiAgICAqIEBwYXJhbSB7T2JqZWN0X0Jhc2V9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBpbnNlcnRlZC5cbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCBUaGUgaW5kZXguXG4gICAgIyMjXG4gICAgaW5zZXJ0T2JqZWN0OihvYmplY3QsIGluZGV4KSAtPlxuICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQucmVtb3ZlKG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudD8ucmVtb3ZlT2JqZWN0KG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgQHN1Yk9iamVjdHMuc3BsaWNlKGluZGV4LCAwLCBvYmplY3QpXG4gICAgICBcbiAgICAgICAgaWYgb2JqZWN0LmlkP1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQob2JqZWN0LCBvYmplY3QuaWQpXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHN1Yi1vYmplY3QgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldE9iamVjdFxuICAgICogQHBhcmFtIHtPYmplY3RfQmFzZX0gb2JqZWN0IFRoZSBvYmplY3QuXG4gICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4LlxuICAgICMjI1xuICAgIHNldE9iamVjdDogKG9iamVjdCwgaW5kZXgpIC0+XG4gICAgICAgIGlmIG9iamVjdFxuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnJlbW92ZShvYmplY3QpXG4gICAgICAgICAgICBvYmplY3QucGFyZW50Py5yZW1vdmVPYmplY3Qob2JqZWN0KVxuICAgICAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgICAgIFxuICAgICAgICBAc3ViT2JqZWN0c1tpbmRleF0gPSBvYmplY3RcbiAgICAgIFxuICAgICAgICBpZiBvYmplY3Q/LmlkP1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQob2JqZWN0LCBvYmplY3QuaWQpXG4gICAgXG4gICAgIyMjKlxuICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCBmcm9tIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVtb3ZlT2JqZWN0XG4gICAgKiBAcGFyYW0ge09iamVjdF9CYXNlfSBvYmplY3QgVGhlIG9iamVjdCB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZC5cbiAgICAjIyNcbiAgICByZW1vdmVPYmplY3Q6IChvYmplY3QpIC0+XG4gICAgICAgIEBzdWJPYmplY3RzLnJlbW92ZShvYmplY3QpXG4gICAgICAgIG9iamVjdC5wYXJlbnQgPSBudWxsXG4gICAgICAgIEBuZWVkc1VwZGF0ZSA9IHllc1xuICAgIFxuICAgICMjIypcbiAgICAqIEVyYXNlcyB0aGUgb2JqZWN0IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoZSBsaXN0IHNpemVcbiAgICAqIHdpbGwgbm90IGJlIGNoYW5nZWQgYnV0IHRoZSB0aGUgdmFsdWUgYXQgdGhlIGluZGV4IHdpbGwgYmUgc2V0IHRvIG51bGwuXG4gICAgKlxuICAgICogQG1ldGhvZCBlcmFzZU9iamVjdFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBlcmFzZWQuXG4gICAgIyMjXG4gICAgZXJhc2VPYmplY3Q6IChpbmRleCkgLT5cbiAgICAgICAgb2JqZWN0ID0gQHN1Yk9iamVjdHNbaW5kZXhdXG4gICAgICAgIG9iamVjdD8ucGFyZW50ID0gbnVsbFxuICAgICAgICBAc3ViT2JqZWN0c1tpbmRleF0gPSBudWxsXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudCB0byB0aGUgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgYWRkQ29tcG9uZW50XG4gICAgKiBAcGFyYW0ge0NvbXBvbmVudH0gY29tcG9uZW50IFRoZSBjb21wb25lbnRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBBbiBvcHRpb25hbCB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbXBvbmVudC5cbiAgICAjIyNcbiAgICBhZGRDb21wb25lbnQ6IChjb21wb25lbnQsIGlkKSAtPlxuICAgICAgICBpZiBub3QgQGNvbXBvbmVudHMuY29udGFpbnMoY29tcG9uZW50KVxuICAgICAgICAgICAgY29tcG9uZW50Lm9iamVjdCA9IHRoaXNcbiAgICAgICAgICAgIEBjb21wb25lbnRzLnB1c2goY29tcG9uZW50KVxuICAgICAgICAgICAgaWYgaWQ/XG4gICAgICAgICAgICAgICAgQGNvbXBvbmVudHNCeUlkW2lkXSA9IGNvbXBvbmVudFxuICAgICMjIypcbiAgICAqIEluc2VydHMgYSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGluc2VydENvbXBvbmVudFxuICAgICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBUaGUgY29tcG9uZW50LlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4IFRoZSBpbmRleC5cbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBBbiBvcHRpb25hbCB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbXBvbmVudC5cbiAgICAjIyMgICAgXG4gICAgaW5zZXJ0Q29tcG9uZW50OiAoY29tcG9uZW50LCBpbmRleCwgaWQpIC0+XG4gICAgICAgIEBjb21wb25lbnRzLnJlbW92ZShjb21wb25lbnQpXG4gICAgICAgIGNvbXBvbmVudC5vYmplY3QgPSB0aGlzXG4gICAgICAgIEBjb21wb25lbnRzLnNwbGljZShpbmRleCwgMCwgY29tcG9uZW50KVxuICAgICAgICBpZiBpZD9cbiAgICAgICAgICAgIEBjb21wb25lbnRzQnlJZFtpZF0gPSBjb21wb25lbnRcbiAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIGEgY29tcG9uZW50IGZyb20gdGhlIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlbW92ZUNvbXBvbmVudFxuICAgICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHRvIHJlbW92ZS5cbiAgICAjIyMgIFxuICAgIHJlbW92ZUNvbXBvbmVudDogKGNvbXBvbmVudCkgLT4gXG4gICAgICAgIEBjb21wb25lbnRzLnJlbW92ZShjb21wb25lbnQpXG4gICAgICAgIGlmIGlkP1xuICAgICAgICAgICAgZGVsZXRlIEBjb21wb25lbnRzQnlJZFtpZF1cblxuZ3MuT2JqZWN0X0Jhc2UgPSBPYmplY3RfQmFzZSJdfQ==\n//# sourceURL=Object_Base_5.js"
12 + "compiledContent": "var Object_Base;\n\nObject_Base = (function() {\n\n /**\n * Called if this object instance is restored from a data-bundle. It can be used\n * re-assign event-handler, anonymous functions, etc.\n * \n * @method onDataBundleRestore.\n * @param Object data - The data-bundle\n * @param gs.ObjectCodecContext context - The codec-context.\n */\n Object_Base.prototype.onDataBundleRestore = function(data, context) {\n if (this.id) {\n return window[\"$\" + this.id] = this;\n }\n };\n\n Object_Base.accessors(\"group\", {\n set: function(g) {\n var ref;\n this.group_ = g;\n return (ref = gs.ObjectManager.current) != null ? ref.addToGroup(this, g) : void 0;\n },\n get: function() {\n return this.group_;\n }\n });\n\n Object_Base.accessors(\"order\", {\n set: function(o) {\n var ref;\n if (o !== this.order_) {\n this.order_ = o;\n return (ref = this.parent) != null ? ref.needsSort = true : void 0;\n }\n },\n get: function() {\n return this.order_;\n }\n });\n\n Object_Base.accessors(\"needsUpdate\", {\n set: function(v) {\n var parent;\n this.needsUpdate_ = v;\n parent = this.parent;\n while (parent) {\n parent.needsUpdate_ = true;\n parent = parent.parent;\n }\n if (v) {\n return this.requestSubUpdate();\n }\n },\n get: function() {\n return this.needsUpdate_ || SceneManager.scene.preparing;\n }\n });\n\n Object_Base.prototype.requestSubUpdate = function() {\n var j, len, object, ref;\n ref = this.subObjects;\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n if (object) {\n object.needsUpdate_ = true;\n object.requestSubUpdate();\n }\n }\n return null;\n };\n\n Object_Base.accessors(\"needsFullUpdate\", {\n set: function(v) {\n var j, len, object, ref, results;\n this.needsUpdate = v;\n if (v) {\n ref = this.subObjects;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n results.push(object.needsFullUpdate = v);\n }\n return results;\n }\n },\n get: function() {\n return this.needsUpdate_;\n }\n });\n\n\n /**\n * The base class for all game objects. A game object itself doesn't implement\n * any game logic but uses components and sub-objects for that.\n *\n * @module gs\n * @class Object_Base\n * @memberof gs\n * @constructor\n */\n\n function Object_Base() {\n\n /**\n * @property subObjects\n * @type gs.Object_Base[]\n * @default []\n * A list of game-objects grouped under this game object.\n */\n var ref;\n this.subObjects = [];\n\n /**\n * @property components\n * @type gs.Component[]\n * @default []\n * A list of components defining the logic/behavior and appearance of the game object.\n */\n this.components = [];\n\n /**\n * @property componentsById\n * @type Object\n * @default []\n * All associated components by their ID.\n */\n this.componentsById = {};\n\n /**\n * @property disposed\n * @type boolean\n * @default false\n * Indicates if the game object id disposed. A disposed game object cannot be used anymore.\n */\n this.disposed = false;\n\n /**\n * @property active\n * @default true\n * Indicates if the game object is active. An inactive game object will not be updated.\n */\n this.active = true;\n this.input = false;\n\n /**\n * @property id\n * @type string\n * @default null\n * The game object's UID (Unique ID)\n */\n this.id = null;\n\n /**\n * @property group\n * @default null\n * @type string\n * The game object's group. To get all object's of a specific group the gs.ObjectManager.objectsByGroup property can be used.\n */\n this.group = null;\n\n /**\n * @property parent\n * @type gs.Object_Base\n * @default null\n * The parent object if the game object is a sub-object of another game object.\n */\n this.parent = null;\n\n /**\n * @property order\n * @type number\n * @default 0\n * Controls the update-order. The smaller the value the earlier the game object is updated before other game objects are updated.\n */\n this.order = 0;\n\n /**\n * @property rIndex\n * @type number\n * @default 0\n * Holds the render-index if the game object has a graphical representation on screen. The render-index is the\n * index of the game object's graphic-object(gs.GraphicObject) in the current list of graphic-objects. The render-index\n * is read-only. Setting the render-index to a certain value has no effect.\n */\n this.rIndex = 0;\n\n /**\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the list of sub-objects needs to be sorted by order because of a change.\n */\n this.needsSort = true;\n\n /**\n * @property needsSort\n * @type boolean\n * @default true\n * Indicates if the UI object needs to be updated.\n */\n this.needsUpdate = true;\n\n /**\n * @property initialized\n * @type boolean\n * @default true\n * Indicates if the game object and its components have been initialized.\n */\n this.initialized = false;\n\n /**\n * @property customData\n * @type Object\n * @default {}\n * A custom data object which can be used to add any custom data/fields to the game\n * object. It is an empty object by default.\n */\n this.customData = {};\n if ((ref = gs.ObjectManager.current) != null) {\n ref.registerObject(this);\n }\n }\n\n\n /**\n * Disposes the object with all its components and sub-objects. A disposed object will be\n * removed from the parent automatically.\n *\n * @method dispose\n */\n\n Object_Base.prototype.dispose = function() {\n var ref;\n if (!this.disposed) {\n this.disposed = true;\n this.disposeComponents();\n this.disposeObjects();\n if ((ref = gs.ObjectManager.current) != null) {\n ref.unregisterObject(this);\n }\n }\n return null;\n };\n\n\n /**\n * Disposes all sub-objects.\n *\n * @method disposeObjects\n * @protected\n */\n\n Object_Base.prototype.disposeObjects = function() {\n var j, len, ref, results, subObject;\n ref = this.subObjects;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n subObject = ref[j];\n results.push(subObject != null ? typeof subObject.dispose === \"function\" ? subObject.dispose() : void 0 : void 0);\n }\n return results;\n };\n\n\n /**\n * Disposes all components\n *\n * @method disposeComponents\n * @protected\n */\n\n Object_Base.prototype.disposeComponents = function() {\n var component, j, len, ref, results;\n ref = this.components;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n results.push(component != null ? typeof component.dispose === \"function\" ? component.dispose() : void 0 : void 0);\n }\n return results;\n };\n\n\n /**\n * Calls setup-routine on all components.\n *\n * @method setup\n */\n\n Object_Base.prototype.setup = function() {\n var component, j, len, ref;\n ref = this.components;\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n if (!(component != null ? component.isSetup : void 0)) {\n component.setup();\n }\n }\n this.initialized = true;\n return null;\n };\n\n\n /**\n * Deserializes components from a data-bundle object.\n * \n * @method componentsFromDataBundle\n * @param {Object} data The data-bundle object.\n */\n\n Object_Base.prototype.componentsFromDataBundle = function(data) {\n var component, componentObject, j, len, ref;\n if (data != null ? data.components : void 0) {\n ref = data.components;\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n componentObject = new gs[component.className](component);\n this.addComponent(componentObject);\n }\n delete data.components;\n }\n return null;\n };\n\n\n /**\n * Serializes components of a specified type to a data-bundle. A component\n * needs to implement the toDataBundle method for correct serialization.\n *\n * @method componentsToDataBundle\n * @param {String} type - A component class name.\n * @return A data bundle.\n */\n\n Object_Base.prototype.componentsToDataBundle = function(type) {\n var bundle, component, components, j, len, ref;\n components = [];\n ref = this.components;\n for (j = 0, len = ref.length; j < len; j++) {\n component = ref[j];\n if (component instanceof type) {\n if (component.toDataBundle == null) {\n continue;\n }\n bundle = component.toDataBundle();\n bundle.className = component.constructor.name;\n components.push(bundle);\n }\n }\n return components;\n };\n\n\n /**\n * Starts a full-refresh on all sub-objects\n *\n * @method fullRefresh\n */\n\n Object_Base.prototype.fullRefresh = function() {\n var j, len, object, ref;\n ref = this.subObjects;\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n if (object) {\n object.needsUpdate = true;\n object.fullRefresh();\n }\n }\n return null;\n };\n\n\n /**\n * Updates the object with all parent- and sub-objects. \n *\n * @method fullUpdate\n */\n\n Object_Base.prototype.fullUpdate = function() {\n var j, len, object, parent, ref, results;\n parent = this;\n while (parent !== null) {\n parent.update();\n parent = parent.parent;\n }\n ref = this.subObjects;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n object = ref[j];\n results.push(object != null ? object.update() : void 0);\n }\n return results;\n };\n\n\n /**\n * Updates the object and all its components. This method is\n * called automatically by the parent or ObjectManager so in regular it is \n * not necessary to call it manually.\n *\n * @method update\n */\n\n Object_Base.prototype.update = function() {\n var component, i;\n if (!this.active) {\n return;\n }\n i = 0;\n while (i < this.components.length) {\n component = this.components[i];\n if (!component.disposed) {\n component.update();\n i++;\n } else {\n this.components.splice(i, 1);\n }\n }\n if (this.input) {\n Input.clear();\n }\n this.input = false;\n return null;\n };\n\n\n /**\n * Searches for the first component with the specified class name.\n *\n * @method findComponent\n * @param {String} name The class name of the component.\n * @return {Component} The component or null if a component with the specified class name cannot be found.\n */\n\n Object_Base.prototype.findComponent = function(name) {\n return this.components.first(function(v) {\n return v.constructor.name === name;\n });\n };\n\n\n /**\n * Searches for all components with the specified class name.\n *\n * @method findComponents\n * @param {String} name The class name of the components.\n * @return {Array} The components or null if no component with the specified class name has been found.\n */\n\n Object_Base.prototype.findComponents = function(name) {\n return this.components.where(function(v) {\n return v.constructor.name === name;\n });\n };\n\n\n /**\n * Searches for the component with the specified ID.\n *\n * @method findComponentById\n * @param {String} id The unique identifier of the component.\n * @return {Component} The component or null if a component with the specified ID cannot be found.\n */\n\n Object_Base.prototype.findComponentById = function(id) {\n return this.componentsById[id];\n };\n\n\n /**\n * Searches for the component with the specified name. If multiple components have the\n * same name, it will return the first match.\n *\n * @method findComponentByName\n * @param {String} name The name of the component to find.\n * @return {Component} The component or null if a component with the specified name cannot be found.\n */\n\n Object_Base.prototype.findComponentByName = function(name) {\n return this.components.first(function(v) {\n return v.name === name;\n });\n };\n\n\n /**\n * Searches for components with the specified name.\n *\n * @method findComponentsByName\n * @param {String} name The name of the components to find.\n * @return {Component[]} An array of components matching the specified name or null if no components with the specified name exist.\n */\n\n Object_Base.prototype.findComponentsByName = function(name) {\n return this.components.where(function(v) {\n return v.name === name;\n });\n };\n\n\n /**\n * Adds an object to the list of sub-objects.\n *\n * @method addObject\n * @param {Object_Base} object The object which should be added.\n */\n\n Object_Base.prototype.addObject = function(object) {\n var ref, ref1;\n if ((ref = gs.ObjectManager.current) != null) {\n ref.remove(object);\n }\n if ((ref1 = object.parent) != null) {\n ref1.removeObject(object);\n }\n object.parent = this;\n this.subObjects.push(object);\n this.needsSort = true;\n this.needsUpdate = true;\n if (object.id != null) {\n return gs.ObjectManager.current.setObjectById(object, object.id);\n }\n };\n\n\n /**\n * Inserts an object into the list of sub-objects at the specified index.\n *\n * @method insertObject\n * @param {Object_Base} object The object which should be inserted.\n * @param {Number} index The index.\n */\n\n Object_Base.prototype.insertObject = function(object, index) {\n var ref;\n gs.ObjectManager.current.remove(object);\n if ((ref = object.parent) != null) {\n ref.removeObject(object);\n }\n object.parent = this;\n this.subObjects.splice(index, 0, object);\n if (object.id != null) {\n return gs.ObjectManager.current.setObjectById(object, object.id);\n }\n };\n\n\n /**\n * Sets sub-object at the specified index.\n *\n * @method setObject\n * @param {Object_Base} object The object.\n * @param {Number} index The index.\n */\n\n Object_Base.prototype.setObject = function(object, index) {\n var ref;\n if (object) {\n gs.ObjectManager.current.remove(object);\n if ((ref = object.parent) != null) {\n ref.removeObject(object);\n }\n object.parent = this;\n }\n this.subObjects[index] = object;\n if ((object != null ? object.id : void 0) != null) {\n return gs.ObjectManager.current.setObjectById(object, object.id);\n }\n };\n\n\n /**\n * Removes the specified object from the list of sub-objects.\n *\n * @method removeObject\n * @param {Object_Base} object The object which should be removed.\n */\n\n Object_Base.prototype.removeObject = function(object) {\n this.subObjects.remove(object);\n object.parent = null;\n return this.needsUpdate = true;\n };\n\n\n /**\n * Removes the object at the specified index from the list of sub-objects.\n *\n * @method removeObjectAt\n * @param {number} index The index of the objec to remove.\n */\n\n Object_Base.prototype.removeObjectAt = function(index) {\n var object;\n object = this.subObjects[index];\n this.subObjects.splice(index, 1);\n object.parent = null;\n return this.needsUpdate = true;\n };\n\n\n /**\n * Removes all sub-objects.\n *\n * @method removeAllObjects\n */\n\n Object_Base.prototype.removeAllObjects = function() {\n var results;\n results = [];\n while (this.subObjects.length > 0) {\n results.push(this.removeObjectAt(0));\n }\n return results;\n };\n\n\n /**\n * Erases the object at the specified index. The list size\n * will not be changed but the the value at the index will be set to null.\n *\n * @method eraseObject\n * @param {Number} object The object which should be erased.\n */\n\n Object_Base.prototype.eraseObject = function(index) {\n var object;\n object = this.subObjects[index];\n if (object != null) {\n object.parent = null;\n }\n return this.subObjects[index] = null;\n };\n\n\n /**\n * Adds the specified component to the object.\n *\n * @method addComponent\n * @param {Component} component The component\n * @param {String} id An optional unique identifier for the component.\n */\n\n Object_Base.prototype.addComponent = function(component, id) {\n if (!this.components.contains(component)) {\n component.object = this;\n this.components.push(component);\n if (id != null) {\n return this.componentsById[id] = component;\n }\n }\n };\n\n\n /**\n * Inserts a component at the specified index.\n *\n * @method insertComponent\n * @param {Component} component The component.\n * @param {Number} index The index.\n * @param {String} id An optional unique identifier for the component.\n */\n\n Object_Base.prototype.insertComponent = function(component, index, id) {\n this.components.remove(component);\n component.object = this;\n this.components.splice(index, 0, component);\n if (id != null) {\n return this.componentsById[id] = component;\n }\n };\n\n\n /**\n * Removes a component from the object.\n *\n * @method removeComponent\n * @param {Component} component The component to remove.\n */\n\n Object_Base.prototype.removeComponent = function(component) {\n this.components.remove(component);\n if (typeof id !== \"undefined\" && id !== null) {\n return delete this.componentsById[id];\n }\n };\n\n return Object_Base;\n\n})();\n\ngs.Object_Base = Object_Base;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7O3dCQVFBLG1CQUFBLEdBQXFCLFNBQUMsSUFBRCxFQUFPLE9BQVA7SUFDakIsSUFBRyxJQUFDLENBQUEsRUFBSjthQUNJLE1BQU8sQ0FBQSxHQUFBLEdBQUksSUFBQyxDQUFBLEVBQUwsQ0FBUCxHQUFrQixLQUR0Qjs7RUFEaUI7O0VBV3JCLFdBQUMsQ0FBQSxTQUFELENBQVcsT0FBWCxFQUNJO0lBQUEsR0FBQSxFQUFLLFNBQUMsQ0FBRDtBQUNELFVBQUE7TUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVOzJEQUNjLENBQUUsVUFBMUIsQ0FBcUMsSUFBckMsRUFBMkMsQ0FBM0M7SUFGQyxDQUFMO0lBSUEsR0FBQSxFQUFLLFNBQUE7YUFBRyxJQUFDLENBQUE7SUFBSixDQUpMO0dBREo7O0VBY0EsV0FBQyxDQUFBLFNBQUQsQ0FBVyxPQUFYLEVBQ0k7SUFBQSxHQUFBLEVBQUssU0FBQyxDQUFEO0FBQ0QsVUFBQTtNQUFBLElBQUcsQ0FBQSxLQUFLLElBQUMsQ0FBQSxNQUFUO1FBQ0ksSUFBQyxDQUFBLE1BQUQsR0FBVTtnREFDSCxDQUFFLFNBQVQsR0FBcUIsY0FGekI7O0lBREMsQ0FBTDtJQUlBLEdBQUEsRUFBSyxTQUFBO2FBQUcsSUFBQyxDQUFBO0lBQUosQ0FKTDtHQURKOztFQWVBLFdBQUMsQ0FBQSxTQUFELENBQVcsYUFBWCxFQUNJO0lBQUEsR0FBQSxFQUFLLFNBQUMsQ0FBRDtBQUNELFVBQUE7TUFBQSxJQUFDLENBQUEsWUFBRCxHQUFnQjtNQUVoQixNQUFBLEdBQVMsSUFBQyxDQUFBO0FBQ1YsYUFBTSxNQUFOO1FBQ0ksTUFBTSxDQUFDLFlBQVAsR0FBc0I7UUFDdEIsTUFBQSxHQUFTLE1BQU0sQ0FBQztNQUZwQjtNQVNBLElBQUcsQ0FBSDtlQUNJLElBQUMsQ0FBQSxnQkFBRCxDQUFBLEVBREo7O0lBYkMs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QUFDLElBQVosQ0FBaUIsU0FBakI7TUFDQSxJQUFHLFVBQUg7ZUFDSSxJQUFDLENBQUEsY0FBZSxDQUFBLEVBQUEsQ0FBaEIsR0FBc0IsVUFEMUI7T0FISjs7RUFEVTs7O0FBTWQ7Ozs7Ozs7Ozt3QkFRQSxlQUFBLEdBQWlCLFNBQUMsU0FBRCxFQUFZLEtBQVosRUFBbUIsRUFBbkI7SUFDYixJQUFDLENBQUEsVUFBVSxDQUFDLE1BQVosQ0FBbUIsU0FBbkI7SUFDQSxTQUFTLENBQUMsTUFBVixHQUFtQjtJQUNuQixJQUFDLENBQUEsVUFBVSxDQUFDLE1BQVosQ0FBbUIsS0FBbkIsRUFBMEIsQ0FBMUIsRUFBNkIsU0FBN0I7SUFDQSxJQUFHLFVBQUg7YUFDSSxJQUFDLENBQUEsY0FBZSxDQUFBLEVBQUEsQ0FBaEIsR0FBc0IsVUFEMUI7O0VBSmE7OztBQU9qQjs7Ozs7Ozt3QkFNQSxlQUFBLEdBQWlCLFNBQUMsU0FBRDtJQUNiLElBQUMsQ0FBQSxVQUFVLENBQUMsTUFBWixDQUFtQixTQUFuQjtJQUNBLElBQUcsd0NBQUg7YUFDSSxPQUFPLElBQUMsQ0FBQSxjQUFlLENBQUEsRUFBQSxFQUQzQjs7RUFGYTs7Ozs7O0FBS3JCLEVBQUUsQ0FBQyxXQUFILEdBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4jXG4jICAgU2NyaXB0OiBPYmplY3RfQmFzZVxuI1xuIyAgICQkQ09QWVJJR0hUJCRcbiNcbiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuY2xhc3MgT2JqZWN0X0Jhc2VcbiAgICAjIyMqXG4gICAgKiBDYWxsZWQgaWYgdGhpcyBvYmplY3QgaW5zdGFuY2UgaXMgcmVzdG9yZWQgZnJvbSBhIGRhdGEtYnVuZGxlLiBJdCBjYW4gYmUgdXNlZFxuICAgICogcmUtYXNzaWduIGV2ZW50LWhhbmRsZXIsIGFub255bW91cyBmdW5jdGlvbnMsIGV0Yy5cbiAgICAqIFxuICAgICogQG1ldGhvZCBvbkRhdGFCdW5kbGVSZXN0b3JlLlxuICAgICogQHBhcmFtIE9iamVjdCBkYXRhIC0gVGhlIGRhdGEtYnVuZGxlXG4gICAgKiBAcGFyYW0gZ3MuT2JqZWN0Q29kZWNDb250ZXh0IGNvbnRleHQgLSBUaGUgY29kZWMtY29udGV4dC5cbiAgICAjIyNcbiAgICBvbkRhdGFCdW5kbGVSZXN0b3JlOiAoZGF0YSwgY29udGV4dCkgLT5cbiAgICAgICAgaWYgQGlkXG4gICAgICAgICAgICB3aW5kb3dbXCIkXCIrQGlkXSA9IHRoaXNcbiAgICAgICAgICAgIFxuICAgIFxuICAgICNcbiAgICAjIEdldHMgb3Igc2V0cyB0aGUgZ3JvdXAgdGhlIG9iamVjdCBiZWxvbmdzIHRvLlxuICAgICNcbiAgICAjIEBwcm9wZXJ0eSBncm91cFxuICAgICMgQHR5cGUgc3RyaW5nXG4gICAgI1xuICAgIEBhY2Nlc3NvcnMgXCJncm91cFwiLCBcbiAgICAgICAgc2V0OiAoZykgLT4gXG4gICAgICAgICAgICBAZ3JvdXBfID0gZ1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50Py5hZGRUb0dyb3VwKHRoaXMsIGcpXG4gICAgICAgICAgICBcbiAgICAgICAgZ2V0OiAtPiBAZ3JvdXBfXG4gICAgICAgIFxuICAgICNcbiAgICAjIEdldHMgb3Igc2V0cyB0aGUgb3JkZXItaW5kZXggb2YgdGhlIG9iamVjdC4gVGhlIGxvd2VyIHRoZSBpbmRleCwgdGhlXG4gICAgIyBlYXJsaWVyIHRoZSBvYmplY3Qgd2lsbCBiZSB1cGRhdGVkIGluIGEgbGlzdCBvZiBzdWItb2JqZWN0cy5cbiAgICAjXG4gICAgIyBAcHJvcGVydHkgb3JkZXJcbiAgICAjIEB0eXBlIG51bWJlclxuICAgICNcbiAgICBAYWNjZXNzb3JzIFwib3JkZXJcIixcbiAgICAgICAgc2V0OiAobykgLT5cbiAgICAgICAgICAgIGlmIG8gIT0gQG9yZGVyX1xuICAgICAgICAgICAgICAgIEBvcmRlcl8gPSBvXG4gICAgICAgICAgICAgICAgQHBhcmVudD8ubmVlZHNTb3J0ID0gdHJ1ZVxuICAgICAgICBnZXQ6IC0+IEBvcmRlcl9cbiAgICAgICAgXG4gICAgI1xuICAgICMgR2V0cyBvciBzZXRzIGlmIGFuIG9iamVjdHMgbmVlZHMgYW4gdXBkYXRlLiBJZiB0cnVlLCB0aGUgcGFyZW50IHdpbGwgdXBkYXRlXG4gICAgIyB0aGUgb2JqZWN0IGluIHRoZSBuZXh0IHVwZGF0ZSBhbmQgcmVzZXRzIHRoZSBuZWVkc1VwZGF0ZSBwcm9wZXJ0eSBiYWNrXG4gICAgIyB0byBmYWxzZS5cbiAgICAjXG4gICAgIyBAcHJvcGVydHkgbmVlZHNVcGRhdGVcbiAgICAjIEB0eXBlIGJvb2xlYW5cbiAgICAjXG4gICAgQGFjY2Vzc29ycyBcIm5lZWRzVXBkYXRlXCIsIFxuICAgICAgICBzZXQ6ICh2KSAtPlxuICAgICAgICAgICAgQG5lZWRzVXBkYXRlXyA9IHZcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50ID0gQHBhcmVudFxuICAgICAgICAgICAgd2hpbGUgcGFyZW50XG4gICAgICAgICAgICAgICAgcGFyZW50Lm5lZWRzVXBkYXRlXyA9IHllc1xuICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICNpZiB2XG4gICAgICAgICAgICAjICAgIEBwYXJlbnQ/Lm5lZWRzVXBkYXRlID0geWVzXG4gICAgICAgICAgICAjaWYgdlxuICAgICAgICAgICAgIyAgICBmb3Igb2JqZWN0IGluIEBzdWJPYmplY3RzXG4gICAgICAgICAgICAjICAgICAgICBvYmplY3QubmVlZHNVcGRhdGVfID0gdlxuICAgICAgICAgICAgaWYgdlxuICAgICAgICAgICAgICAgIEByZXF1ZXN0U3ViVXBkYXRlKClcbiAgICAgICAgZ2V0OiAtPiByZXR1cm4gQG5lZWRzVXBkYXRlXyB8fCBTY2VuZU1hbmFnZXIuc2NlbmUucHJlcGFyaW5nXG4gICAgICAgIFxuICAgIHJlcXVlc3RTdWJVcGRhdGU6IC0+XG4gICAgICAgIGZvciBvYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgIGlmIG9iamVjdFxuICAgICAgICAgICAgICAgIG9iamVjdC5uZWVkc1VwZGF0ZV8gPSB5ZXNcbiAgICAgICAgICAgICAgICBvYmplY3QucmVxdWVzdFN1YlVwZGF0ZSgpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgI1xuICAgICMgR2V0cyBvciBzZXRzIGlmIGFuIG9iamVjdCBuZWVkcyBhIGZ1bGwgdXBkYXRlLiBBIGZ1bGwgdXBkYXRlIHRyaWdnZXJzXG4gICAgIyBhbiB1cGRhdGUgZm9yIGFsbCBzdWItb2JqZWN0cyByZWN1cnNpdmVseS4gXG4gICAgI1xuICAgICMgQHByb3BlcnR5IG5lZWRzRnVsbFVwZGF0ZVxuICAgICMgQHR5cGUgYm9vbGVhblxuICAgICNcbiAgICBAYWNjZXNzb3JzIFwibmVlZHNGdWxsVXBkYXRlXCIsIFxuICAgICAgICBzZXQ6ICh2KSAtPlxuICAgICAgICAgICAgQG5lZWRzVXBkYXRlID0gdlxuICAgICAgICAgICAgaWYgdlxuICAgICAgICAgICAgICAgIGZvciBvYmplY3QgaW4gQHN1Yk9iamVjdHNcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm5lZWRzRnVsbFVwZGF0ZSA9IHZcbiAgICAgICAgZ2V0OiAtPiBAbmVlZHNVcGRhdGVfXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBUaGUgYmFzZSBjbGFzcyBmb3IgYWxsIGdhbWUgb2JqZWN0cy4gQSBnYW1lIG9iamVjdCBpdHNlbGYgZG9lc24ndCBpbXBsZW1lbnRcbiAgICAqIGFueSBnYW1lIGxvZ2ljIGJ1dCB1c2VzIGNvbXBvbmVudHMgYW5kIHN1Yi1vYmplY3RzIGZvciB0aGF0LlxuICAgICpcbiAgICAqIEBtb2R1bGUgZ3NcbiAgICAqIEBjbGFzcyBPYmplY3RfQmFzZVxuICAgICogQG1lbWJlcm9mIGdzXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAjIyNcbiAgICBjb25zdHJ1Y3RvcjogKCkgLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdWJPYmplY3RzXG4gICAgICAgICogQHR5cGUgZ3MuT2JqZWN0X0Jhc2VbXVxuICAgICAgICAqIEBkZWZhdWx0IFtdXG4gICAgICAgICogQSBsaXN0IG9mIGdhbWUtb2JqZWN0cyBncm91cGVkIHVuZGVyIHRoaXMgZ2FtZSBvYmplY3QuXG4gICAgICAgICMjI1xuICAgICAgICBAc3ViT2JqZWN0cyA9IFtdXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGNvbXBvbmVudHNcbiAgICAgICAgKiBAdHlwZSBncy5Db21wb25lbnRbXVxuICAgICAgICAqIEBkZWZhdWx0IFtdXG4gICAgICAgICogQSBsaXN0IG9mIGNvbXBvbmVudHMgZGVmaW5pbmcgdGhlIGxvZ2ljL2JlaGF2aW9yIGFuZCBhcHBlYXJhbmNlIG9mIHRoZSBnYW1lIG9iamVjdC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBjb21wb25lbnRzID0gW11cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgY29tcG9uZW50c0J5SWRcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgKiBAZGVmYXVsdCBbXVxuICAgICAgICAqIEFsbCBhc3NvY2lhdGVkIGNvbXBvbmVudHMgYnkgdGhlaXIgSUQuXG4gICAgICAgICMjI1xuICAgICAgICBAY29tcG9uZW50c0J5SWQgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBkaXNwb3NlZFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgZ2FtZSBvYmplY3QgaWQgZGlzcG9zZWQuIEEgZGlzcG9zZWQgZ2FtZSBvYmplY3QgY2Fubm90IGJlIHVzZWQgYW55bW9yZS5cbiAgICAgICAgIyMjXG4gICAgICAgIEBkaXNwb3NlZCA9IG5vXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGFjdGl2ZVxuICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGdhbWUgb2JqZWN0IGlzIGFjdGl2ZS4gQW4gaW5hY3RpdmUgZ2FtZSBvYmplY3Qgd2lsbCBub3QgYmUgdXBkYXRlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBhY3RpdmUgPSB5ZXNcbiAgICAgICAgXG4gICAgICAgIEBpbnB1dCA9IG5vXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IGlkXG4gICAgICAgICogQHR5cGUgc3RyaW5nXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIFRoZSBnYW1lIG9iamVjdCdzIFVJRCAoVW5pcXVlIElEKVxuICAgICAgICAjIyNcbiAgICAgICAgQGlkID0gbnVsbCBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgZ3JvdXBcbiAgICAgICAgKiBAZGVmYXVsdCBudWxsXG4gICAgICAgICogQHR5cGUgc3RyaW5nXG4gICAgICAgICogVGhlIGdhbWUgb2JqZWN0J3MgZ3JvdXAuIFRvIGdldCBhbGwgb2JqZWN0J3Mgb2YgYSBzcGVjaWZpYyBncm91cCB0aGUgZ3MuT2JqZWN0TWFuYWdlci5vYmplY3RzQnlHcm91cCBwcm9wZXJ0eSBjYW4gYmUgdXNlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBncm91cCA9IG51bGwgXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IHBhcmVudFxuICAgICAgICAqIEB0eXBlIGdzLk9iamVjdF9CYXNlXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIFRoZSBwYXJlbnQgb2JqZWN0IGlmIHRoZSBnYW1lIG9iamVjdCBpcyBhIHN1Yi1vYmplY3Qgb2YgYW5vdGhlciBnYW1lIG9iamVjdC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBwYXJlbnQgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IG9yZGVyXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICogQGRlZmF1bHQgMFxuICAgICAgICAqIENvbnRyb2xzIHRoZSB1cGRhdGUtb3JkZXIuIFRoZSBzbWFsbGVyIHRoZSB2YWx1ZSB0aGUgZWFybGllciB0aGUgZ2FtZSBvYmplY3QgaXMgdXBkYXRlZCBiZWZvcmUgb3RoZXIgZ2FtZSBvYmplY3RzIGFyZSB1cGRhdGVkLlxuICAgICAgICAjIyNcbiAgICAgICAgQG9yZGVyID0gMFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBySW5kZXhcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgKiBAZGVmYXVsdCAwXG4gICAgICAgICogSG9sZHMgdGhlIHJlbmRlci1pbmRleCBpZiB0aGUgZ2FtZSBvYmplY3QgaGFzIGEgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9uIHNjcmVlbi4gVGhlIHJlbmRlci1pbmRleCBpcyB0aGVcbiAgICAgICAgKiBpbmRleCBvZiB0aGUgZ2FtZSBvYmplY3QncyBncmFwaGljLW9iamVjdChncy5HcmFwaGljT2JqZWN0KSBpbiB0aGUgY3VycmVudCBsaXN0IG9mIGdyYXBoaWMtb2JqZWN0cy4gVGhlIHJlbmRlci1pbmRleFxuICAgICAgICAqIGlzIHJlYWQtb25seS4gU2V0dGluZyB0aGUgcmVuZGVyLWluZGV4IHRvIGEgY2VydGFpbiB2YWx1ZSBoYXMgbm8gZWZmZWN0LlxuICAgICAgICAjIyNcbiAgICAgICAgQHJJbmRleCA9IDBcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgbmVlZHNTb3J0XG4gICAgICAgICogQHR5cGUgYm9vbGVhblxuICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGxpc3Qgb2Ygc3ViLW9iamVjdHMgbmVlZHMgdG8gYmUgc29ydGVkIGJ5IG9yZGVyIGJlY2F1c2Ugb2YgYSBjaGFuZ2UuXG4gICAgICAgICMjI1xuICAgICAgICBAbmVlZHNTb3J0ID0geWVzXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQHByb3BlcnR5IG5lZWRzU29ydFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBVSSBvYmplY3QgbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAgICAgICAgIyMjXG4gICAgICAgIEBuZWVkc1VwZGF0ZSA9IHllc1xuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBpbml0aWFsaXplZFxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBnYW1lIG9iamVjdCBhbmQgaXRzIGNvbXBvbmVudHMgaGF2ZSBiZWVuIGluaXRpYWxpemVkLlxuICAgICAgICAjIyNcbiAgICAgICAgQGluaXRpYWxpemVkID0gbm9cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tRGF0YVxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAqIEBkZWZhdWx0IHt9XG4gICAgICAgICogQSBjdXN0b20gZGF0YSBvYmplY3Qgd2hpY2ggY2FuIGJlIHVzZWQgdG8gYWRkIGFueSBjdXN0b20gZGF0YS9maWVsZHMgdG8gdGhlIGdhbWVcbiAgICAgICAgKiBvYmplY3QuIEl0IGlzIGFuIGVtcHR5IG9iamVjdCBieSBkZWZhdWx0LlxuICAgICAgICAjIyNcbiAgICAgICAgQGN1c3RvbURhdGEgPSB7fVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8ucmVnaXN0ZXJPYmplY3QodGhpcylcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgdGhlIG9iamVjdCB3aXRoIGFsbCBpdHMgY29tcG9uZW50cyBhbmQgc3ViLW9iamVjdHMuIEEgZGlzcG9zZWQgb2JqZWN0IHdpbGwgYmVcbiAgICAqIHJlbW92ZWQgZnJvbSB0aGUgcGFyZW50IGF1dG9tYXRpY2FsbHkuXG4gICAgKlxuICAgICogQG1ldGhvZCBkaXNwb3NlXG4gICAgIyMjXG4gICAgZGlzcG9zZTogLT5cbiAgICAgICAgaWYgbm90IEBkaXNwb3NlZFxuICAgICAgICAgICAgQGRpc3Bvc2VkID0geWVzXG4gICAgICAgICAgICBAZGlzcG9zZUNvbXBvbmVudHMoKVxuICAgICAgICAgICAgQGRpc3Bvc2VPYmplY3RzKClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8udW5yZWdpc3Rlck9iamVjdCh0aGlzKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgYWxsIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZU9iamVjdHNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyNcbiAgICBkaXNwb3NlT2JqZWN0czogLT5cbiAgICAgICAgZm9yIHN1Yk9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgc3ViT2JqZWN0Py5kaXNwb3NlPygpXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBEaXNwb3NlcyBhbGwgY29tcG9uZW50c1xuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZUNvbXBvbmVudHNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyNcbiAgICBkaXNwb3NlQ29tcG9uZW50czogLT5cbiAgICAgICAgZm9yIGNvbXBvbmVudCBpbiBAY29tcG9uZW50c1xuICAgICAgICAgICAgY29tcG9uZW50Py5kaXNwb3NlPygpXG4gICAgICAgXG4gICAgIyMjKlxuICAgICogQ2FsbHMgc2V0dXAtcm91dGluZSBvbiBhbGwgY29tcG9uZW50cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldHVwXG4gICAgIyMjXG4gICAgc2V0dXA6IC0+XG4gICAgICAgIGZvciBjb21wb25lbnQgaW4gQGNvbXBvbmVudHNcbiAgICAgICAgICAgIGNvbXBvbmVudC5zZXR1cCgpIGlmIG5vdCBjb21wb25lbnQ/LmlzU2V0dXBcbiAgICAgICAgICAgIFxuICAgICAgICBAaW5pdGlhbGl6ZWQgPSB5ZXNcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGVzZXJpYWxpemVzIGNvbXBvbmVudHMgZnJvbSBhIGRhdGEtYnVuZGxlIG9iamVjdC5cbiAgICAqIFxuICAgICogQG1ldGhvZCBjb21wb25lbnRzRnJvbURhdGFCdW5kbGVcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIFRoZSBkYXRhLWJ1bmRsZSBvYmplY3QuXG4gICAgIyMjXG4gICAgY29tcG9uZW50c0Zyb21EYXRhQnVuZGxlOiAoZGF0YSkgLT5cbiAgICAgICAgaWYgZGF0YT8uY29tcG9uZW50c1xuICAgICAgICAgICAgZm9yIGNvbXBvbmVudCBpbiBkYXRhLmNvbXBvbmVudHNcbiAgICAgICAgICAgICAgICBjb21wb25lbnRPYmplY3QgPSBuZXcgZ3NbY29tcG9uZW50LmNsYXNzTmFtZV0oY29tcG9uZW50KVxuICAgICAgICAgICAgICAgIEBhZGRDb21wb25lbnQoY29tcG9uZW50T2JqZWN0KVxuICAgICAgICAgICAgZGVsZXRlIGRhdGEuY29tcG9uZW50c1xuICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXJpYWxpemVzIGNvbXBvbmVudHMgb2YgYSBzcGVjaWZpZWQgdHlwZSB0byBhIGRhdGEtYnVuZGxlLiBBIGNvbXBvbmVudFxuICAgICogbmVlZHMgdG8gaW1wbGVtZW50IHRoZSB0b0RhdGFCdW5kbGUgbWV0aG9kIGZvciBjb3JyZWN0IHNlcmlhbGl6YXRpb24uXG4gICAgKlxuICAgICogQG1ldGhvZCBjb21wb25lbnRzVG9EYXRhQnVuZGxlXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIEEgY29tcG9uZW50IGNsYXNzIG5hbWUuXG4gICAgKiBAcmV0dXJuIEEgZGF0YSBidW5kbGUuXG4gICAgIyMjXG4gICAgY29tcG9uZW50c1RvRGF0YUJ1bmRsZTogKHR5cGUpIC0+XG4gICAgICAgIGNvbXBvbmVudHMgPSBbXVxuICAgICAgICBmb3IgY29tcG9uZW50IGluIEBjb21wb25lbnRzXG4gICAgICAgICAgICBpZiBjb21wb25lbnQgaW5zdGFuY2VvZiB0eXBlXG4gICAgICAgICAgICAgICAgY29udGludWUgdW5sZXNzIGNvbXBvbmVudC50b0RhdGFCdW5kbGU/XG4gICAgICAgICAgICAgICAgYnVuZGxlID0gY29tcG9uZW50LnRvRGF0YUJ1bmRsZSgpXG4gICAgICAgICAgICAgICAgYnVuZGxlLmNsYXNzTmFtZSA9IGNvbXBvbmVudC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKGJ1bmRsZSlcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudHNcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogU3RhcnRzIGEgZnVsbC1yZWZyZXNoIG9uIGFsbCBzdWItb2JqZWN0c1xuICAgICpcbiAgICAqIEBtZXRob2QgZnVsbFJlZnJlc2hcbiAgICAjIyNcbiAgICBmdWxsUmVmcmVzaDogLT5cbiAgICAgICAgZm9yIG9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgaWYgb2JqZWN0XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5lZWRzVXBkYXRlID0geWVzXG4gICAgICAgICAgICAgICAgb2JqZWN0LmZ1bGxSZWZyZXNoKClcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIFxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgdGhlIG9iamVjdCB3aXRoIGFsbCBwYXJlbnQtIGFuZCBzdWItb2JqZWN0cy4gXG4gICAgKlxuICAgICogQG1ldGhvZCBmdWxsVXBkYXRlXG4gICAgIyMjXG4gICAgZnVsbFVwZGF0ZTogLT5cbiAgICAgICAgcGFyZW50ID0gdGhpc1xuICAgICAgICB3aGlsZSBwYXJlbnQgIT0gbnVsbFxuICAgICAgICAgICAgcGFyZW50LnVwZGF0ZSgpXG4gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50XG4gICAgICAgICAgICBcbiAgICAgICAgZm9yIG9iamVjdCBpbiBAc3ViT2JqZWN0c1xuICAgICAgICAgICAgb2JqZWN0Py51cGRhdGUoKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBVcGRhdGVzIHRoZSBvYmplY3QgYW5kIGFsbCBpdHMgY29tcG9uZW50cy4gVGhpcyBtZXRob2QgaXNcbiAgICAqIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSBwYXJlbnQgb3IgT2JqZWN0TWFuYWdlciBzbyBpbiByZWd1bGFyIGl0IGlzIFxuICAgICogbm90IG5lY2Vzc2FyeSB0byBjYWxsIGl0IG1hbnVhbGx5LlxuICAgICpcbiAgICAqIEBtZXRob2QgdXBkYXRlXG4gICAgIyMjXG4gICAgdXBkYXRlOiAtPlxuICAgICAgICByZXR1cm4gaWYgIUBhY3RpdmVcbiAgICAgICAgaSA9IDBcbiAgICAgICAgd2hpbGUgaSA8IEBjb21wb25lbnRzLmxlbmd0aFxuICAgICAgICAgICAgY29tcG9uZW50ID0gQGNvbXBvbmVudHNbaV1cbiAgICAgICAgICAgIGlmIG5vdCBjb21wb25lbnQuZGlzcG9zZWRcbiAgICAgICAgICAgICAgICBjb21wb25lbnQudXBkYXRlKClcbiAgICAgICAgICAgICAgICBpKytcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBAY29tcG9uZW50cy5zcGxpY2UoaSwgMSlcblxuXG4gICAgICAgIGlmIEBpbnB1dCB0aGVuIElucHV0LmNsZWFyKClcbiAgICAgICAgQGlucHV0ID0gbm9cbiAgICAgICAgXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRDb21wb25lbnRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSBjb21wb25lbnQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgb3IgbnVsbCBpZiBhIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZSBjYW5ub3QgYmUgZm91bmQuXG4gICAgIyMjXG4gICAgZmluZENvbXBvbmVudDogKG5hbWUpIC0+IEBjb21wb25lbnRzLmZpcnN0ICh2KSAtPiB2LmNvbnN0cnVjdG9yLm5hbWUgPT0gbmFtZVxuICAgIFxuICAgICMjIypcbiAgICAqIFNlYXJjaGVzIGZvciBhbGwgY29tcG9uZW50cyB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRDb21wb25lbnRzXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgY29tcG9uZW50cy5cbiAgICAqIEByZXR1cm4ge0FycmF5fSBUaGUgY29tcG9uZW50cyBvciBudWxsIGlmIG5vIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZSBoYXMgYmVlbiBmb3VuZC5cbiAgICAjIyNcbiAgICBmaW5kQ29tcG9uZW50czogKG5hbWUpIC0+IEBjb21wb25lbnRzLndoZXJlICh2KSAtPiB2LmNvbnN0cnVjdG9yLm5hbWUgPT0gbmFtZVxuICAgIFxuICAgICMjIypcbiAgICAqIFNlYXJjaGVzIGZvciB0aGUgY29tcG9uZW50IHdpdGggdGhlIHNwZWNpZmllZCBJRC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRDb21wb25lbnRCeUlkXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBjb21wb25lbnQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgb3IgbnVsbCBpZiBhIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgSUQgY2Fubm90IGJlIGZvdW5kLlxuICAgICMjI1xuICAgIGZpbmRDb21wb25lbnRCeUlkOiAoaWQpIC0+IEBjb21wb25lbnRzQnlJZFtpZF1cbiAgICBcbiAgICAjIyMqXG4gICAgKiBTZWFyY2hlcyBmb3IgdGhlIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4gSWYgbXVsdGlwbGUgY29tcG9uZW50cyBoYXZlIHRoZVxuICAgICogc2FtZSBuYW1lLCBpdCB3aWxsIHJldHVybiB0aGUgZmlyc3QgbWF0Y2guXG4gICAgKlxuICAgICogQG1ldGhvZCBmaW5kQ29tcG9uZW50QnlOYW1lXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY29tcG9uZW50IHRvIGZpbmQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgb3IgbnVsbCBpZiBhIGNvbXBvbmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBjYW5ub3QgYmUgZm91bmQuXG4gICAgIyMjXG4gICAgZmluZENvbXBvbmVudEJ5TmFtZTogKG5hbWUpIC0+IEBjb21wb25lbnRzLmZpcnN0ICh2KSAtPiB2Lm5hbWUgPT0gbmFtZVxuICAgIFxuICAgICMjIypcbiAgICAqIFNlYXJjaGVzIGZvciBjb21wb25lbnRzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLlxuICAgICpcbiAgICAqIEBtZXRob2QgZmluZENvbXBvbmVudHNCeU5hbWVcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnRzIHRvIGZpbmQuXG4gICAgKiBAcmV0dXJuIHtDb21wb25lbnRbXX0gQW4gYXJyYXkgb2YgY29tcG9uZW50cyBtYXRjaGluZyB0aGUgc3BlY2lmaWVkIG5hbWUgb3IgbnVsbCBpZiBubyBjb21wb25lbnRzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGV4aXN0LlxuICAgICMjI1xuICAgIGZpbmRDb21wb25lbnRzQnlOYW1lOiAobmFtZSkgLT4gQGNvbXBvbmVudHMud2hlcmUgKHYpIC0+IHYubmFtZSA9PSBuYW1lXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyBhbiBvYmplY3QgdG8gdGhlIGxpc3Qgb2Ygc3ViLW9iamVjdHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBhZGRPYmplY3RcbiAgICAqIEBwYXJhbSB7T2JqZWN0X0Jhc2V9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBhZGRlZC5cbiAgICAjIyNcbiAgICBhZGRPYmplY3Q6IChvYmplY3QpIC0+XG4gICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudD8ucmVtb3ZlKG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudD8ucmVtb3ZlT2JqZWN0KG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgQHN1Yk9iamVjdHMucHVzaChvYmplY3QpXG4gICAgICAgIEBuZWVkc1NvcnQgPSB5ZXNcbiAgICAgICAgQG5lZWRzVXBkYXRlID0geWVzXG4gICAgXG4gICAgICAgIGlmIG9iamVjdC5pZD9cbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudC5zZXRPYmplY3RCeUlkKG9iamVjdCwgb2JqZWN0LmlkKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBJbnNlcnRzIGFuIG9iamVjdCBpbnRvIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAgKlxuICAgICogQG1ldGhvZCBpbnNlcnRPYmplY3RcbiAgICAqIEBwYXJhbSB7T2JqZWN0X0Jhc2V9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBpbnNlcnRlZC5cbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCBUaGUgaW5kZXguXG4gICAgIyMjXG4gICAgaW5zZXJ0T2JqZWN0OihvYmplY3QsIGluZGV4KSAtPlxuICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQucmVtb3ZlKG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudD8ucmVtb3ZlT2JqZWN0KG9iamVjdClcbiAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgQHN1Yk9iamVjdHMuc3BsaWNlKGluZGV4LCAwLCBvYmplY3QpXG4gICAgICBcbiAgICAgICAgaWYgb2JqZWN0LmlkP1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQob2JqZWN0LCBvYmplY3QuaWQpXG4gICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHN1Yi1vYmplY3QgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldE9iamVjdFxuICAgICogQHBhcmFtIHtPYmplY3RfQmFzZX0gb2JqZWN0IFRoZSBvYmplY3QuXG4gICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4LlxuICAgICMjI1xuICAgIHNldE9iamVjdDogKG9iamVjdCwgaW5kZXgpIC0+XG4gICAgICAgIGlmIG9iamVjdFxuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnJlbW92ZShvYmplY3QpXG4gICAgICAgICAgICBvYmplY3QucGFyZW50Py5yZW1vdmVPYmplY3Qob2JqZWN0KVxuICAgICAgICAgICAgb2JqZWN0LnBhcmVudCA9IHRoaXNcbiAgICAgICAgICAgIFxuICAgICAgICBAc3ViT2JqZWN0c1tpbmRleF0gPSBvYmplY3RcbiAgICAgIFxuICAgICAgICBpZiBvYmplY3Q/LmlkP1xuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQob2JqZWN0LCBvYmplY3QuaWQpXG4gICAgXG4gICAgIyMjKlxuICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCBmcm9tIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVtb3ZlT2JqZWN0XG4gICAgKiBAcGFyYW0ge09iamVjdF9CYXNlfSBvYmplY3QgVGhlIG9iamVjdCB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZC5cbiAgICAjIyNcbiAgICByZW1vdmVPYmplY3Q6IChvYmplY3QpIC0+XG4gICAgICAgIEBzdWJPYmplY3RzLnJlbW92ZShvYmplY3QpXG4gICAgICAgIG9iamVjdC5wYXJlbnQgPSBudWxsXG4gICAgICAgIEBuZWVkc1VwZGF0ZSA9IHllc1xuICAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBmcm9tIHRoZSBsaXN0IG9mIHN1Yi1vYmplY3RzLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmVtb3ZlT2JqZWN0QXRcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG9iamVjIHRvIHJlbW92ZS5cbiAgICAjIyMgICBcbiAgICByZW1vdmVPYmplY3RBdDogKGluZGV4KSAtPlxuICAgICAgICBvYmplY3QgPSBAc3ViT2JqZWN0c1tpbmRleF1cbiAgICAgICAgQHN1Yk9iamVjdHMuc3BsaWNlKGluZGV4LCAxKVxuICAgICAgICBvYmplY3QucGFyZW50ID0gbnVsbFxuICAgICAgICBAbmVlZHNVcGRhdGUgPSB5ZXNcbiAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIGFsbCBzdWItb2JqZWN0cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlbW92ZUFsbE9iamVjdHNcbiAgICAjIyMgICAgIFxuICAgIHJlbW92ZUFsbE9iamVjdHM6IC0+XG4gICAgICAgIHdoaWxlIEBzdWJPYmplY3RzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgIEByZW1vdmVPYmplY3RBdCgwKVxuICAgIFxuICAgICMjIypcbiAgICAqIEVyYXNlcyB0aGUgb2JqZWN0IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoZSBsaXN0IHNpemVcbiAgICAqIHdpbGwgbm90IGJlIGNoYW5nZWQgYnV0IHRoZSB0aGUgdmFsdWUgYXQgdGhlIGluZGV4IHdpbGwgYmUgc2V0IHRvIG51bGwuXG4gICAgKlxuICAgICogQG1ldGhvZCBlcmFzZU9iamVjdFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IG9iamVjdCBUaGUgb2JqZWN0IHdoaWNoIHNob3VsZCBiZSBlcmFzZWQuXG4gICAgIyMjXG4gICAgZXJhc2VPYmplY3Q6IChpbmRleCkgLT5cbiAgICAgICAgb2JqZWN0ID0gQHN1Yk9iamVjdHNbaW5kZXhdXG4gICAgICAgIG9iamVjdD8ucGFyZW50ID0gbnVsbFxuICAgICAgICBAc3ViT2JqZWN0c1tpbmRleF0gPSBudWxsXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudCB0byB0aGUgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgYWRkQ29tcG9uZW50XG4gICAgKiBAcGFyYW0ge0NvbXBvbmVudH0gY29tcG9uZW50IFRoZSBjb21wb25lbnRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBBbiBvcHRpb25hbCB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbXBvbmVudC5cbiAgICAjIyNcbiAgICBhZGRDb21wb25lbnQ6IChjb21wb25lbnQsIGlkKSAtPlxuICAgICAgICBpZiBub3QgQGNvbXBvbmVudHMuY29udGFpbnMoY29tcG9uZW50KVxuICAgICAgICAgICAgY29tcG9uZW50Lm9iamVjdCA9IHRoaXNcbiAgICAgICAgICAgIEBjb21wb25lbnRzLnB1c2goY29tcG9uZW50KVxuICAgICAgICAgICAgaWYgaWQ/XG4gICAgICAgICAgICAgICAgQGNvbXBvbmVudHNCeUlkW2lkXSA9IGNvbXBvbmVudFxuICAgICMjIypcbiAgICAqIEluc2VydHMgYSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGluc2VydENvbXBvbmVudFxuICAgICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBUaGUgY29tcG9uZW50LlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4IFRoZSBpbmRleC5cbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBBbiBvcHRpb25hbCB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbXBvbmVudC5cbiAgICAjIyMgICAgXG4gICAgaW5zZXJ0Q29tcG9uZW50OiAoY29tcG9uZW50LCBpbmRleCwgaWQpIC0+XG4gICAgICAgIEBjb21wb25lbnRzLnJlbW92ZShjb21wb25lbnQpXG4gICAgICAgIGNvbXBvbmVudC5vYmplY3QgPSB0aGlzXG4gICAgICAgIEBjb21wb25lbnRzLnNwbGljZShpbmRleCwgMCwgY29tcG9uZW50KVxuICAgICAgICBpZiBpZD9cbiAgICAgICAgICAgIEBjb21wb25lbnRzQnlJZFtpZF0gPSBjb21wb25lbnRcbiAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIGEgY29tcG9uZW50IGZyb20gdGhlIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJlbW92ZUNvbXBvbmVudFxuICAgICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHRvIHJlbW92ZS5cbiAgICAjIyMgIFxuICAgIHJlbW92ZUNvbXBvbmVudDogKGNvbXBvbmVudCkgLT4gXG4gICAgICAgIEBjb21wb25lbnRzLnJlbW92ZShjb21wb25lbnQpXG4gICAgICAgIGlmIGlkP1xuICAgICAgICAgICAgZGVsZXRlIEBjb21wb25lbnRzQnlJZFtpZF1cblxuZ3MuT2JqZWN0X0Jhc2UgPSBPYmplY3RfQmFzZSJdfQ==\n//# sourceURL=Object_Base_5.js"
13 13 },
14 14 "summary": [
15 15 "name",