Subversion Repository Public Repository

Nextrek

Diff Revisions 1085 vs 1086 for /s2s/data/4216707AK784EA4859S86BBE1FCA7990F36B.json

Diff revisions: vs.
  @@ -6,10 +6,10 @@
6 6 "name": "UIManager",
7 7 "type": "game_script",
8 8 "order": 8,
9 - "content": "# ===================================================================\n#\n# Script: UIManager\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\n\nclass Formula\n ###*\n * Encapsulates a UI formula. A formula can be used in UI layouts to define\n * property-bindings or to implement a specific behavior.\n *\n * @module ui\n * @class Formula\n * @memberof ui\n * @constructor\n * @param {Function} f - The formula-function. Defines the logic of the formula.\n * @param {Object} data - An optional data-object which can be accessed inside the formula-function.\n * @param {string} event - An optional event-name to define when the formula should be executed.\n ###\n constructor: (f, data, event) ->\n ###*\n * Indicates if its the first time the formula is called.\n * @property onInitialize\n * @type boolean\n ###\n @onInitialize = yes\n \n ###*\n * The formula-function.\n * @property exec_\n * @type Function\n ###\n @exec_ = f\n \n ###*\n * An optional data-object which can bes accessed inside the formula-function.\n * @property data\n * @type Object\n ### \n @data = data\n \n ###*\n * An optional event-name to define when the formula should be executed.\n * @property event\n * @type string\n ### \n @event = event\n \n ###*\n * An array of custom number-data which can be used for different purposes. The first element\n * is also used in onChange method to store the old value and check against the new one to detect a change.\n * @property numbers\n * @type number[]\n ### \n @numbers = new Array(10)\n @numbers[i] = 0 for i in [0..@numbers.length]\n \n ###*\n * An array of custom string-data which can be used for different purposes. The first element\n * is also used in onTextChange method to store the old value and check against the new one to detect a change.\n * @property strings\n * @type string[]\n ###\n @strings = new Array(10)\n @strings[i] = \"\" for i in [0..@strings.length]\n \n \n ###*\n * The formula-function. Its a wrapper-function before the first-time call was made.\n * @method exec\n ###\n exec: ->\n @exec = @exec_\n r = @exec_.apply(this, arguments)\n @onInitialize = no\n \n return r\n \n ###*\n * Checks if the specified number-value has changed since the last check. It uses\n * the first entry of the numbers-array to store the value and check against the new one.\n *\n * @method onChange\n * @param {number} numberValue - Number value to check.\n ### \n onChange: (numberValue) ->\n result = @numbers[0] != numberValue\n @numbers[0] = numberValue\n \n return result\n \n ###*\n * Checks if the specified text-value has changed since the last check. It uses\n * the first entry of the strings-array to store the value and check against the new one.\n *\n * @method onTextChange\n * @param {string} textValue - Text value to check.\n ### \n onTextChange: (textValue) ->\n result = @strings[0] != textValue\n @strings[0] = textValue\n \n return result\n \nui.Formula = Formula\n\nclass Space\n ###*\n * Describes a space inside or around something like a margin or padding.\n *\n * @module ui\n * @class Space\n * @memberof ui\n * @constructor\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n ###\n constructor: (left, top, right, bottom) ->\n ###*\n * Space at the left in pixels.\n * @property left\n * @type number\n ###\n @left = left\n \n ###*\n * Space at the top in pixels.\n * @property top\n * @type number\n ###\n @top = top\n \n ###*\n * Space at the right in pixels.\n * @property right\n * @type number\n ###\n @right = right\n \n ###*\n * Space at the bottom in pixels.\n * @property bottom\n * @type number\n ###\n @bottom = bottom\n \n ###*\n * Sets the coordinates of the space by copying them from a specified space.\n *\n * @method setFromObject\n * @param {Object} space - A space to copy.\n ### \n setFromObject: (space) ->\n @left = space.left\n @top = space.top\n @right = space.right\n @bottom = space.bottom\n \n ###*\n * Sets the coordinates of the space.\n *\n * @method set\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n ### \n set: (left, top, right, bottom) ->\n @left = left\n @top = top\n @right = right\n @bottom = bottom\n \n ###*\n * Creates a new space object from an array of coordinates.\n *\n * @method fromArray\n * @static\n * @param {number[]} array - An array of coordinates (left, top right, bottom).\n ### \n @fromArray: (array) -> new ui.Space(array[0], array[1], array[2], array[3])\n \nui.Space = Space\n\nclass Style\n ###*\n * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain \"style\" to it.\n *\n * @module ui\n * @class Style\n * @memberof ui\n * @constructor\n * @param {Object} descriptor - A style-descriptor to initialize the style from.\n * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.\n * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.\n ###\n constructor: (descriptor, id, selector) ->\n ###*\n * ID number to quickly access this style and link to this style.\n * @property id\n * @type number\n ###\n @id = id\n \n ###*\n * Style-ID of target object. This style will only be applied on UI objects with that style ID which are\n * children of UI objects where this style is applied.\n * @property target\n * @type number\n ###\n @target = -1\n \n ###*\n * Selector-ID which controls under which conditions the style becomes active.\n * @property selector\n * @type number\n ###\n @selector = selector\n \n ###*\n * The font used for the text-display.\n * @default null\n * @property font\n * @type gs.Font\n ###\n @font = null\n \n ###*\n * The UI object's image used for visual presentation.\n * @property image\n * @type string\n ###\n @image = null\n \n ###*\n * The UI object's animations used for visual presentation.\n * @default null\n * @property animations\n * @type Object[]\n ###\n @animations = null\n \n ###*\n * The UI object's color.\n * @property color\n * @type gs.Color\n ###\n @color = null\n \n ###*\n * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner\n * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1\n * places the object with its lower-right corner.\n * @property anchor\n * @type gs.Point\n ###\n @anchor = null\n \n ###*\n * The UI object's zoom-setting for x and y axis.\n * @default new gs.Point(1.0, 1.0)\n * @property zoom\n * @type gs.Point\n ###\n @zoom = null\n \n ###*\n * The UI object's margin. The margin defines an extra space around the UI object. \n * The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property margin\n * @type Object\n ###\n @margin = null\n \n ###*\n * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property padding\n * @type Object\n ###\n @padding = null\n \n ###*\n * The UI object's mask for masking-effects.\n * @property mask\n * @type gs.Mask\n ###\n @mask = null\n \n ###*\n * The UI object's alignment.\n * @property alignment\n * @type ui.Alignment\n ###\n @alignment = -1\n \n ###*\n * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.\n * @property opacity\n * @type number\n ###\n @opacity = -1\n \n ###*\n * The object's clip-rect for visual presentation.\n * @default null\n * @property clipRect\n * @type gs.Rect\n * @protected\n ###\n @clipRect = null\n \n ###*\n * The corner-size of the frame.\n * @property frameCornerSize\n * @type number\n ###\n @frameCornerSize = -1\n \n ###*\n * The thickness of the frame.\n * @property frameThickness\n * @type number\n ###\n @frameThickness = -1\n \n ###*\n * The looping of the image.\n * @property looping\n * @type ui.Orientation\n ###\n @looping = null\n \n ###*\n * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered\n * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it\n * should have the largest z-index of all game objects.\n * @property zIndex\n * @type number\n ###\n @zIndex = -1\n \n ###*\n * The object's alignment on x-axis. Needs to be supported by layout.\n * @property alignmentX\n * @type number\n ###\n @alignmentX = -1\n \n ###*\n * The object's alignment on y-axis. Needs to be supported by layout.\n * @property alignmentY\n * @type number\n ###\n @alignmentY = -1\n \n ###*\n * The object's resize behavior.\n * @property resizable\n * @type boolean\n ###\n @resizable = null\n \n ###*\n * The original style descriptor.\n * @property descriptor\n * @type Object\n ###\n @descriptor = descriptor\n \n if descriptor\n @setFromDescriptor(descriptor)\n\n ###*\n * Initializes the style from a style-descriptor.\n *\n * @method setFromDescriptor\n * @param {Object} descriptor - The style-descriptor.\n ### \n setFromDescriptor: (descriptor) ->\n @descriptor = descriptor\n @image = descriptor.image\n @color = gs.Color.fromArray(descriptor.color) if descriptor.color\n @anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]) if descriptor.anchor\n @zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]) if descriptor.zoom\n \n if descriptor.font\n @setupFont(descriptor)\n \n if descriptor.clipRect\n @clipRect = gs.Rect.fromArray(descriptor.clipRect)\n \n @opacity = descriptor.opacity if descriptor.opacity >= 0\n @alignment = descriptor.alignment if descriptor.alignment >= 0\n @margin = ui.Space.fromArray(descriptor.margin) if descriptor.margin\n @padding = ui.Space.fromArray(descriptor.padding) if descriptor.padding\n @animations = descriptor.animations\n @frameCornerSize = descriptor.frameCornerSize if descriptor.frameCornerSize\n @frameThickness = descriptor.frameThickness if descriptor.frameThickness\n @frame = descriptor.frame if descriptor.frame\n @looping = descriptor.looping if descriptor.looping\n @resizable = descriptor.resizable if descriptor.resizable?\n @zIndex = descriptor.zIndex if descriptor.zIndex\n @alignmentX = ui.UIManager.alignments[descriptor.alignmentX] if descriptor.alignmentX\n @alignmentY = ui.UIManager.alignments[descriptor.alignmentY] if descriptor.alignmentY\n \n set: (style) ->\n @image = style.image\n @color.setFromObject(style.color)\n @anchor.set(style.anchor.x, style.anchor.y)\n @zoom.set(style.zoom.x, style.zoom.y)\n \n if style.font\n if !@font then @font = new gs.Font(style.font.name, style.font.size)\n @font.set(style.font)\n \n if style.clipRect\n if !@clipRect then @clipRect = new gs.Rect()\n @clipRect.setFromObject(style.clipRect)\n \n @opacity = style.opacitz\n @alignment = style.alignment\n @margin.setFromObject(style.margin)\n @padding.setFromObject(style.padding)\n \n ###*\n * Initializes font-data from a style-descriptor.\n *\n * @method setupFont\n * @param {Object} descriptor - The style-descriptor.\n * @protected\n ### \n setupFont: (descriptor) ->\n if descriptor.font\n if !@font\n @font = new Font(descriptor.font.name, descriptor.font.size ? 0)\n else\n @font.name = descriptor.font.name\n @font.size = descriptor.font.size ? 0\n \n @font.bold = descriptor.font.bold ? @font.bold\n @font.italic = descriptor.font.italic ? @font.italic\n @font.smallCaps = descriptor.font.smallCaps ? @font.smallCaps\n @font.underline = descriptor.font.underline ? @font.underline\n @font.strikeThrough = descriptor.font.strikeThrough ? @font.strikeThrough\n \n if descriptor.font.color?\n @font.color.setFromArray(descriptor.font.color)\n \n if descriptor.font.border?\n @font.border = descriptor.font.border ? no\n @font.borderSize = descriptor.font.borderSize ? 4\n @font.borderColor.set(0, 0, 0, 255)\n \n if descriptor.font.outline?\n @font.border = descriptor.font.outline ? no\n @font.borderSize = descriptor.font.outline.size ? 4\n \n if descriptor.font.outline.color?\n @font.borderColor.setFromArray(descriptor.font.outline.color)\n else\n @font.borderColor.set(0, 0, 0, 255)\n \n ###*\n * Applies the style to a UI object.\n *\n * @method apply\n * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.\n ### \n apply: (object) ->\n if not object.activeStyles.contains(this)\n object.activeStyles.push(this)\n if @font then object.font?.set(@font)\n if @color then object.color.set(@color)\n if @image then object.image = @image\n if @anchor then object.anchor.set(@anchor.x, @anchor.y)\n if @zoom then object.zoom.set(@zoom.x, @zoom.y)\n if @padding then object.padding.setFromObject(@padding)\n if @margin then object.margin.setFromObject(@margin)\n if @opacity >= 0 then object.opacity = @opacity\n if @alignment >= 0 then object.alignment = @alignment\n if @frameThickness >= 0 then object.frameThickness = @frameThickness\n if @frameCornerSize >= 0 then object.frameCornerSize = @frameCornerSize\n if @mask then object.mask.set(@mask)\n if @zIndex >= 0 then object.zIndex = @zIndex\n if @alignmentX >= 0 then object.alignmentX = @alignmentX\n if @alignmentY >= 0 then object.alignmentY = @alignmentY\n if @resizable? then object.resizable = @resizable\n \n @applyLooping(object)\n @applyAnimations(object)\n \n ###*\n * Applies the looping-data of the style to a UI object.\n *\n * @method applyLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.\n * @protected\n ### \n applyLooping: (object) ->\n if @looping\n if !object.visual.looping\n object.visual.dispose()\n object.removeComponent(object.visual)\n object.visual = new gs.Component_TilingSprite()\n object.addComponent(object.visual)\n \n object.visual.looping.vertical = @looping.vertical\n object.visual.looping.horizontal = @looping.horizontal\n \n ###*\n * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler\n * component(ui.Component_AnimationHandler) with the id \"animationHandler\" to the UI object if not already exists.\n *\n * @method applyAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.\n * @protected\n ### \n applyAnimations: (object) ->\n if @animations\n object.animations = Object.deepCopy(@animations)\n if !object.findComponentById(\"animationHandler\")\n object.animationExecutor = new ui.Component_AnimationExecutor()\n object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\")\n object.addComponent(object.animationExecutor, \"animationExecutor\")\n \n \n ###*\n * Reverts the changes from a UI object made by this style. However, this resets all styleable properties\n * were set by this style. So it is necessary to apply all other styles again, but that is already handles in\n * ui.Component_UIBehavior.\n *\n * @method revert\n * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.\n ### \n revert: (object) ->\n activeStyles = object.activeStyles\n if object.activeStyles.contains(this)\n object.activeStyles.remove(this)\n \n if @font then object.font.set(gs.Fonts.TEXT); (if s.font then object.font.set(s.font); break) for s in activeStyles by -1\n if @color then object.color.set(Color.WHITE); (if s.color then object.color.set(s.color); break) for s in activeStyles by -1\n if @image then object.image = null; (if s.image then object.image = s.image; break) for s in activeStyles by -1\n if @anchor then object.anchor.set(0, 0); (if s.anchor then object.anchor.setFromObject(s.anchor); break) for s in activeStyles by -1\n if @zoom then object.zoom.set(1.0, 1.0); (if s.zoom then object.zoom.setFromObject(s.zoom); break) for s in activeStyles by -1\n if @padding then object.padding.set(0, 0, 0, 0); (if s.padding then object.padding.setFromObject(s.padding); break) for s in activeStyles by -1\n if @margin then object.margin.set(0, 0, 0, 0); (if s.margin then object.margin.setFromObject(s.margin); break) for s in activeStyles by -1\n if @opacity >= 0 then object.opacity = 255; (if s.opacity >= 0 then object.opacity = s.opacity; break) for s in activeStyles by -1\n if @alignment >= 0 then object.alignment = 0; (if s.alignment >= 0 then object.alignment = s.alignment; break) for s in activeStyles by -1\n if @frameCornerSize >= 0 then object.frameCornerSize = 16; (if s.frameCornerSize >= 0 then object.frameCornerSize = s.frameCornerSize; break) for s in activeStyles by -1\n if @frameThickness >= 0 then object.frameThickness = 16; (if s.frameThickness >= 0 then object.frameThickness = s.frameThickness; break) for s in activeStyles by -1\n if @mask then object.mask.set(null); (if s.mask then object.mask.set(s.font); break) for s in activeStyles by -1\n if @zIndex >= 0 then object.zIndex = 0; (if s.zIndex >= 0 then object.zIndex = s.zIndex; break) for s in activeStyles by -1\n if @alignmentX >= 0 then object.alignmentX = 0; (if s.alignmentX >= 0 then object.alignmentX = s.alignmentX; break) for s in activeStyles by -1\n if @alignmentY >= 0 then object.alignmentY = 0; (if s.alignmentY >= 0 then object.alignmentY = s.alignmentY; break) for s in activeStyles by -1\n if @resizable? then object.resizable = no; (if s.resizable? then object.resizable = s.resizable; break) for s in activeStyles by -1\n \n @revertAnimations(object)\n @revertLooping(object)\n \n ###*\n * Reverts the animation-data changes applied to a UI object by this style.\n *\n * @method revertAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.\n ### \n revertAnimations: (object) ->\n activeStyles = object.activeStyles\n if @animations\n object.animations = null; \n for s in activeStyles by -1\n if s.animations\n object.animations = Object.deepCopy(s.animations)\n if !object.findComponentById(\"animationHandler\")\n object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\")\n \n ###*\n * Reverts the looping-data changes applied to a UI object by this style.\n *\n * @method revertLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.\n ### \n revertLooping: (object) ->\n activeStyles = object.activeStyles\n if @looping\n object.visual.looping.vertical = no\n object.visual.looping.horizontal = no\n for s in activeStyles by -1\n if s.looping\n if !object.visual.looping\n object.visual.dispose()\n object.removeComponent(object.visual)\n object.visual = new gs.Component_TilingSprite()\n object.addComponent(object.visual)\n \n object.visual.looping.vertical = s.looping.vertical\n object.visual.looping.horizontal = s.looping.horizontal\n \nui.Style = Style\n\nclass UIManager\n ###*\n * Handles the creation of In Game UI elements. For more information about\n * In-Game UI see help file.\n *\n * @module ui\n * @class UIManager\n * @memberof ui\n * @constructor\n ###\n constructor: ->\n ###*\n * Stores all registered UI layouts by name/id.\n * @property layouts\n * @type Object\n ###\n @layouts = {}\n \n ###*\n * Stores all registered UI styles by name/id.\n * @property styles\n * @type Object\n ###\n @styles = {}\n \n ###*\n * Stores all UI styles by number id.\n * @property stylesById\n * @type ui.Style[]\n ###\n @stylesById = new Array()\n \n ###*\n * Stores all UI styles by style-name.\n * @property stylesByName\n * @type Object\n ###\n @stylesByName = {}\n \n ###*\n * Stores all registered custom UI types/templates by name/id.\n * @property customTypes\n * @type Object\n ###\n @customTypes = {}\n \n ###*\n * Stores all registered UI controllers by name/id.\n * @property customTypes\n * @type Object\n ###\n @controllers = {}\n \n ###*\n * Stores all registered UI data sources by name/id.\n * @property customTypes\n * @type Object\n ###\n @dataSources = {}\n \n ###*\n * Mapping to table to map alignment names to number values.\n * @property alignments\n * @type Object\n * @protected\n ###\n @alignments = { \"left\": 0, \"top\": 0, \"center\": 1, \"bottom\": 2, \"right\": 2, \"0\": 0, \"1\": 1, \"2\": 2 }\n \n ###*\n * Mapping to table to map blend-mode names to number values.\n * @property blendModes\n * @type Object\n * @protected\n ###\n @blendModes = { \"normal\": 0, \"add\": 1, \"sub\": 2 }\n \n ###*\n * Mapping to table to map selector names to number values.\n * @property selectors\n * @type Object\n ###\n @selectors = { normal: 0, hover: 1, selected: 2, enabled: 3, focused: 4 }\n @defaultPlaceholderParams = {}\n \n ###*\n * Sets up UI Manager, optimizes styles, etc.\n *\n * @method setup\n ###\n setup: ->\n @setupStyles()\n \n ###*\n * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.\n *\n * @method setupStyles\n * @protected\n ###\n setupStyles: ->\n id = 0\n selectorMap = @selectors\n for k of @styles\n subs = k.split(\" \")\n selector = subs[0].split(\":\")\n \n if selectorMap[selector[1]]\n @stylesById[id] = new ui.Style(@styles[k], id, selectorMap[selector[1]])\n else\n @stylesById[id] = new ui.Style(@styles[k], id, 0)\n \n if !@stylesByName[selector[0]]\n @stylesByName[selector[0]] = []\n \n @stylesByName[selector[0]].push(@stylesById[id])\n @styles[k] = @stylesById[id]\n \n id++\n \n for k of @styles\n subs = k.split(\" \")\n if subs.length > 1\n @stylesByName[subs[1]].push(@styles[k])\n @styles[k].target = @styles[k.split(\":\")[0]]?.id\n #@styles[subs[1]].target = @styles[k].id\n #@styles[k].target = @styles[subs[1]].id\n \n return null\n \n ###*\n * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed\n * and placeholder formulas are replaced with their evaluated result value.\n *\n * @method executePlaceholderFormulas\n * @param {Object} descriptor - The descriptor.\n * @param {Object} params - Object containing the placeholder params.\n * @protected\n ### \n executePlaceholderFormulas: (descriptor, id, params) ->\n return if not descriptor?\n keys = Object.keys(descriptor)\n \n for k in keys\n v = descriptor[k]\n if v?\n if v instanceof Array\n for i, c in v\n if i?\n if typeof i == \"object\"\n @executePlaceholderFormulas(i, id, params)\n else if c != \"exec\" and typeof i == \"function\"\n window.p = params || @defaultPlaceholderParams\n window.d = descriptor\n v[c] = i()\n else if typeof v == \"object\"\n @executePlaceholderFormulas(v, id, params)\n else if k != \"exec_\" and typeof v == \"function\"\n window.p = params || @defaultPlaceholderParams\n window.d = descriptor\n descriptor[k] = v()\n return null\n\n ###*\n * Creates a calculation for a specified expression.\n *\n * @method createCalcFunction\n * @param {String} expression - The expression to create a calculation function for.\n * @return {Function} The calculation function.\n * @protected\n ### \n createCalcFunction: (expression) ->\n expression = expression.replace(/([0-9]+)%/gm, \"($1 / 100 * v)\")\n return eval(\"(function(v){ return \" + expression + \"})\")\n \n ###*\n * Creates an object from the specified object type. The type has the format\n * <namespace>.<typename> like vn.Component_Hotspot.\n *\n * @method createObject\n * @param {String} type - The type name.\n * @return {Object} The created object.\n * @protected\n ### \n createObject: (type) ->\n subs = type.split(\".\")\n return new window[subs[0]][subs[1]]()\n \n ###*\n * Creates an UI object from a specified UI descriptor.\n *\n * @method createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n ### \n createFromDescriptor: (descriptor, parent) ->\n control = null\n \n for k of @controllers\n if @controllers[k].type?\n @controllers[k] = @createObject(@controllers[k].type)\n \n @_createFromDescriptor(descriptor, parent)\n \n \n ###*\n * Creates an image button UI object.\n *\n * @method createImageButton\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createImageButton: (descriptor) ->\n control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling) \n \n control.behavior.sound = descriptor.sound\n control.behavior.sounds = descriptor.sounds\n control.image = descriptor.image\n control.images = descriptor.images\n if descriptor.imageFolder?\n control.imageFolder = descriptor.imageFolder\n \n if descriptor.looping?\n control.visual.dispose()\n control.removeComponent(control.visual)\n control.visual = new gs.Component_TilingSprite()\n control.addComponent(control.visual)\n \n control.visual.looping.vertical = descriptor.looping.vertical\n control.visual.looping.horizontal = descriptor.looping.horizontal\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates an image UI object.\n *\n * @method createImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createImage: (descriptor) ->\n control = new ui.Object_Image(descriptor.image, descriptor.imageHandling) \n \n if descriptor.imageFolder?\n control.imageFolder = descriptor.imageFolder\n \n if descriptor.looping?\n control.visual.dispose()\n control.removeComponent(control.visual)\n control.visual = new gs.Component_TilingSprite()\n control.addComponent(control.visual)\n \n control.visual.looping.vertical = descriptor.looping.vertical\n control.visual.looping.horizontal = descriptor.looping.horizontal\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates an image map UI object.\n *\n * @method createImageMap\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createImageMap: (descriptor) ->\n control = new ui.Object_ImageMap()\n control.hotspots = (descriptor.hotspots||[]).select (h) -> \n { x: h.rect[0], y: h.rect[1], size: { width: h.rect[2], height: h.rect[3] }, data: { action: 3, actions: h.actions } }\n control.images = descriptor.images\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\")\n control.target = SceneManager.scene.behavior\n \n return control\n \n ###*\n * Creates a video UI object.\n *\n * @method createVideo\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createVideo: (descriptor) ->\n control = new ui.Object_Video()\n control.video = descriptor.video\n control.loop = descriptor.loop ? yes\n \n return control\n \n \n ###*\n * Creates a panel UI object.\n *\n * @method createPanel\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createPanel: (descriptor) ->\n control = new ui.Object_Panel()\n control.modal = descriptor.modal ? no\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates a frame UI object.\n *\n * @method createFrame\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createFrame: (descriptor) ->\n control = new ui.Object_Frame(descriptor.frameSkin)\n control.frameThickness = descriptor.frameThickness || 16\n control.frameCornerSize = descriptor.frameCornerSize || 16\n control.image = descriptor.image\n control.images = descriptor.images\n \n return control\n \n ###*\n * Creates a three-part image UI object.\n *\n * @method createThreePartImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createThreePartImage: (descriptor) ->\n control = new ui.Object_ThreePartImage(descriptor.frameSkin)\n control.firstPartSize = descriptor.firstPartSize || 16\n control.middlePartSize = descriptor.middlePartSize || 1\n control.lastPartSize = descriptor.lastPartSize || 16\n control.image = descriptor.image\n control.images = descriptor.images\n \n return control\n \n ###*\n * Creates a text UI object.\n *\n * @method createText\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createText: (descriptor) ->\n control = new ui.Object_Text()\n control.text = lcs(descriptor.text)\n control.sizeToFit = descriptor.sizeToFit\n control.formatting = descriptor.formatting\n control.wordWrap = descriptor.wordWrap ? no\n control.behavior.format = descriptor.format\n if descriptor.textPadding\n control.behavior.padding = ui.Space.fromArray(descriptor.textPadding)\n if descriptor.resolvePlaceholders?\n control.resolvePlaceholders = descriptor.resolvePlaceholders\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates a free-layout UI object.\n *\n * @method createFreeLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createFreeLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1)\n else\n control = new ui.Object_FreeLayout(0, 0, 1, 1)\n control.sizeToFit = descriptor.sizeToFit\n \n return control\n \n ###*\n * Creates a stack-layout UI object.\n *\n * @method createStackLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createStackLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)\n else\n control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation)\n control.sizeToFit = descriptor.sizeToFit\n \n return control\n \n ###*\n * Creates a spread-layout UI object.\n *\n * @method createSpreadLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createSpreadLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)\n else\n control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation)\n \n return control\n \n ###*\n * Creates a grid-layout UI object.\n *\n * @method createGridLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createGridLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template)\n else\n control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template)\n control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0]\n control.sizeToFit = descriptor.sizeToFit\n \n return control\n \n ###*\n * Creates a message UI object.\n *\n * @method createMessage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createMessage: (descriptor) ->\n control = new ui.Object_Message() \n \n return control\n \n ###*\n * Creates a data-grid UI object.\n *\n * @method createDataGrid\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createDataGrid: (descriptor) ->\n control = new ui.Object_DataGrid(descriptor)\n \n return control\n \n ###*\n * Creates an UI object depending on the object-type of the specified UI descriptor.\n *\n * @method createControl\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n ### \n createControl: (descriptor) ->\n control = null\n \n switch descriptor.type\n when \"ui.ImageButton\"\n control = @createImageButton(descriptor)\n when \"ui.Image\"\n control = @createImage(descriptor)\n when \"ui.ImageMap\"\n control = @createImageMap(descriptor)\n when \"ui.Video\"\n control = @createVideo(descriptor)\n when \"ui.Panel\"\n control = @createPanel(descriptor)\n when \"ui.Frame\"\n control = @createFrame(descriptor)\n when \"ui.ThreePartImage\"\n control = @createThreePartImage(descriptor)\n when \"ui.Text\"\n control = @createText(descriptor)\n when \"ui.Message\"\n control = @createMessage(descriptor)\n when \"ui.DataGrid\"\n control = @createDataGrid(descriptor)\n when \"ui.FreeLayout\"\n control = @createFreeLayout(descriptor)\n when \"ui.StackLayout\"\n control = @createStackLayout(descriptor)\n when \"ui.SpreadLayout\"\n control = @createSpreadLayout(descriptor)\n when \"ui.GridLayout\"\n control = @createGridLayout(descriptor)\n \n return control\n \n \n createLayoutRect: (frame, control) ->\n if !control.layoutRect\n control.layoutRect = new ui.LayoutRect()\n control.layoutRect.set(0, 0, 0, 0)\n \n if frame?\n if frame[0]?.length?\n control.layoutRect.x = @createCalcFunction(frame[0])\n control.dstRect.x = 0\n else\n control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)\n \n if frame[1]?.length?\n control.layoutRect.y = @createCalcFunction(frame[1])\n control.dstRect.y = 0\n else\n control.dstRect.y = (frame[1] ? control.dstRect.y)\n \n if frame[2]?.length?\n control.layoutRect.width = @createCalcFunction(frame[2])\n control.dstRect.width = 1\n else\n control.dstRect.width = (frame[2] ? control.dstRect.width)\n \n if frame[3]?.length?\n control.layoutRect.height = @createCalcFunction(frame[3])\n control.dstRect.height = 1\n else\n control.dstRect.height = (frame[3] ? control.dstRect.height)\n \n \n ###*\n * Adds the styles defined in an array of style-names to the specified control.\n *\n * @method addControlStyles\n * @param {Object} control - The control to add the styles to.\n * @param {string[]} styles - Array of style-names to add.\n ### \n addControlStyles: (control, styles) ->\n for styleName in styles\n if @stylesByName[styleName]?\n for style in @stylesByName[styleName]\n control.styles.push(style)\n if style.target == -1 and style.selector == 0\n style.apply(control)\n ###*\n * Creates an UI object from a specified UI descriptor. This method is called\n * recursively for all child-descriptors.\n *\n * @method createControlFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @param {number} index - The index.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n ### \n createControlFromDescriptor: (descriptor, parent, index) ->\n control = null\n \n if descriptor.style?\n descriptor.styles = [descriptor.style]\n delete descriptor.style\n \n descriptor = Object.deepCopy(descriptor)\n @executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params)\n \n control = @createControl(descriptor)\n \n if not control?\n type = Object.deepCopy(@customTypes[descriptor.type])\n \n @executePlaceholderFormulas(type, descriptor.id, descriptor.params)\n \n typeName = type.type\n customFields = type.customFields\n bindings = type.bindings\n formulas = type.formulas\n actions = type.actions\n if type.style?\n type.styles = [type.style]\n type.style = null\n \n Object.mixin(type, descriptor)\n if customFields? then Object.mixin(type.customFields, customFields)\n if bindings? and bindings != type.bindings then type.bindings = type.bindings.concat(bindings)\n if formulas? and formulas != type.formulas then type.formulas = type.formulas.concat(formulas)\n if actions? and actions != type.actions then type.actions = actions.concat(type.actions)\n type.type = typeName\n \n return @createControlFromDescriptor(type, parent)\n else if parent?\n parent.addObject(control)\n control.index = index\n else\n gs.ObjectManager.current.addObject(control)\n \n control.ui = new ui.Component_UIBehavior()\n control.addComponent(control.ui)\n \n \n \n control.params = descriptor.params\n \n if descriptor.updateBehavior == \"continuous\"\n control.updateBehavior = ui.UpdateBehavior.CONTINUOUS\n \n if descriptor.inheritProperties\n control.inheritProperties = yes\n \n if descriptor.font?\n control.font = new Font(descriptor.font.name, descriptor.font.size)\n control.font.bold = descriptor.font.bold ? control.font.bold\n control.font.italic = descriptor.font.italic ? control.font.italic\n control.font.smallCaps = descriptor.font.smallCaps ? control.font.smallCaps\n control.font.underline = descriptor.font.underline ? control.font.underline\n control.font.strikeThrough = descriptor.font.strikeThrough ? control.font.strikeThrough\n \n if descriptor.font.color?\n control.font.color = Color.fromArray(descriptor.font.color)\n if descriptor.font.border?\n control.font.border = descriptor.font.border ? no\n control.font.borderSize = descriptor.font.borderSize ? 4\n #if descriptor.font.border.color\n # control.font.borderColor = Color.fromArray(descriptor.font.border.color)\n control.font.borderColor = new Color(0, 0, 0)\n \n if descriptor.font.outline?\n control.font.border = descriptor.font.outline ? no\n control.font.borderSize = descriptor.font.outline.size ? 4\n \n if descriptor.font.outline.color?\n control.font.borderColor = Color.fromArray(descriptor.font.outline.color)\n else\n control.font.borderColor = new Color(0, 0, 0)\n \n if descriptor.components?\n for c in descriptor.components\n m = c.module || \"gs\"\n component = new window[m][c.type](c.params)\n control.addComponent(component, c.id)\n control[c.id] = component\n #component.setup?()\n \n control.focusable = descriptor.focusable ? control.focusable \n if descriptor.nextKeyObject\n control.ui.nextKeyObjectId = descriptor.nextKeyObject\n \n if descriptor.initialFocus\n control.ui.focus()\n \n actions = Object.deepCopy(if descriptor.action? then [descriptor.action] else descriptor.actions) \n if actions?\n for action in actions\n if action?\n action.event = action.event ? \"onAccept\"\n if not action.target?\n target = if @controllers? then @controllers[descriptor.target] else controller\n action.target = target || SceneManager.scene.behavior\n \n control.actions = actions\n \n if(!control.findComponentById(\"actionHandler\"))\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\")\n \n if descriptor.id?\n control.id = descriptor.id\n gs.ObjectManager.current.setObjectById(control, control.id)\n \n control.descriptor = descriptor\n control.layoutRect = new Rect()\n control.layoutRect.set(0, 0, 0, 0)\n if descriptor.frame?\n if descriptor.frame[0]?.length?\n control.layoutRect.x = @createCalcFunction(descriptor.frame[0])\n control.dstRect.x = 0\n else\n control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)\n \n if descriptor.frame[1]?.length?\n control.layoutRect.y = @createCalcFunction(descriptor.frame[1])\n control.dstRect.y = 0\n else\n control.dstRect.y = (descriptor.frame[1] ? control.dstRect.y)\n \n if descriptor.frame[2]?.length?\n control.layoutRect.width = @createCalcFunction(descriptor.frame[2])\n control.dstRect.width = 1\n else\n control.dstRect.width = (descriptor.frame[2] ? control.dstRect.width)\n \n if descriptor.frame[3]?.length?\n control.layoutRect.height = @createCalcFunction(descriptor.frame[3]) #parseInt(descriptor.frame[3].split(\"%\")[0])\n control.dstRect.height = 1\n else\n control.dstRect.height = (descriptor.frame[3] ? control.dstRect.height)\n \n if descriptor.sizeToParent?\n control.sizeToParent = descriptor.sizeToParent\n \n if descriptor.blendMode?\n control.blendMode = @blendModes[descriptor.blendMode]\n \n if descriptor.anchor?\n control.anchor.set(descriptor.anchor[0], descriptor.anchor[1])\n \n\n control.opacity = descriptor.opacity ? 255 \n if descriptor.minimumSize?\n control.minimumSize = { width: descriptor.minimumSize[0], height: descriptor.minimumSize[1] }\n \n if descriptor.resizable? then control.resizable = descriptor.resizable\n if descriptor.scrollable? then control.scrollable = descriptor.scrollable \n if descriptor.fixedSize? then control.fixedSize = descriptor.fixedSize\n if descriptor.draggable?\n control.draggable = descriptor.draggable\n control.draggable.step = 0\n if control.draggable.rect?\n control.draggable.rect = Rect.fromArray(control.draggable.rect)\n control.addComponent(new ui.Component_Draggable())\n \n if descriptor.bindings?\n control.bindings = descriptor.bindings\n control.insertComponent(new ui.Component_BindingHandler(), 0)\n \n if descriptor.formulas?\n control.formulas = descriptor.formulas\n control.insertComponent(new ui.Component_FormulaHandler(), 0)\n \n control.dataField = descriptor.dataField\n control.enabled = descriptor.enabled ? yes\n if descriptor.selectable? then control.selectable = descriptor.selectable\n if descriptor.group? \n control.group = descriptor.group\n gs.ObjectManager.current.addToGroup(control, control.group)\n \n if descriptor.customFields?\n control.customFields = Object.deepCopy(descriptor.customFields)\n \n if descriptor.margin?\n control.margin.left = descriptor.margin[0]\n control.margin.top = descriptor.margin[1]\n control.margin.right = descriptor.margin[2]\n control.margin.bottom = descriptor.margin[3]\n \n if descriptor.padding?\n control.padding.left = descriptor.padding[0]\n control.padding.top = descriptor.padding[1]\n control.padding.right = descriptor.padding[2]\n control.padding.bottom = descriptor.padding[3]\n \n if descriptor.alignment?\n control.alignment = @alignments[descriptor.alignment]\n \n control.alignmentY = @alignments[descriptor.alignmentY || 0]\n control.alignmentX = @alignments[descriptor.alignmentX || 0]\n control.zIndex = descriptor.zIndex || 0\n control.order = descriptor.order || 0\n control.chainOrder = (descriptor.chainOrder ? descriptor.zOrder) + (parent?.chainOrder || 0)\n if descriptor.zoom?\n control.zoom = x: descriptor.zoom[0] / 100, y: descriptor.zoom[1] / 100\n #control.dataFields = dataFields\n #control.controllers = @controllers\n #control.controller = controller\n \n if descriptor.visible?\n control.visible = descriptor.visible\n if descriptor.clipRect\n control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height)\n\n if descriptor.styles?\n @addControlStyles(control, descriptor.styles)\n \n \n if descriptor.template?\n control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode)\n data = ui.Component_FormulaHandler.fieldValue(control, control.dataField) #control.dataFields[control.dataField]\n isNumber = typeof data == \"number\"\n if data?\n for i in [0...(data.length ? data)]\n if data[i]? or isNumber\n valid = yes\n if descriptor.dataFilter? and not isNumber\n valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter)\n if valid or isNumber\n child = @createControlFromDescriptor(descriptor.template, control, i)\n #child.dataFields = control.dataFields\n \n if data[i]?.dstRect\n child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect)\n if (not child.clipRect?) and control.clipRect?\n child.clipRect = control.clipRect\n #child.parent = control\n control.addObject(child)\n child.index = i\n child.order = (data.length ? data) - i\n control.controls.push(child)\n \n \n if descriptor.controls and descriptor.controls.exec\n controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls)\n else\n controls = descriptor.controls\n \n if controls?\n for item, i in controls\n childControl = @_createFromDescriptor(item, control, i)\n if (not childControl.clipRect?) and control.clipRect?\n childControl.clipRect = control.clipRect\n childControl.index = i\n childControl.origin.x = control.origin.x + control.dstRect.x\n childControl.origin.y = control.origin.y + control.dstRect.y\n #childControl.parent = control\n control.addObject(childControl)\n control.controls.push(childControl)\n \n if control.styles and control.parentsByStyle\n #for style in control.styles\n \n parent = control.parent\n while parent\n if parent.styles\n for style in parent.styles\n if !control.parentsByStyle[style.id]\n control.parentsByStyle[style.id] = []\n control.parentsByStyle[style.id].push(parent)\n \n #while parent\n #if parent.controlsByStyle\n # if(!parent.controlsByStyle[style.id])\n # parent.controlsByStyle[style.id] = []\n # parent.controlsByStyle[style.id].push(control)\n # if control.parentsByStyle\n # if !control.parentsByStyle[style.id]\n # control.parentsByStyle[style.id] = []\n # control.parentsByStyle[style.id].push(parent)\n parent = parent.parent\n \n if descriptor.animations?\n control.animations = Object.deepCopy(descriptor.animations)\n control.animationExecutor = new ui.Component_AnimationExecutor()\n control.addComponent(control.animationExecutor)\n control.addComponent(new ui.Component_AnimationHandler())\n \n control.ui.updateStyle()\n control.setup()\n \n return control\n \n ###*\n * Creates an UI object from a specified UI descriptor.\n *\n * @method _createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n * @protected \n ### \n _createFromDescriptor: (descriptor, parent, index) -> \n control = @createControlFromDescriptor(descriptor, parent, index)\n \n if descriptor.controller?\n controller = @controllers[descriptor.controller]\n control.controller = controller\n control.addComponent(controller)\n \n return control\n \n createLayoutFromDescriptor: (descriptor, parent, index) ->\n @_createFromDescriptor(descriptor, parent, index)\n \n \n \nGraphics.width = $PARAMS.resolution.width\nGraphics.height = $PARAMS.resolution.height\nui.UiFactory = new UIManager()\nui.UIManager = ui.UiFactory",
9 + "content": "# ===================================================================\n#\n# Script: UIManager\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\n\nclass Formula\n ###*\n * Encapsulates a UI formula. A formula can be used in UI layouts to define\n * property-bindings or to implement a specific behavior.\n *\n * @module ui\n * @class Formula\n * @memberof ui\n * @constructor\n * @param {Function} f - The formula-function. Defines the logic of the formula.\n * @param {Object} data - An optional data-object which can be accessed inside the formula-function.\n * @param {string} event - An optional event-name to define when the formula should be executed.\n ###\n constructor: (f, data, event) ->\n ###*\n * Indicates if its the first time the formula is called.\n * @property onInitialize\n * @type boolean\n ###\n @onInitialize = yes\n \n ###*\n * The formula-function.\n * @property exec_\n * @type Function\n ###\n @exec_ = f\n \n ###*\n * An optional data-object which can bes accessed inside the formula-function.\n * @property data\n * @type Object\n ### \n @data = data\n \n ###*\n * An optional event-name to define when the formula should be executed.\n * @property event\n * @type string\n ### \n @event = event\n \n ###*\n * An array of custom number-data which can be used for different purposes. The first element\n * is also used in onChange method to store the old value and check against the new one to detect a change.\n * @property numbers\n * @type number[]\n ### \n @numbers = new Array(10)\n @numbers[i] = 0 for i in [0..@numbers.length]\n \n ###*\n * An array of custom string-data which can be used for different purposes. The first element\n * is also used in onTextChange method to store the old value and check against the new one to detect a change.\n * @property strings\n * @type string[]\n ###\n @strings = new Array(10)\n @strings[i] = \"\" for i in [0..@strings.length]\n \n \n ###*\n * The formula-function. Its a wrapper-function before the first-time call was made.\n * @method exec\n ###\n exec: ->\n @exec = @exec_\n r = @exec_.apply(this, arguments)\n @onInitialize = no\n \n return r\n \n ###*\n * Checks if the specified number-value has changed since the last check. It uses\n * the first entry of the numbers-array to store the value and check against the new one.\n *\n * @method onChange\n * @param {number} numberValue - Number value to check.\n ### \n onChange: (numberValue) ->\n result = @numbers[0] != numberValue\n @numbers[0] = numberValue\n \n return result\n \n ###*\n * Checks if the specified text-value has changed since the last check. It uses\n * the first entry of the strings-array to store the value and check against the new one.\n *\n * @method onTextChange\n * @param {string} textValue - Text value to check.\n ### \n onTextChange: (textValue) ->\n result = @strings[0] != textValue\n @strings[0] = textValue\n \n return result\n \nui.Formula = Formula\n\nclass Space\n ###*\n * Describes a space inside or around something like a margin or padding.\n *\n * @module ui\n * @class Space\n * @memberof ui\n * @constructor\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n ###\n constructor: (left, top, right, bottom) ->\n ###*\n * Space at the left in pixels.\n * @property left\n * @type number\n ###\n @left = left\n \n ###*\n * Space at the top in pixels.\n * @property top\n * @type number\n ###\n @top = top\n \n ###*\n * Space at the right in pixels.\n * @property right\n * @type number\n ###\n @right = right\n \n ###*\n * Space at the bottom in pixels.\n * @property bottom\n * @type number\n ###\n @bottom = bottom\n \n ###*\n * Sets the coordinates of the space by copying them from a specified space.\n *\n * @method setFromObject\n * @param {Object} space - A space to copy.\n ### \n setFromObject: (space) ->\n @left = space.left\n @top = space.top\n @right = space.right\n @bottom = space.bottom\n \n ###*\n * Sets the coordinates of the space.\n *\n * @method set\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n ### \n set: (left, top, right, bottom) ->\n @left = left\n @top = top\n @right = right\n @bottom = bottom\n \n ###*\n * Creates a new space object from an array of coordinates.\n *\n * @method fromArray\n * @static\n * @param {number[]} array - An array of coordinates (left, top right, bottom).\n ### \n @fromArray: (array) -> new ui.Space(array[0], array[1], array[2], array[3])\n \nui.Space = Space\n\nclass Style\n ###*\n * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain \"style\" to it.\n *\n * @module ui\n * @class Style\n * @memberof ui\n * @constructor\n * @param {Object} descriptor - A style-descriptor to initialize the style from.\n * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.\n * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.\n ###\n constructor: (descriptor, id, selector) ->\n ###*\n * ID number to quickly access this style and link to this style.\n * @property id\n * @type number\n ###\n @id = id\n \n ###*\n * Style-ID of target object. This style will only be applied on UI objects with that style ID which are\n * children of UI objects where this style is applied.\n * @property target\n * @type number\n ###\n @target = -1\n \n ###*\n * Selector-ID which controls under which conditions the style becomes active.\n * @property selector\n * @type number\n ###\n @selector = selector\n \n ###*\n * The font used for the text-display.\n * @default null\n * @property font\n * @type gs.Font\n ###\n @font = null\n \n ###*\n * The UI object's image used for visual presentation.\n * @property image\n * @type string\n ###\n @image = null\n \n ###*\n * The UI object's animations used for visual presentation.\n * @default null\n * @property animations\n * @type Object[]\n ###\n @animations = null\n \n ###*\n * The UI object's color.\n * @property color\n * @type gs.Color\n ###\n @color = null\n \n ###*\n * The UI object's tone.\n * @property tone\n * @type gs.Tone\n ###\n @tone = null\n \n ###*\n * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner\n * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1\n * places the object with its lower-right corner.\n * @property anchor\n * @type gs.Point\n ###\n @anchor = null\n \n ###*\n * The UI object's zoom-setting for x and y axis.\n * @default new gs.Point(1.0, 1.0)\n * @property zoom\n * @type gs.Point\n ###\n @zoom = null\n \n ###*\n * The UI object's margin. The margin defines an extra space around the UI object. \n * The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property margin\n * @type Object\n ###\n @margin = null\n \n ###*\n * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property padding\n * @type Object\n ###\n @padding = null\n \n ###*\n * The UI object's mask for masking-effects.\n * @property mask\n * @type gs.Mask\n ###\n @mask = null\n \n ###*\n * The UI object's alignment.\n * @property alignment\n * @type ui.Alignment\n ###\n @alignment = -1\n \n ###*\n * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.\n * @property opacity\n * @type number\n ###\n @opacity = -1\n \n ###*\n * The object's clip-rect for visual presentation.\n * @default null\n * @property clipRect\n * @type gs.Rect\n * @protected\n ###\n @clipRect = null\n \n ###*\n * The corner-size of the frame.\n * @property frameCornerSize\n * @type number\n ###\n @frameCornerSize = -1\n \n ###*\n * The thickness of the frame.\n * @property frameThickness\n * @type number\n ###\n @frameThickness = -1\n \n ###*\n * The looping of the image.\n * @property looping\n * @type ui.Orientation\n ###\n @looping = null\n \n ###*\n * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered\n * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it\n * should have the largest z-index of all game objects.\n * @property zIndex\n * @type number\n ###\n @zIndex = -1\n \n ###*\n * The object's alignment on x-axis. Needs to be supported by layout.\n * @property alignmentX\n * @type number\n ###\n @alignmentX = -1\n \n ###*\n * The object's alignment on y-axis. Needs to be supported by layout.\n * @property alignmentY\n * @type number\n ###\n @alignmentY = -1\n \n ###*\n * The object's resize behavior.\n * @property resizable\n * @type boolean\n ###\n @resizable = null\n \n ###*\n * The original style descriptor.\n * @property descriptor\n * @type Object\n ###\n @descriptor = descriptor\n \n if descriptor\n @setFromDescriptor(descriptor)\n\n ###*\n * Initializes the style from a style-descriptor.\n *\n * @method setFromDescriptor\n * @param {Object} descriptor - The style-descriptor.\n ### \n setFromDescriptor: (descriptor) ->\n @descriptor = descriptor\n @image = descriptor.image\n @color = gs.Color.fromArray(descriptor.color) if descriptor.color\n @tone = gs.Tone.fromArray(descriptor.tone) if descriptor.tone\n @anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]) if descriptor.anchor\n @zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]) if descriptor.zoom\n \n if descriptor.font\n @setupFont(descriptor)\n \n if descriptor.clipRect\n @clipRect = gs.Rect.fromArray(descriptor.clipRect)\n \n @opacity = descriptor.opacity if descriptor.opacity >= 0\n @alignment = descriptor.alignment if descriptor.alignment >= 0\n @margin = ui.Space.fromArray(descriptor.margin) if descriptor.margin\n @padding = ui.Space.fromArray(descriptor.padding) if descriptor.padding\n @animations = descriptor.animations\n @frameCornerSize = descriptor.frameCornerSize if descriptor.frameCornerSize\n @frameThickness = descriptor.frameThickness if descriptor.frameThickness\n @frame = descriptor.frame if descriptor.frame\n @looping = descriptor.looping if descriptor.looping\n @resizable = descriptor.resizable if descriptor.resizable?\n @zIndex = descriptor.zIndex if descriptor.zIndex\n @alignmentX = ui.UIManager.alignments[descriptor.alignmentX] if descriptor.alignmentX\n @alignmentY = ui.UIManager.alignments[descriptor.alignmentY] if descriptor.alignmentY\n \n set: (style) ->\n @image = style.image\n @color.setFromObject(style.color)\n @tone.setFromObject(style.tone)\n @anchor.set(style.anchor.x, style.anchor.y)\n @zoom.set(style.zoom.x, style.zoom.y)\n \n if style.font\n if !@font then @font = new gs.Font(style.font.name, style.font.size)\n @font.set(style.font)\n \n if style.clipRect\n if !@clipRect then @clipRect = new gs.Rect()\n @clipRect.setFromObject(style.clipRect)\n \n @opacity = style.opacitz\n @alignment = style.alignment\n @margin.setFromObject(style.margin)\n @padding.setFromObject(style.padding)\n \n ###*\n * Initializes font-data from a style-descriptor.\n *\n * @method setupFont\n * @param {Object} descriptor - The style-descriptor.\n * @protected\n ### \n setupFont: (descriptor) ->\n if descriptor.font\n if !@font\n @font = new Font(descriptor.font.name, descriptor.font.size ? 0)\n else\n @font.name = descriptor.font.name\n @font.size = descriptor.font.size ? 0\n \n @font.bold = descriptor.font.bold ? @font.bold\n @font.italic = descriptor.font.italic ? @font.italic\n @font.smallCaps = descriptor.font.smallCaps ? @font.smallCaps\n @font.underline = descriptor.font.underline ? @font.underline\n @font.strikeThrough = descriptor.font.strikeThrough ? @font.strikeThrough\n \n if descriptor.font.color?\n @font.color.setFromArray(descriptor.font.color)\n \n if descriptor.font.border?\n @font.border = descriptor.font.border ? no\n @font.borderSize = descriptor.font.borderSize ? 4\n @font.borderColor.set(0, 0, 0, 255)\n \n if descriptor.font.outline?\n @font.border = descriptor.font.outline ? no\n @font.borderSize = descriptor.font.outline.size ? 4\n \n if descriptor.font.outline.color?\n @font.borderColor.setFromArray(descriptor.font.outline.color)\n else\n @font.borderColor.set(0, 0, 0, 255)\n \n ###*\n * Applies the style to a UI object.\n *\n * @method apply\n * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.\n ### \n apply: (object) ->\n if not object.activeStyles.contains(this)\n object.activeStyles.push(this)\n if @font then object.font?.set(@font)\n if @color then object.color.set(@color)\n if @tone then object.tone?.set(@tone)\n if @image then object.image = @image\n if @anchor then object.anchor.set(@anchor.x, @anchor.y)\n if @zoom then object.zoom.set(@zoom.x, @zoom.y)\n if @padding then object.padding.setFromObject(@padding)\n if @margin then object.margin.setFromObject(@margin)\n if @opacity >= 0 then object.opacity = @opacity\n if @alignment >= 0 then object.alignment = @alignment\n if @frameThickness >= 0 then object.frameThickness = @frameThickness\n if @frameCornerSize >= 0 then object.frameCornerSize = @frameCornerSize\n if @mask then object.mask.set(@mask)\n if @zIndex >= 0 then object.zIndex = @zIndex\n if @alignmentX >= 0 then object.alignmentX = @alignmentX\n if @alignmentY >= 0 then object.alignmentY = @alignmentY\n if @resizable? then object.resizable = @resizable\n \n @applyLooping(object)\n @applyAnimations(object)\n \n ###*\n * Applies the looping-data of the style to a UI object.\n *\n * @method applyLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.\n * @protected\n ### \n applyLooping: (object) ->\n if @looping\n if !object.visual.looping\n object.visual.dispose()\n object.removeComponent(object.visual)\n object.visual = new gs.Component_TilingSprite()\n object.addComponent(object.visual)\n \n object.visual.looping.vertical = @looping.vertical\n object.visual.looping.horizontal = @looping.horizontal\n \n ###*\n * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler\n * component(ui.Component_AnimationHandler) with the id \"animationHandler\" to the UI object if not already exists.\n *\n * @method applyAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.\n * @protected\n ### \n applyAnimations: (object) ->\n if @animations\n object.animations = Object.deepCopy(@animations)\n if !object.findComponentById(\"animationHandler\")\n object.animationExecutor = new ui.Component_AnimationExecutor()\n object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\")\n object.addComponent(object.animationExecutor, \"animationExecutor\")\n \n \n ###*\n * Reverts the changes from a UI object made by this style. However, this resets all styleable properties\n * were set by this style. So it is necessary to apply all other styles again, but that is already handles in\n * ui.Component_UIBehavior.\n *\n * @method revert\n * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.\n ### \n revert: (object) ->\n activeStyles = object.activeStyles\n if object.activeStyles.contains(this)\n object.activeStyles.remove(this)\n \n if @font then object.font.set(gs.Fonts.TEXT); (if s.font then object.font.set(s.font); break) for s in activeStyles by -1\n if @color then object.color.set(Color.WHITE); (if s.color then object.color.set(s.color); break) for s in activeStyles by -1\n if @tone then object.tone?.set(0, 0, 0, 0); (if s.tone then object.tone?.set(s.tone); break) for s in activeStyles by -1\n if @image then object.image = null; (if s.image then object.image = s.image; break) for s in activeStyles by -1\n if @anchor then object.anchor.set(0, 0); (if s.anchor then object.anchor.setFromObject(s.anchor); break) for s in activeStyles by -1\n if @zoom then object.zoom.set(1.0, 1.0); (if s.zoom then object.zoom.setFromObject(s.zoom); break) for s in activeStyles by -1\n if @padding then object.padding.set(0, 0, 0, 0); (if s.padding then object.padding.setFromObject(s.padding); break) for s in activeStyles by -1\n if @margin then object.margin.set(0, 0, 0, 0); (if s.margin then object.margin.setFromObject(s.margin); break) for s in activeStyles by -1\n if @opacity >= 0 then object.opacity = 255; (if s.opacity >= 0 then object.opacity = s.opacity; break) for s in activeStyles by -1\n if @alignment >= 0 then object.alignment = 0; (if s.alignment >= 0 then object.alignment = s.alignment; break) for s in activeStyles by -1\n if @frameCornerSize >= 0 then object.frameCornerSize = 16; (if s.frameCornerSize >= 0 then object.frameCornerSize = s.frameCornerSize; break) for s in activeStyles by -1\n if @frameThickness >= 0 then object.frameThickness = 16; (if s.frameThickness >= 0 then object.frameThickness = s.frameThickness; break) for s in activeStyles by -1\n if @mask then object.mask.set(null); (if s.mask then object.mask.set(s.font); break) for s in activeStyles by -1\n if @zIndex >= 0 then object.zIndex = 0; (if s.zIndex >= 0 then object.zIndex = s.zIndex; break) for s in activeStyles by -1\n if @alignmentX >= 0 then object.alignmentX = 0; (if s.alignmentX >= 0 then object.alignmentX = s.alignmentX; break) for s in activeStyles by -1\n if @alignmentY >= 0 then object.alignmentY = 0; (if s.alignmentY >= 0 then object.alignmentY = s.alignmentY; break) for s in activeStyles by -1\n if @resizable? then object.resizable = no; (if s.resizable? then object.resizable = s.resizable; break) for s in activeStyles by -1\n \n @revertAnimations(object)\n @revertLooping(object)\n \n ###*\n * Reverts the animation-data changes applied to a UI object by this style.\n *\n * @method revertAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.\n ### \n revertAnimations: (object) ->\n activeStyles = object.activeStyles\n if @animations\n object.animations = null; \n for s in activeStyles by -1\n if s.animations\n object.animations = Object.deepCopy(s.animations)\n if !object.findComponentById(\"animationHandler\")\n object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\")\n \n ###*\n * Reverts the looping-data changes applied to a UI object by this style.\n *\n * @method revertLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.\n ### \n revertLooping: (object) ->\n activeStyles = object.activeStyles\n if @looping\n object.visual.looping.vertical = no\n object.visual.looping.horizontal = no\n for s in activeStyles by -1\n if s.looping\n if !object.visual.looping\n object.visual.dispose()\n object.removeComponent(object.visual)\n object.visual = new gs.Component_TilingSprite()\n object.addComponent(object.visual)\n \n object.visual.looping.vertical = s.looping.vertical\n object.visual.looping.horizontal = s.looping.horizontal\n \nui.Style = Style\n\nclass UIManager\n ###*\n * Handles the creation of In Game UI elements. For more information about\n * In-Game UI see help file.\n *\n * @module ui\n * @class UIManager\n * @memberof ui\n * @constructor\n ###\n constructor: ->\n ###*\n * Stores all registered UI layouts by name/id.\n * @property layouts\n * @type Object\n ###\n @layouts = {}\n \n ###*\n * Stores all registered UI styles by name/id.\n * @property styles\n * @type Object\n ###\n @styles = {}\n \n ###*\n * Stores all UI styles by number id.\n * @property stylesById\n * @type ui.Style[]\n ###\n @stylesById = new Array()\n \n ###*\n * Stores all UI styles by style-name.\n * @property stylesByName\n * @type Object\n ###\n @stylesByName = {}\n \n ###*\n * Stores all registered custom UI types/templates by name/id.\n * @property customTypes\n * @type Object\n ###\n @customTypes = {}\n \n ###*\n * Stores all registered UI controllers by name/id.\n * @property customTypes\n * @type Object\n ###\n @controllers = {}\n \n ###*\n * Stores all registered UI data sources by name/id.\n * @property customTypes\n * @type Object\n ###\n @dataSources = {}\n \n ###*\n * Mapping to table to map alignment names to number values.\n * @property alignments\n * @type Object\n * @protected\n ###\n @alignments = { \"left\": 0, \"top\": 0, \"center\": 1, \"bottom\": 2, \"right\": 2, \"0\": 0, \"1\": 1, \"2\": 2 }\n \n ###*\n * Mapping to table to map blend-mode names to number values.\n * @property blendModes\n * @type Object\n * @protected\n ###\n @blendModes = { \"normal\": 0, \"add\": 1, \"sub\": 2 }\n \n ###*\n * Mapping to table to map selector names to number values.\n * @property selectors\n * @type Object\n ###\n @selectors = { normal: 0, hover: 1, selected: 2, enabled: 3, focused: 4 }\n @defaultPlaceholderParams = {}\n \n ###*\n * Sets up UI Manager, optimizes styles, etc.\n *\n * @method setup\n ###\n setup: ->\n @setupStyles()\n \n ###*\n * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.\n *\n * @method setupStyles\n * @protected\n ###\n setupStyles: ->\n id = 0\n selectorMap = @selectors\n for k of @styles\n subs = k.split(\" \")\n selector = subs[0].split(\":\")\n \n if selectorMap[selector[1]]\n @stylesById[id] = new ui.Style(@styles[k], id, selectorMap[selector[1]])\n else\n @stylesById[id] = new ui.Style(@styles[k], id, 0)\n \n if !@stylesByName[selector[0]]\n @stylesByName[selector[0]] = []\n \n @stylesByName[selector[0]].push(@stylesById[id])\n @styles[k] = @stylesById[id]\n \n id++\n \n for k of @styles\n subs = k.split(\" \")\n if subs.length > 1\n @stylesByName[subs[1]].push(@styles[k])\n @styles[k].target = @styles[k.split(\":\")[0]]?.id\n #@styles[subs[1]].target = @styles[k].id\n #@styles[k].target = @styles[subs[1]].id\n \n return null\n \n ###*\n * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed\n * and placeholder formulas are replaced with their evaluated result value.\n *\n * @method executePlaceholderFormulas\n * @param {Object} descriptor - The descriptor.\n * @param {Object} params - Object containing the placeholder params.\n * @protected\n ### \n executePlaceholderFormulas: (descriptor, id, params) ->\n return if not descriptor?\n keys = Object.keys(descriptor)\n \n for k in keys\n v = descriptor[k]\n if v?\n if v instanceof Array\n for i, c in v\n if i?\n if typeof i == \"object\"\n @executePlaceholderFormulas(i, id, params)\n else if c != \"exec\" and typeof i == \"function\"\n window.p = params || @defaultPlaceholderParams\n window.d = descriptor\n v[c] = i()\n else if typeof v == \"object\"\n @executePlaceholderFormulas(v, id, params)\n else if k != \"exec_\" and typeof v == \"function\"\n window.p = params || @defaultPlaceholderParams\n window.d = descriptor\n descriptor[k] = v()\n return null\n\n ###*\n * Creates a calculation for a specified expression.\n *\n * @method createCalcFunction\n * @param {String} expression - The expression to create a calculation function for.\n * @return {Function} The calculation function.\n * @protected\n ### \n createCalcFunction: (expression) ->\n expression = expression.replace(/([0-9]+)%/gm, \"($1 / 100 * v)\")\n return eval(\"(function(v){ return \" + expression + \"})\")\n \n ###*\n * Creates an object from the specified object type. The type has the format\n * <namespace>.<typename> like vn.Component_Hotspot.\n *\n * @method createObject\n * @param {String} type - The type name.\n * @return {Object} The created object.\n * @protected\n ### \n createObject: (type) ->\n subs = type.split(\".\")\n return new window[subs[0]][subs[1]]()\n \n ###*\n * Creates an UI object from a specified UI descriptor.\n *\n * @method createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n ### \n createFromDescriptor: (descriptor, parent) ->\n control = null\n \n for k of @controllers\n if @controllers[k].type?\n @controllers[k] = @createObject(@controllers[k].type)\n \n @_createFromDescriptor(descriptor, parent)\n \n \n ###*\n * Creates an image button UI object.\n *\n * @method createImageButton\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createImageButton: (descriptor) ->\n control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling) \n \n control.behavior.sound = descriptor.sound\n control.behavior.sounds = descriptor.sounds\n control.image = descriptor.image\n control.images = descriptor.images\n if descriptor.imageFolder?\n control.imageFolder = descriptor.imageFolder\n \n if descriptor.looping?\n control.visual.dispose()\n control.removeComponent(control.visual)\n control.visual = new gs.Component_TilingSprite()\n control.addComponent(control.visual)\n \n control.visual.looping.vertical = descriptor.looping.vertical\n control.visual.looping.horizontal = descriptor.looping.horizontal\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates an image UI object.\n *\n * @method createImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createImage: (descriptor) ->\n control = new ui.Object_Image(descriptor.image, descriptor.imageHandling) \n \n if descriptor.imageFolder?\n control.imageFolder = descriptor.imageFolder\n \n if descriptor.looping?\n control.visual.dispose()\n control.removeComponent(control.visual)\n control.visual = new gs.Component_TilingSprite()\n control.addComponent(control.visual)\n \n control.visual.looping.vertical = descriptor.looping.vertical\n control.visual.looping.horizontal = descriptor.looping.horizontal\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates an image map UI object.\n *\n * @method createImageMap\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createImageMap: (descriptor) ->\n control = new ui.Object_ImageMap()\n control.hotspots = (descriptor.hotspots||[]).select (h) -> \n { x: h.rect[0], y: h.rect[1], size: { width: h.rect[2], height: h.rect[3] }, data: { action: 3, actions: h.actions } }\n control.images = descriptor.images\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\")\n control.target = SceneManager.scene.behavior\n control.visual.variableContext = new gs.InterpreterContext(SceneManager.scene.layoutName, SceneManager.scene)\n \n return control\n \n ###*\n * Creates a video UI object.\n *\n * @method createVideo\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createVideo: (descriptor) ->\n control = new ui.Object_Video()\n control.video = descriptor.video\n control.loop = descriptor.loop ? yes\n \n return control\n \n \n ###*\n * Creates a panel UI object.\n *\n * @method createPanel\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createPanel: (descriptor) ->\n control = new ui.Object_Panel()\n control.modal = descriptor.modal ? no\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates a frame UI object.\n *\n * @method createFrame\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createFrame: (descriptor) ->\n control = new ui.Object_Frame(descriptor.frameSkin)\n control.frameThickness = descriptor.frameThickness || 16\n control.frameCornerSize = descriptor.frameCornerSize || 16\n control.image = descriptor.image\n control.images = descriptor.images\n \n return control\n \n ###*\n * Creates a three-part image UI object.\n *\n * @method createThreePartImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createThreePartImage: (descriptor) ->\n control = new ui.Object_ThreePartImage(descriptor.frameSkin)\n control.firstPartSize = descriptor.firstPartSize || 16\n control.middlePartSize = descriptor.middlePartSize || 1\n control.lastPartSize = descriptor.lastPartSize || 16\n control.image = descriptor.image\n control.images = descriptor.images\n \n return control\n \n ###*\n * Creates a text UI object.\n *\n * @method createText\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createText: (descriptor) ->\n control = new ui.Object_Text()\n control.text = lcs(descriptor.text)\n control.sizeToFit = descriptor.sizeToFit\n control.formatting = descriptor.formatting\n control.wordWrap = descriptor.wordWrap ? no\n control.behavior.format = descriptor.format\n if descriptor.textPadding\n control.behavior.padding = ui.Space.fromArray(descriptor.textPadding)\n if descriptor.resolvePlaceholders?\n control.resolvePlaceholders = descriptor.resolvePlaceholders\n if descriptor.color?\n control.color = Color.fromArray(descriptor.color)\n \n return control\n \n ###*\n * Creates a free-layout UI object.\n *\n * @method createFreeLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createFreeLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1)\n else\n control = new ui.Object_FreeLayout(0, 0, 1, 1)\n control.sizeToFit = descriptor.sizeToFit\n \n return control\n \n ###*\n * Creates a stack-layout UI object.\n *\n * @method createStackLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createStackLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)\n else\n control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation)\n control.sizeToFit = descriptor.sizeToFit\n \n return control\n \n ###*\n * Creates a spread-layout UI object.\n *\n * @method createSpreadLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createSpreadLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)\n else\n control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation)\n \n return control\n \n ###*\n * Creates a grid-layout UI object.\n *\n * @method createGridLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createGridLayout: (descriptor) ->\n if descriptor.frame?\n control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template)\n else\n control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template)\n control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0]\n control.sizeToFit = descriptor.sizeToFit\n \n return control\n \n ###*\n * Creates a message UI object.\n *\n * @method createMessage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createMessage: (descriptor) ->\n control = new ui.Object_Message() \n \n return control\n \n ###*\n * Creates a data-grid UI object.\n *\n * @method createDataGrid\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n ### \n createDataGrid: (descriptor) ->\n control = new ui.Object_DataGrid(descriptor)\n \n return control\n \n ###*\n * Creates an UI object depending on the object-type of the specified UI descriptor.\n *\n * @method createControl\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n ### \n createControl: (descriptor) ->\n control = null\n \n switch descriptor.type\n when \"ui.ImageButton\"\n control = @createImageButton(descriptor)\n when \"ui.Image\"\n control = @createImage(descriptor)\n when \"ui.ImageMap\"\n control = @createImageMap(descriptor)\n when \"ui.Video\"\n control = @createVideo(descriptor)\n when \"ui.Panel\"\n control = @createPanel(descriptor)\n when \"ui.Frame\"\n control = @createFrame(descriptor)\n when \"ui.ThreePartImage\"\n control = @createThreePartImage(descriptor)\n when \"ui.Text\"\n control = @createText(descriptor)\n when \"ui.Message\"\n control = @createMessage(descriptor)\n when \"ui.DataGrid\"\n control = @createDataGrid(descriptor)\n when \"ui.FreeLayout\"\n control = @createFreeLayout(descriptor)\n when \"ui.StackLayout\"\n control = @createStackLayout(descriptor)\n when \"ui.SpreadLayout\"\n control = @createSpreadLayout(descriptor)\n when \"ui.GridLayout\"\n control = @createGridLayout(descriptor)\n \n return control\n \n \n createLayoutRect: (frame, control) ->\n if !control.layoutRect\n control.layoutRect = new ui.LayoutRect()\n control.layoutRect.set(0, 0, 0, 0)\n \n if frame?\n if frame[0]?.length?\n control.layoutRect.x = @createCalcFunction(frame[0])\n control.dstRect.x = 0\n else\n control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)\n \n if frame[1]?.length?\n control.layoutRect.y = @createCalcFunction(frame[1])\n control.dstRect.y = 0\n else\n control.dstRect.y = (frame[1] ? control.dstRect.y)\n \n if frame[2]?.length?\n control.layoutRect.width = @createCalcFunction(frame[2])\n control.dstRect.width = 1\n else\n control.dstRect.width = (frame[2] ? control.dstRect.width)\n \n if frame[3]?.length?\n control.layoutRect.height = @createCalcFunction(frame[3])\n control.dstRect.height = 1\n else\n control.dstRect.height = (frame[3] ? control.dstRect.height)\n \n \n ###*\n * Adds the styles defined in an array of style-names to the specified control.\n *\n * @method addControlStyles\n * @param {Object} control - The control to add the styles to.\n * @param {string[]} styles - Array of style-names to add.\n ### \n addControlStyles: (control, styles) ->\n for styleName in styles\n if @stylesByName[styleName]?\n for style in @stylesByName[styleName]\n control.styles.push(style)\n if style.target == -1 and style.selector == 0\n style.apply(control)\n ###*\n * Creates an UI object from a specified UI descriptor. This method is called\n * recursively for all child-descriptors.\n *\n * @method createControlFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @param {number} index - The index.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n ### \n createControlFromDescriptor: (descriptor, parent, index) ->\n control = null\n \n if descriptor.style?\n descriptor.styles = [descriptor.style]\n delete descriptor.style\n \n descriptor = Object.deepCopy(descriptor)\n @executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params)\n \n control = @createControl(descriptor)\n \n if not control?\n type = Object.deepCopy(@customTypes[descriptor.type])\n \n @executePlaceholderFormulas(type, descriptor.id, descriptor.params)\n \n typeName = type.type\n customFields = type.customFields\n bindings = type.bindings\n formulas = type.formulas\n actions = type.actions\n if type.style?\n type.styles = [type.style]\n type.style = null\n \n Object.mixin(type, descriptor)\n if customFields? then Object.mixin(type.customFields, customFields)\n if bindings? and bindings != type.bindings then type.bindings = type.bindings.concat(bindings)\n if formulas? and formulas != type.formulas then type.formulas = type.formulas.concat(formulas)\n if actions? and actions != type.actions then type.actions = actions.concat(type.actions)\n type.type = typeName\n \n return @createControlFromDescriptor(type, parent)\n else if parent?\n parent.addObject(control)\n control.index = index\n else\n gs.ObjectManager.current.addObject(control)\n \n control.ui = new ui.Component_UIBehavior()\n control.addComponent(control.ui)\n \n \n \n control.params = descriptor.params\n \n if descriptor.updateBehavior == \"continuous\"\n control.updateBehavior = ui.UpdateBehavior.CONTINUOUS\n \n if descriptor.inheritProperties\n control.inheritProperties = yes\n \n if descriptor.font?\n control.font = new Font(descriptor.font.name, descriptor.font.size)\n control.font.bold = descriptor.font.bold ? control.font.bold\n control.font.italic = descriptor.font.italic ? control.font.italic\n control.font.smallCaps = descriptor.font.smallCaps ? control.font.smallCaps\n control.font.underline = descriptor.font.underline ? control.font.underline\n control.font.strikeThrough = descriptor.font.strikeThrough ? control.font.strikeThrough\n \n if descriptor.font.color?\n control.font.color = Color.fromArray(descriptor.font.color)\n if descriptor.font.border?\n control.font.border = descriptor.font.border ? no\n control.font.borderSize = descriptor.font.borderSize ? 4\n #if descriptor.font.border.color\n # control.font.borderColor = Color.fromArray(descriptor.font.border.color)\n control.font.borderColor = new Color(0, 0, 0)\n \n if descriptor.font.outline?\n control.font.border = descriptor.font.outline ? no\n control.font.borderSize = descriptor.font.outline.size ? 4\n \n if descriptor.font.outline.color?\n control.font.borderColor = Color.fromArray(descriptor.font.outline.color)\n else\n control.font.borderColor = new Color(0, 0, 0)\n \n if descriptor.components?\n for c in descriptor.components\n m = c.module || \"gs\"\n component = new window[m][c.type](c.params)\n control.addComponent(component, c.id)\n control[c.id] = component\n #component.setup?()\n \n control.focusable = descriptor.focusable ? control.focusable \n if descriptor.nextKeyObject\n control.ui.nextKeyObjectId = descriptor.nextKeyObject\n \n if descriptor.initialFocus\n control.ui.focus()\n \n actions = Object.deepCopy(if descriptor.action? then [descriptor.action] else descriptor.actions) \n if actions?\n for action in actions\n if action?\n action.event = action.event ? \"onAccept\"\n if not action.target?\n target = if @controllers? then @controllers[descriptor.target] else controller\n action.target = target || SceneManager.scene.behavior\n \n control.actions = actions\n \n if(!control.findComponentById(\"actionHandler\"))\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\")\n \n if descriptor.id?\n control.id = descriptor.id\n gs.ObjectManager.current.setObjectById(control, control.id)\n \n control.descriptor = descriptor\n control.layoutRect = new Rect()\n control.layoutRect.set(0, 0, 0, 0)\n if descriptor.frame?\n if descriptor.frame[0]?.length?\n control.layoutRect.x = @createCalcFunction(descriptor.frame[0])\n control.dstRect.x = 0\n else\n control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)\n \n if descriptor.frame[1]?.length?\n control.layoutRect.y = @createCalcFunction(descriptor.frame[1])\n control.dstRect.y = 0\n else\n control.dstRect.y = (descriptor.frame[1] ? control.dstRect.y)\n \n if descriptor.frame[2]?.length?\n control.layoutRect.width = @createCalcFunction(descriptor.frame[2])\n control.dstRect.width = 1\n else\n control.dstRect.width = (descriptor.frame[2] ? control.dstRect.width)\n \n if descriptor.frame[3]?.length?\n control.layoutRect.height = @createCalcFunction(descriptor.frame[3]) #parseInt(descriptor.frame[3].split(\"%\")[0])\n control.dstRect.height = 1\n else\n control.dstRect.height = (descriptor.frame[3] ? control.dstRect.height)\n \n if descriptor.sizeToParent?\n control.sizeToParent = descriptor.sizeToParent\n \n if descriptor.blendMode?\n control.blendMode = @blendModes[descriptor.blendMode]\n \n if descriptor.anchor?\n control.anchor.set(descriptor.anchor[0], descriptor.anchor[1])\n \n\n control.opacity = descriptor.opacity ? 255 \n if descriptor.minimumSize?\n control.minimumSize = { width: descriptor.minimumSize[0], height: descriptor.minimumSize[1] }\n \n if descriptor.resizable? then control.resizable = descriptor.resizable\n if descriptor.scrollable? then control.scrollable = descriptor.scrollable \n if descriptor.fixedSize? then control.fixedSize = descriptor.fixedSize\n if descriptor.draggable?\n control.draggable = descriptor.draggable\n control.draggable.step = 0\n if control.draggable.rect?\n control.draggable.rect = Rect.fromArray(control.draggable.rect)\n control.addComponent(new ui.Component_Draggable())\n \n if descriptor.bindings?\n control.bindings = descriptor.bindings\n control.insertComponent(new ui.Component_BindingHandler(), 0)\n \n if descriptor.formulas?\n control.formulas = descriptor.formulas\n control.insertComponent(new ui.Component_FormulaHandler(), 0)\n \n control.dataField = descriptor.dataField\n control.enabled = descriptor.enabled ? yes\n if descriptor.selectable? then control.selectable = descriptor.selectable\n if descriptor.group? \n control.group = descriptor.group\n gs.ObjectManager.current.addToGroup(control, control.group)\n \n if descriptor.customFields?\n control.customFields = Object.deepCopy(descriptor.customFields)\n \n if descriptor.margin?\n control.margin.left = descriptor.margin[0]\n control.margin.top = descriptor.margin[1]\n control.margin.right = descriptor.margin[2]\n control.margin.bottom = descriptor.margin[3]\n \n if descriptor.padding?\n control.padding.left = descriptor.padding[0]\n control.padding.top = descriptor.padding[1]\n control.padding.right = descriptor.padding[2]\n control.padding.bottom = descriptor.padding[3]\n \n if descriptor.alignment?\n control.alignment = @alignments[descriptor.alignment]\n \n control.alignmentY = @alignments[descriptor.alignmentY || 0]\n control.alignmentX = @alignments[descriptor.alignmentX || 0]\n control.zIndex = descriptor.zIndex || 0\n control.order = descriptor.order || 0\n control.chainOrder = (descriptor.chainOrder ? descriptor.zOrder) + (parent?.chainOrder || 0)\n if descriptor.zoom?\n control.zoom = x: descriptor.zoom[0] / 100, y: descriptor.zoom[1] / 100\n #control.dataFields = dataFields\n #control.controllers = @controllers\n #control.controller = controller\n \n if descriptor.visible?\n control.visible = descriptor.visible\n if descriptor.clipRect\n control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height)\n\n if descriptor.styles?\n @addControlStyles(control, descriptor.styles)\n \n \n if descriptor.template?\n control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode)\n data = ui.Component_FormulaHandler.fieldValue(control, control.dataField) #control.dataFields[control.dataField]\n isNumber = typeof data == \"number\"\n if data?\n for i in [0...(data.length ? data)]\n if data[i]? or isNumber\n valid = yes\n if descriptor.dataFilter? and not isNumber\n valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter)\n if valid or isNumber\n child = @createControlFromDescriptor(descriptor.template, control, i)\n #child.dataFields = control.dataFields\n \n if data[i]?.dstRect\n child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect)\n if (not child.clipRect?) and control.clipRect?\n child.clipRect = control.clipRect\n #child.parent = control\n control.addObject(child)\n child.index = i\n child.order = (data.length ? data) - i\n control.controls.push(child)\n \n \n if descriptor.controls and descriptor.controls.exec\n controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls)\n else\n controls = descriptor.controls\n \n if controls?\n for item, i in controls\n childControl = @_createFromDescriptor(item, control, i)\n if (not childControl.clipRect?) and control.clipRect?\n childControl.clipRect = control.clipRect\n childControl.index = i\n childControl.origin.x = control.origin.x + control.dstRect.x\n childControl.origin.y = control.origin.y + control.dstRect.y\n #childControl.parent = control\n control.addObject(childControl)\n control.controls.push(childControl)\n \n if control.styles and control.parentsByStyle\n #for style in control.styles\n \n parent = control.parent\n while parent\n if parent.styles\n for style in parent.styles\n if !control.parentsByStyle[style.id]\n control.parentsByStyle[style.id] = []\n control.parentsByStyle[style.id].push(parent)\n \n #while parent\n #if parent.controlsByStyle\n # if(!parent.controlsByStyle[style.id])\n # parent.controlsByStyle[style.id] = []\n # parent.controlsByStyle[style.id].push(control)\n # if control.parentsByStyle\n # if !control.parentsByStyle[style.id]\n # control.parentsByStyle[style.id] = []\n # control.parentsByStyle[style.id].push(parent)\n parent = parent.parent\n \n if descriptor.animations?\n control.animations = Object.deepCopy(descriptor.animations)\n control.animationExecutor = new ui.Component_AnimationExecutor()\n control.addComponent(control.animationExecutor)\n control.addComponent(new ui.Component_AnimationHandler())\n \n control.ui.updateStyle()\n control.setup()\n \n return control\n \n ###*\n * Creates an UI object from a specified UI descriptor.\n *\n * @method _createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n * @protected \n ### \n _createFromDescriptor: (descriptor, parent, index) -> \n control = @createControlFromDescriptor(descriptor, parent, index)\n \n if descriptor.controller?\n controller = @controllers[descriptor.controller]\n control.controller = controller\n control.addComponent(controller)\n \n return control\n \n createLayoutFromDescriptor: (descriptor, parent, index) ->\n @_createFromDescriptor(descriptor, parent, index)\n \n \n \nGraphics.width = $PARAMS.resolution.width\nGraphics.height = $PARAMS.resolution.height\nui.UiFactory = new UIManager()\nui.UIManager = ui.UiFactory",
10 10 "parentId": "C0268943K60B3A42B7SA6F1EDDCF2F642FD7",
11 11 "folder": false,
12 - "compiledContent": "var Formula, Space, Style, UIManager;\n\nFormula = (function() {\n\n /**\n * Encapsulates a UI formula. A formula can be used in UI layouts to define\n * property-bindings or to implement a specific behavior.\n *\n * @module ui\n * @class Formula\n * @memberof ui\n * @constructor\n * @param {Function} f - The formula-function. Defines the logic of the formula.\n * @param {Object} data - An optional data-object which can be accessed inside the formula-function.\n * @param {string} event - An optional event-name to define when the formula should be executed.\n */\n function Formula(f, data, event) {\n\n /**\n * Indicates if its the first time the formula is called.\n * @property onInitialize\n * @type boolean\n */\n var i, j, l, ref, ref1;\n this.onInitialize = true;\n\n /**\n * The formula-function.\n * @property exec_\n * @type Function\n */\n this.exec_ = f;\n\n /**\n * An optional data-object which can bes accessed inside the formula-function.\n * @property data\n * @type Object\n */\n this.data = data;\n\n /**\n * An optional event-name to define when the formula should be executed.\n * @property event\n * @type string\n */\n this.event = event;\n\n /**\n * An array of custom number-data which can be used for different purposes. The first element\n * is also used in onChange method to store the old value and check against the new one to detect a change.\n * @property numbers\n * @type number[]\n */\n this.numbers = new Array(10);\n for (i = j = 0, ref = this.numbers.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {\n this.numbers[i] = 0;\n }\n\n /**\n * An array of custom string-data which can be used for different purposes. The first element\n * is also used in onTextChange method to store the old value and check against the new one to detect a change.\n * @property strings\n * @type string[]\n */\n this.strings = new Array(10);\n for (i = l = 0, ref1 = this.strings.length; 0 <= ref1 ? l <= ref1 : l >= ref1; i = 0 <= ref1 ? ++l : --l) {\n this.strings[i] = \"\";\n }\n }\n\n\n /**\n * The formula-function. Its a wrapper-function before the first-time call was made.\n * @method exec\n */\n\n Formula.prototype.exec = function() {\n var r;\n this.exec = this.exec_;\n r = this.exec_.apply(this, arguments);\n this.onInitialize = false;\n return r;\n };\n\n\n /**\n * Checks if the specified number-value has changed since the last check. It uses\n * the first entry of the numbers-array to store the value and check against the new one.\n *\n * @method onChange\n * @param {number} numberValue - Number value to check.\n */\n\n Formula.prototype.onChange = function(numberValue) {\n var result;\n result = this.numbers[0] !== numberValue;\n this.numbers[0] = numberValue;\n return result;\n };\n\n\n /**\n * Checks if the specified text-value has changed since the last check. It uses\n * the first entry of the strings-array to store the value and check against the new one.\n *\n * @method onTextChange\n * @param {string} textValue - Text value to check.\n */\n\n Formula.prototype.onTextChange = function(textValue) {\n var result;\n result = this.strings[0] !== textValue;\n this.strings[0] = textValue;\n return result;\n };\n\n return Formula;\n\n})();\n\nui.Formula = Formula;\n\nSpace = (function() {\n\n /**\n * Describes a space inside or around something like a margin or padding.\n *\n * @module ui\n * @class Space\n * @memberof ui\n * @constructor\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n */\n function Space(left, top, right, bottom) {\n\n /**\n * Space at the left in pixels.\n * @property left\n * @type number\n */\n this.left = left;\n\n /**\n * Space at the top in pixels.\n * @property top\n * @type number\n */\n this.top = top;\n\n /**\n * Space at the right in pixels.\n * @property right\n * @type number\n */\n this.right = right;\n\n /**\n * Space at the bottom in pixels.\n * @property bottom\n * @type number\n */\n this.bottom = bottom;\n }\n\n\n /**\n * Sets the coordinates of the space by copying them from a specified space.\n *\n * @method setFromObject\n * @param {Object} space - A space to copy.\n */\n\n Space.prototype.setFromObject = function(space) {\n this.left = space.left;\n this.top = space.top;\n this.right = space.right;\n return this.bottom = space.bottom;\n };\n\n\n /**\n * Sets the coordinates of the space.\n *\n * @method set\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n */\n\n Space.prototype.set = function(left, top, right, bottom) {\n this.left = left;\n this.top = top;\n this.right = right;\n return this.bottom = bottom;\n };\n\n\n /**\n * Creates a new space object from an array of coordinates.\n *\n * @method fromArray\n * @static\n * @param {number[]} array - An array of coordinates (left, top right, bottom).\n */\n\n Space.fromArray = function(array) {\n return new ui.Space(array[0], array[1], array[2], array[3]);\n };\n\n return Space;\n\n})();\n\nui.Space = Space;\n\nStyle = (function() {\n\n /**\n * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain \"style\" to it.\n *\n * @module ui\n * @class Style\n * @memberof ui\n * @constructor\n * @param {Object} descriptor - A style-descriptor to initialize the style from.\n * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.\n * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.\n */\n function Style(descriptor, id, selector) {\n\n /**\n * ID number to quickly access this style and link to this style.\n * @property id\n * @type number\n */\n this.id = id;\n\n /**\n * Style-ID of target object. This style will only be applied on UI objects with that style ID which are\n * children of UI objects where this style is applied.\n * @property target\n * @type number\n */\n this.target = -1;\n\n /**\n * Selector-ID which controls under which conditions the style becomes active.\n * @property selector\n * @type number\n */\n this.selector = selector;\n\n /**\n * The font used for the text-display.\n * @default null\n * @property font\n * @type gs.Font\n */\n this.font = null;\n\n /**\n * The UI object's image used for visual presentation.\n * @property image\n * @type string\n */\n this.image = null;\n\n /**\n * The UI object's animations used for visual presentation.\n * @default null\n * @property animations\n * @type Object[]\n */\n this.animations = null;\n\n /**\n * The UI object's color.\n * @property color\n * @type gs.Color\n */\n this.color = null;\n\n /**\n * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner\n * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1\n * places the object with its lower-right corner.\n * @property anchor\n * @type gs.Point\n */\n this.anchor = null;\n\n /**\n * The UI object's zoom-setting for x and y axis.\n * @default new gs.Point(1.0, 1.0)\n * @property zoom\n * @type gs.Point\n */\n this.zoom = null;\n\n /**\n * The UI object's margin. The margin defines an extra space around the UI object. \n * The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property margin\n * @type Object\n */\n this.margin = null;\n\n /**\n * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property padding\n * @type Object\n */\n this.padding = null;\n\n /**\n * The UI object's mask for masking-effects.\n * @property mask\n * @type gs.Mask\n */\n this.mask = null;\n\n /**\n * The UI object's alignment.\n * @property alignment\n * @type ui.Alignment\n */\n this.alignment = -1;\n\n /**\n * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.\n * @property opacity\n * @type number\n */\n this.opacity = -1;\n\n /**\n * The object's clip-rect for visual presentation.\n * @default null\n * @property clipRect\n * @type gs.Rect\n * @protected\n */\n this.clipRect = null;\n\n /**\n * The corner-size of the frame.\n * @property frameCornerSize\n * @type number\n */\n this.frameCornerSize = -1;\n\n /**\n * The thickness of the frame.\n * @property frameThickness\n * @type number\n */\n this.frameThickness = -1;\n\n /**\n * The looping of the image.\n * @property looping\n * @type ui.Orientation\n */\n this.looping = null;\n\n /**\n * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered\n * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it\n * should have the largest z-index of all game objects.\n * @property zIndex\n * @type number\n */\n this.zIndex = -1;\n\n /**\n * The object's alignment on x-axis. Needs to be supported by layout.\n * @property alignmentX\n * @type number\n */\n this.alignmentX = -1;\n\n /**\n * The object's alignment on y-axis. Needs to be supported by layout.\n * @property alignmentY\n * @type number\n */\n this.alignmentY = -1;\n\n /**\n * The object's resize behavior.\n * @property resizable\n * @type boolean\n */\n this.resizable = null;\n\n /**\n * The original style descriptor.\n * @property descriptor\n * @type Object\n */\n this.descriptor = descriptor;\n if (descriptor) {\n this.setFromDescriptor(descriptor);\n }\n }\n\n\n /**\n * Initializes the style from a style-descriptor.\n *\n * @method setFromDescriptor\n * @param {Object} descriptor - The style-descriptor.\n */\n\n Style.prototype.setFromDescriptor = function(descriptor) {\n this.descriptor = descriptor;\n this.image = descriptor.image;\n if (descriptor.color) {\n this.color = gs.Color.fromArray(descriptor.color);\n }\n if (descriptor.anchor) {\n this.anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]);\n }\n if (descriptor.zoom) {\n this.zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]);\n }\n if (descriptor.font) {\n this.setupFont(descriptor);\n }\n if (descriptor.clipRect) {\n this.clipRect = gs.Rect.fromArray(descriptor.clipRect);\n }\n if (descriptor.opacity >= 0) {\n this.opacity = descriptor.opacity;\n }\n if (descriptor.alignment >= 0) {\n this.alignment = descriptor.alignment;\n }\n if (descriptor.margin) {\n this.margin = ui.Space.fromArray(descriptor.margin);\n }\n if (descriptor.padding) {\n this.padding = ui.Space.fromArray(descriptor.padding);\n }\n this.animations = descriptor.animations;\n if (descriptor.frameCornerSize) {\n this.frameCornerSize = descriptor.frameCornerSize;\n }\n if (descriptor.frameThickness) {\n this.frameThickness = descriptor.frameThickness;\n }\n if (descriptor.frame) {\n this.frame = descriptor.frame;\n }\n if (descriptor.looping) {\n this.looping = descriptor.looping;\n }\n if (descriptor.resizable != null) {\n this.resizable = descriptor.resizable;\n }\n if (descriptor.zIndex) {\n this.zIndex = descriptor.zIndex;\n }\n if (descriptor.alignmentX) {\n this.alignmentX = ui.UIManager.alignments[descriptor.alignmentX];\n }\n if (descriptor.alignmentY) {\n return this.alignmentY = ui.UIManager.alignments[descriptor.alignmentY];\n }\n };\n\n Style.prototype.set = function(style) {\n this.image = style.image;\n this.color.setFromObject(style.color);\n this.anchor.set(style.anchor.x, style.anchor.y);\n this.zoom.set(style.zoom.x, style.zoom.y);\n if (style.font) {\n if (!this.font) {\n this.font = new gs.Font(style.font.name, style.font.size);\n }\n this.font.set(style.font);\n }\n if (style.clipRect) {\n if (!this.clipRect) {\n this.clipRect = new gs.Rect();\n }\n this.clipRect.setFromObject(style.clipRect);\n }\n this.opacity = style.opacitz;\n this.alignment = style.alignment;\n this.margin.setFromObject(style.margin);\n return this.padding.setFromObject(style.padding);\n };\n\n\n /**\n * Initializes font-data from a style-descriptor.\n *\n * @method setupFont\n * @param {Object} descriptor - The style-descriptor.\n * @protected\n */\n\n Style.prototype.setupFont = function(descriptor) {\n var ref, ref1, ref10, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9;\n if (descriptor.font) {\n if (!this.font) {\n this.font = new Font(descriptor.font.name, (ref = descriptor.font.size) != null ? ref : 0);\n } else {\n this.font.name = descriptor.font.name;\n this.font.size = (ref1 = descriptor.font.size) != null ? ref1 : 0;\n }\n this.font.bold = (ref2 = descriptor.font.bold) != null ? ref2 : this.font.bold;\n this.font.italic = (ref3 = descriptor.font.italic) != null ? ref3 : this.font.italic;\n this.font.smallCaps = (ref4 = descriptor.font.smallCaps) != null ? ref4 : this.font.smallCaps;\n this.font.underline = (ref5 = descriptor.font.underline) != null ? ref5 : this.font.underline;\n this.font.strikeThrough = (ref6 = descriptor.font.strikeThrough) != null ? ref6 : this.font.strikeThrough;\n if (descriptor.font.color != null) {\n this.font.color.setFromArray(descriptor.font.color);\n }\n if (descriptor.font.border != null) {\n this.font.border = (ref7 = descriptor.font.border) != null ? ref7 : false;\n this.font.borderSize = (ref8 = descriptor.font.borderSize) != null ? ref8 : 4;\n this.font.borderColor.set(0, 0, 0, 255);\n }\n if (descriptor.font.outline != null) {\n this.font.border = (ref9 = descriptor.font.outline) != null ? ref9 : false;\n this.font.borderSize = (ref10 = descriptor.font.outline.size) != null ? ref10 : 4;\n if (descriptor.font.outline.color != null) {\n return this.font.borderColor.setFromArray(descriptor.font.outline.color);\n } else {\n return this.font.borderColor.set(0, 0, 0, 255);\n }\n }\n }\n };\n\n\n /**\n * Applies the style to a UI object.\n *\n * @method apply\n * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.\n */\n\n Style.prototype.apply = function(object) {\n var ref;\n if (!object.activeStyles.contains(this)) {\n object.activeStyles.push(this);\n if (this.font) {\n if ((ref = object.font) != null) {\n ref.set(this.font);\n }\n }\n if (this.color) {\n object.color.set(this.color);\n }\n if (this.image) {\n object.image = this.image;\n }\n if (this.anchor) {\n object.anchor.set(this.anchor.x, this.anchor.y);\n }\n if (this.zoom) {\n object.zoom.set(this.zoom.x, this.zoom.y);\n }\n if (this.padding) {\n object.padding.setFromObject(this.padding);\n }\n if (this.margin) {\n object.margin.setFromObject(this.margin);\n }\n if (this.opacity >= 0) {\n object.opacity = this.opacity;\n }\n if (this.alignment >= 0) {\n object.alignment = this.alignment;\n }\n if (this.frameThickness >= 0) {\n object.frameThickness = this.frameThickness;\n }\n if (this.frameCornerSize >= 0) {\n object.frameCornerSize = this.frameCornerSize;\n }\n if (this.mask) {\n object.mask.set(this.mask);\n }\n if (this.zIndex >= 0) {\n object.zIndex = this.zIndex;\n }\n if (this.alignmentX >= 0) {\n object.alignmentX = this.alignmentX;\n }\n if (this.alignmentY >= 0) {\n object.alignmentY = this.alignmentY;\n }\n if (this.resizable != null) {\n object.resizable = this.resizable;\n }\n this.applyLooping(object);\n return this.applyAnimations(object);\n }\n };\n\n\n /**\n * Applies the looping-data of the style to a UI object.\n *\n * @method applyLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.\n * @protected\n */\n\n Style.prototype.applyLooping = function(object) {\n if (this.looping) {\n if (!object.visual.looping) {\n object.visual.dispose();\n object.removeComponent(object.visual);\n object.visual = new gs.Component_TilingSprite();\n object.addComponent(object.visual);\n }\n object.visual.looping.vertical = this.looping.vertical;\n return object.visual.looping.horizontal = this.looping.horizontal;\n }\n };\n\n\n /**\n * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler\n * component(ui.Component_AnimationHandler) with the id \"animationHandler\" to the UI object if not already exists.\n *\n * @method applyAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.\n * @protected\n */\n\n Style.prototype.applyAnimations = function(object) {\n if (this.animations) {\n object.animations = Object.deepCopy(this.animations);\n if (!object.findComponentById(\"animationHandler\")) {\n object.animationExecutor = new ui.Component_AnimationExecutor();\n object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\");\n return object.addComponent(object.animationExecutor, \"animationExecutor\");\n }\n }\n };\n\n\n /**\n * Reverts the changes from a UI object made by this style. However, this resets all styleable properties\n * were set by this style. So it is necessary to apply all other styles again, but that is already handles in\n * ui.Component_UIBehavior.\n *\n * @method revert\n * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.\n */\n\n Style.prototype.revert = function(object) {\n var activeStyles, i1, j, j1, k1, l, l1, n, o, p, q, s, t, u, w, x, y, z;\n activeStyles = object.activeStyles;\n if (object.activeStyles.contains(this)) {\n object.activeStyles.remove(this);\n if (this.font) {\n object.font.set(gs.Fonts.TEXT);\n for (j = activeStyles.length - 1; j >= 0; j += -1) {\n s = activeStyles[j];\n if (s.font) {\n object.font.set(s.font);\n break;\n }\n }\n }\n if (this.color) {\n object.color.set(Color.WHITE);\n for (l = activeStyles.length - 1; l >= 0; l += -1) {\n s = activeStyles[l];\n if (s.color) {\n object.color.set(s.color);\n break;\n }\n }\n }\n if (this.image) {\n object.image = null;\n for (n = activeStyles.length - 1; n >= 0; n += -1) {\n s = activeStyles[n];\n if (s.image) {\n object.image = s.image;\n break;\n }\n }\n }\n if (this.anchor) {\n object.anchor.set(0, 0);\n for (o = activeStyles.length - 1; o >= 0; o += -1) {\n s = activeStyles[o];\n if (s.anchor) {\n object.anchor.setFromObject(s.anchor);\n break;\n }\n }\n }\n if (this.zoom) {\n object.zoom.set(1.0, 1.0);\n for (p = activeStyles.length - 1; p >= 0; p += -1) {\n s = activeStyles[p];\n if (s.zoom) {\n object.zoom.setFromObject(s.zoom);\n break;\n }\n }\n }\n if (this.padding) {\n object.padding.set(0, 0, 0, 0);\n for (q = activeStyles.length - 1; q >= 0; q += -1) {\n s = activeStyles[q];\n if (s.padding) {\n object.padding.setFromObject(s.padding);\n break;\n }\n }\n }\n if (this.margin) {\n object.margin.set(0, 0, 0, 0);\n for (t = activeStyles.length - 1; t >= 0; t += -1) {\n s = activeStyles[t];\n if (s.margin) {\n object.margin.setFromObject(s.margin);\n break;\n }\n }\n }\n if (this.opacity >= 0) {\n object.opacity = 255;\n for (u = activeStyles.length - 1; u >= 0; u += -1) {\n s = activeStyles[u];\n if (s.opacity >= 0) {\n object.opacity = s.opacity;\n break;\n }\n }\n }\n if (this.alignment >= 0) {\n object.alignment = 0;\n for (w = activeStyles.length - 1; w >= 0; w += -1) {\n s = activeStyles[w];\n if (s.alignment >= 0) {\n object.alignment = s.alignment;\n break;\n }\n }\n }\n if (this.frameCornerSize >= 0) {\n object.frameCornerSize = 16;\n for (x = activeStyles.length - 1; x >= 0; x += -1) {\n s = activeStyles[x];\n if (s.frameCornerSize >= 0) {\n object.frameCornerSize = s.frameCornerSize;\n break;\n }\n }\n }\n if (this.frameThickness >= 0) {\n object.frameThickness = 16;\n for (y = activeStyles.length - 1; y >= 0; y += -1) {\n s = activeStyles[y];\n if (s.frameThickness >= 0) {\n object.frameThickness = s.frameThickness;\n break;\n }\n }\n }\n if (this.mask) {\n object.mask.set(null);\n for (z = activeStyles.length - 1; z >= 0; z += -1) {\n s = activeStyles[z];\n if (s.mask) {\n object.mask.set(s.font);\n break;\n }\n }\n }\n if (this.zIndex >= 0) {\n object.zIndex = 0;\n for (i1 = activeStyles.length - 1; i1 >= 0; i1 += -1) {\n s = activeStyles[i1];\n if (s.zIndex >= 0) {\n object.zIndex = s.zIndex;\n break;\n }\n }\n }\n if (this.alignmentX >= 0) {\n object.alignmentX = 0;\n for (j1 = activeStyles.length - 1; j1 >= 0; j1 += -1) {\n s = activeStyles[j1];\n if (s.alignmentX >= 0) {\n object.alignmentX = s.alignmentX;\n break;\n }\n }\n }\n if (this.alignmentY >= 0) {\n object.alignmentY = 0;\n for (k1 = activeStyles.length - 1; k1 >= 0; k1 += -1) {\n s = activeStyles[k1];\n if (s.alignmentY >= 0) {\n object.alignmentY = s.alignmentY;\n break;\n }\n }\n }\n if (this.resizable != null) {\n object.resizable = false;\n for (l1 = activeStyles.length - 1; l1 >= 0; l1 += -1) {\n s = activeStyles[l1];\n if (s.resizable != null) {\n object.resizable = s.resizable;\n break;\n }\n }\n }\n this.revertAnimations(object);\n return this.revertLooping(object);\n }\n };\n\n\n /**\n * Reverts the animation-data changes applied to a UI object by this style.\n *\n * @method revertAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.\n */\n\n Style.prototype.revertAnimations = function(object) {\n var activeStyles, j, results, s;\n activeStyles = object.activeStyles;\n if (this.animations) {\n object.animations = null;\n results = [];\n for (j = activeStyles.length - 1; j >= 0; j += -1) {\n s = activeStyles[j];\n if (s.animations) {\n object.animations = Object.deepCopy(s.animations);\n if (!object.findComponentById(\"animationHandler\")) {\n results.push(object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\"));\n } else {\n results.push(void 0);\n }\n } else {\n results.push(void 0);\n }\n }\n return results;\n }\n };\n\n\n /**\n * Reverts the looping-data changes applied to a UI object by this style.\n *\n * @method revertLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.\n */\n\n Style.prototype.revertLooping = function(object) {\n var activeStyles, j, results, s;\n activeStyles = object.activeStyles;\n if (this.looping) {\n object.visual.looping.vertical = false;\n object.visual.looping.horizontal = false;\n results = [];\n for (j = activeStyles.length - 1; j >= 0; j += -1) {\n s = activeStyles[j];\n if (s.looping) {\n if (!object.visual.looping) {\n object.visual.dispose();\n object.removeComponent(object.visual);\n object.visual = new gs.Component_TilingSprite();\n object.addComponent(object.visual);\n }\n object.visual.looping.vertical = s.looping.vertical;\n results.push(object.visual.looping.horizontal = s.looping.horizontal);\n } else {\n results.push(void 0);\n }\n }\n return results;\n }\n };\n\n return Style;\n\n})();\n\nui.Style = Style;\n\nUIManager = (function() {\n\n /**\n * Handles the creation of In Game UI elements. For more information about\n * In-Game UI see help file.\n *\n * @module ui\n * @class UIManager\n * @memberof ui\n * @constructor\n */\n function UIManager() {\n\n /**\n * Stores all registered UI layouts by name/id.\n * @property layouts\n * @type Object\n */\n this.layouts = {};\n\n /**\n * Stores all registered UI styles by name/id.\n * @property styles\n * @type Object\n */\n this.styles = {};\n\n /**\n * Stores all UI styles by number id.\n * @property stylesById\n * @type ui.Style[]\n */\n this.stylesById = new Array();\n\n /**\n * Stores all UI styles by style-name.\n * @property stylesByName\n * @type Object\n */\n this.stylesByName = {};\n\n /**\n * Stores all registered custom UI types/templates by name/id.\n * @property customTypes\n * @type Object\n */\n this.customTypes = {};\n\n /**\n * Stores all registered UI controllers by name/id.\n * @property customTypes\n * @type Object\n */\n this.controllers = {};\n\n /**\n * Stores all registered UI data sources by name/id.\n * @property customTypes\n * @type Object\n */\n this.dataSources = {};\n\n /**\n * Mapping to table to map alignment names to number values.\n * @property alignments\n * @type Object\n * @protected\n */\n this.alignments = {\n \"left\": 0,\n \"top\": 0,\n \"center\": 1,\n \"bottom\": 2,\n \"right\": 2,\n \"0\": 0,\n \"1\": 1,\n \"2\": 2\n };\n\n /**\n * Mapping to table to map blend-mode names to number values.\n * @property blendModes\n * @type Object\n * @protected\n */\n this.blendModes = {\n \"normal\": 0,\n \"add\": 1,\n \"sub\": 2\n };\n\n /**\n * Mapping to table to map selector names to number values.\n * @property selectors\n * @type Object\n */\n this.selectors = {\n normal: 0,\n hover: 1,\n selected: 2,\n enabled: 3,\n focused: 4\n };\n this.defaultPlaceholderParams = {};\n }\n\n\n /**\n * Sets up UI Manager, optimizes styles, etc.\n *\n * @method setup\n */\n\n UIManager.prototype.setup = function() {\n return this.setupStyles();\n };\n\n\n /**\n * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.\n *\n * @method setupStyles\n * @protected\n */\n\n UIManager.prototype.setupStyles = function() {\n var id, k, ref, selector, selectorMap, subs;\n id = 0;\n selectorMap = this.selectors;\n for (k in this.styles) {\n subs = k.split(\" \");\n selector = subs[0].split(\":\");\n if (selectorMap[selector[1]]) {\n this.stylesById[id] = new ui.Style(this.styles[k], id, selectorMap[selector[1]]);\n } else {\n this.stylesById[id] = new ui.Style(this.styles[k], id, 0);\n }\n if (!this.stylesByName[selector[0]]) {\n this.stylesByName[selector[0]] = [];\n }\n this.stylesByName[selector[0]].push(this.stylesById[id]);\n this.styles[k] = this.stylesById[id];\n id++;\n }\n for (k in this.styles) {\n subs = k.split(\" \");\n if (subs.length > 1) {\n this.stylesByName[subs[1]].push(this.styles[k]);\n this.styles[k].target = (ref = this.styles[k.split(\":\")[0]]) != null ? ref.id : void 0;\n }\n }\n return null;\n };\n\n\n /**\n * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed\n * and placeholder formulas are replaced with their evaluated result value.\n *\n * @method executePlaceholderFormulas\n * @param {Object} descriptor - The descriptor.\n * @param {Object} params - Object containing the placeholder params.\n * @protected\n */\n\n UIManager.prototype.executePlaceholderFormulas = function(descriptor, id, params) {\n var c, i, j, k, keys, l, len, len1, v;\n if (descriptor == null) {\n return;\n }\n keys = Object.keys(descriptor);\n for (j = 0, len = keys.length; j < len; j++) {\n k = keys[j];\n v = descriptor[k];\n if (v != null) {\n if (v instanceof Array) {\n for (c = l = 0, len1 = v.length; l < len1; c = ++l) {\n i = v[c];\n if (i != null) {\n if (typeof i === \"object\") {\n this.executePlaceholderFormulas(i, id, params);\n } else if (c !== \"exec\" && typeof i === \"function\") {\n window.p = params || this.defaultPlaceholderParams;\n window.d = descriptor;\n v[c] = i();\n }\n }\n }\n } else if (typeof v === \"object\") {\n this.executePlaceholderFormulas(v, id, params);\n } else if (k !== \"exec_\" && typeof v === \"function\") {\n window.p = params || this.defaultPlaceholderParams;\n window.d = descriptor;\n descriptor[k] = v();\n }\n }\n }\n return null;\n };\n\n\n /**\n * Creates a calculation for a specified expression.\n *\n * @method createCalcFunction\n * @param {String} expression - The expression to create a calculation function for.\n * @return {Function} The calculation function.\n * @protected\n */\n\n UIManager.prototype.createCalcFunction = function(expression) {\n expression = expression.replace(/([0-9]+)%/gm, \"($1 / 100 * v)\");\n return eval(\"(function(v){ return \" + expression + \"})\");\n };\n\n\n /**\n * Creates an object from the specified object type. The type has the format\n * <namespace>.<typename> like vn.Component_Hotspot.\n *\n * @method createObject\n * @param {String} type - The type name.\n * @return {Object} The created object.\n * @protected\n */\n\n UIManager.prototype.createObject = function(type) {\n var subs;\n subs = type.split(\".\");\n return new window[subs[0]][subs[1]]();\n };\n\n\n /**\n * Creates an UI object from a specified UI descriptor.\n *\n * @method createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n */\n\n UIManager.prototype.createFromDescriptor = function(descriptor, parent) {\n var control, k;\n control = null;\n for (k in this.controllers) {\n if (this.controllers[k].type != null) {\n this.controllers[k] = this.createObject(this.controllers[k].type);\n }\n }\n return this._createFromDescriptor(descriptor, parent);\n };\n\n\n /**\n * Creates an image button UI object.\n *\n * @method createImageButton\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createImageButton = function(descriptor) {\n var control;\n control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling);\n control.behavior.sound = descriptor.sound;\n control.behavior.sounds = descriptor.sounds;\n control.image = descriptor.image;\n control.images = descriptor.images;\n if (descriptor.imageFolder != null) {\n control.imageFolder = descriptor.imageFolder;\n }\n if (descriptor.looping != null) {\n control.visual.dispose();\n control.removeComponent(control.visual);\n control.visual = new gs.Component_TilingSprite();\n control.addComponent(control.visual);\n control.visual.looping.vertical = descriptor.looping.vertical;\n control.visual.looping.horizontal = descriptor.looping.horizontal;\n }\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates an image UI object.\n *\n * @method createImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createImage = function(descriptor) {\n var control;\n control = new ui.Object_Image(descriptor.image, descriptor.imageHandling);\n if (descriptor.imageFolder != null) {\n control.imageFolder = descriptor.imageFolder;\n }\n if (descriptor.looping != null) {\n control.visual.dispose();\n control.removeComponent(control.visual);\n control.visual = new gs.Component_TilingSprite();\n control.addComponent(control.visual);\n control.visual.looping.vertical = descriptor.looping.vertical;\n control.visual.looping.horizontal = descriptor.looping.horizontal;\n }\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates an image map UI object.\n *\n * @method createImageMap\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createImageMap = function(descriptor) {\n var control;\n control = new ui.Object_ImageMap();\n control.hotspots = (descriptor.hotspots || []).select(function(h) {\n return {\n x: h.rect[0],\n y: h.rect[1],\n size: {\n width: h.rect[2],\n height: h.rect[3]\n },\n data: {\n action: 3,\n actions: h.actions\n }\n };\n });\n control.images = descriptor.images;\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\");\n control.target = SceneManager.scene.behavior;\n return control;\n };\n\n\n /**\n * Creates a video UI object.\n *\n * @method createVideo\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createVideo = function(descriptor) {\n var control, ref;\n control = new ui.Object_Video();\n control.video = descriptor.video;\n control.loop = (ref = descriptor.loop) != null ? ref : true;\n return control;\n };\n\n\n /**\n * Creates a panel UI object.\n *\n * @method createPanel\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createPanel = function(descriptor) {\n var control, ref;\n control = new ui.Object_Panel();\n control.modal = (ref = descriptor.modal) != null ? ref : false;\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates a frame UI object.\n *\n * @method createFrame\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createFrame = function(descriptor) {\n var control;\n control = new ui.Object_Frame(descriptor.frameSkin);\n control.frameThickness = descriptor.frameThickness || 16;\n control.frameCornerSize = descriptor.frameCornerSize || 16;\n control.image = descriptor.image;\n control.images = descriptor.images;\n return control;\n };\n\n\n /**\n * Creates a three-part image UI object.\n *\n * @method createThreePartImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createThreePartImage = function(descriptor) {\n var control;\n control = new ui.Object_ThreePartImage(descriptor.frameSkin);\n control.firstPartSize = descriptor.firstPartSize || 16;\n control.middlePartSize = descriptor.middlePartSize || 1;\n control.lastPartSize = descriptor.lastPartSize || 16;\n control.image = descriptor.image;\n control.images = descriptor.images;\n return control;\n };\n\n\n /**\n * Creates a text UI object.\n *\n * @method createText\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createText = function(descriptor) {\n var control, ref;\n control = new ui.Object_Text();\n control.text = lcs(descriptor.text);\n control.sizeToFit = descriptor.sizeToFit;\n control.formatting = descriptor.formatting;\n control.wordWrap = (ref = descriptor.wordWrap) != null ? ref : false;\n control.behavior.format = descriptor.format;\n if (descriptor.textPadding) {\n control.behavior.padding = ui.Space.fromArray(descriptor.textPadding);\n }\n if (descriptor.resolvePlaceholders != null) {\n control.resolvePlaceholders = descriptor.resolvePlaceholders;\n }\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates a free-layout UI object.\n *\n * @method createFreeLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createFreeLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1);\n } else {\n control = new ui.Object_FreeLayout(0, 0, 1, 1);\n }\n control.sizeToFit = descriptor.sizeToFit;\n return control;\n };\n\n\n /**\n * Creates a stack-layout UI object.\n *\n * @method createStackLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createStackLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation);\n } else {\n control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation);\n }\n control.sizeToFit = descriptor.sizeToFit;\n return control;\n };\n\n\n /**\n * Creates a spread-layout UI object.\n *\n * @method createSpreadLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createSpreadLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation);\n } else {\n control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation);\n }\n return control;\n };\n\n\n /**\n * Creates a grid-layout UI object.\n *\n * @method createGridLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createGridLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template);\n } else {\n control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template);\n }\n control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0];\n control.sizeToFit = descriptor.sizeToFit;\n return control;\n };\n\n\n /**\n * Creates a message UI object.\n *\n * @method createMessage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createMessage = function(descriptor) {\n var control;\n control = new ui.Object_Message();\n return control;\n };\n\n\n /**\n * Creates a data-grid UI object.\n *\n * @method createDataGrid\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createDataGrid = function(descriptor) {\n var control;\n control = new ui.Object_DataGrid(descriptor);\n return control;\n };\n\n\n /**\n * Creates an UI object depending on the object-type of the specified UI descriptor.\n *\n * @method createControl\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n */\n\n UIManager.prototype.createControl = function(descriptor) {\n var control;\n control = null;\n switch (descriptor.type) {\n case \"ui.ImageButton\":\n control = this.createImageButton(descriptor);\n break;\n case \"ui.Image\":\n control = this.createImage(descriptor);\n break;\n case \"ui.ImageMap\":\n control = this.createImageMap(descriptor);\n break;\n case \"ui.Video\":\n control = this.createVideo(descriptor);\n break;\n case \"ui.Panel\":\n control = this.createPanel(descriptor);\n break;\n case \"ui.Frame\":\n control = this.createFrame(descriptor);\n break;\n case \"ui.ThreePartImage\":\n control = this.createThreePartImage(descriptor);\n break;\n case \"ui.Text\":\n control = this.createText(descriptor);\n break;\n case \"ui.Message\":\n control = this.createMessage(descriptor);\n break;\n case \"ui.DataGrid\":\n control = this.createDataGrid(descriptor);\n break;\n case \"ui.FreeLayout\":\n control = this.createFreeLayout(descriptor);\n break;\n case \"ui.StackLayout\":\n control = this.createStackLayout(descriptor);\n break;\n case \"ui.SpreadLayout\":\n control = this.createSpreadLayout(descriptor);\n break;\n case \"ui.GridLayout\":\n control = this.createGridLayout(descriptor);\n }\n return control;\n };\n\n UIManager.prototype.createLayoutRect = function(frame, control) {\n var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7;\n if (!control.layoutRect) {\n control.layoutRect = new ui.LayoutRect();\n }\n control.layoutRect.set(0, 0, 0, 0);\n if (frame != null) {\n if (((ref = frame[0]) != null ? ref.length : void 0) != null) {\n control.layoutRect.x = this.createCalcFunction(frame[0]);\n control.dstRect.x = 0;\n } else {\n control.dstRect.x = (ref1 = descriptor.frame[0]) != null ? ref1 : control.dstRect.x;\n }\n if (((ref2 = frame[1]) != null ? ref2.length : void 0) != null) {\n control.layoutRect.y = this.createCalcFunction(frame[1]);\n control.dstRect.y = 0;\n } else {\n control.dstRect.y = (ref3 = frame[1]) != null ? ref3 : control.dstRect.y;\n }\n if (((ref4 = frame[2]) != null ? ref4.length : void 0) != null) {\n control.layoutRect.width = this.createCalcFunction(frame[2]);\n control.dstRect.width = 1;\n } else {\n control.dstRect.width = (ref5 = frame[2]) != null ? ref5 : control.dstRect.width;\n }\n if (((ref6 = frame[3]) != null ? ref6.length : void 0) != null) {\n control.layoutRect.height = this.createCalcFunction(frame[3]);\n return control.dstRect.height = 1;\n } else {\n return control.dstRect.height = (ref7 = frame[3]) != null ? ref7 : control.dstRect.height;\n }\n }\n };\n\n\n /**\n * Adds the styles defined in an array of style-names to the specified control.\n *\n * @method addControlStyles\n * @param {Object} control - The control to add the styles to.\n * @param {string[]} styles - Array of style-names to add.\n */\n\n UIManager.prototype.addControlStyles = function(control, styles) {\n var j, len, results, style, styleName;\n results = [];\n for (j = 0, len = styles.length; j < len; j++) {\n styleName = styles[j];\n if (this.stylesByName[styleName] != null) {\n results.push((function() {\n var l, len1, ref, results1;\n ref = this.stylesByName[styleName];\n results1 = [];\n for (l = 0, len1 = ref.length; l < len1; l++) {\n style = ref[l];\n control.styles.push(style);\n if (style.target === -1 && style.selector === 0) {\n results1.push(style.apply(control));\n } else {\n results1.push(void 0);\n }\n }\n return results1;\n }).call(this));\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Creates an UI object from a specified UI descriptor. This method is called\n * recursively for all child-descriptors.\n *\n * @method createControlFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @param {number} index - The index.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n */\n\n UIManager.prototype.createControlFromDescriptor = function(descriptor, parent, index) {\n var action, actions, bindings, c, child, childControl, component, control, controls, customFields, data, formulas, i, isNumber, item, j, l, len, len1, len2, len3, m, n, o, p, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, ref19, ref2, ref20, ref21, ref22, ref23, ref24, ref25, ref26, ref27, ref3, ref4, ref5, ref6, ref7, ref8, ref9, style, target, type, typeName, valid;\n control = null;\n if (descriptor.style != null) {\n descriptor.styles = [descriptor.style];\n delete descriptor.style;\n }\n descriptor = Object.deepCopy(descriptor);\n this.executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params);\n control = this.createControl(descriptor);\n if (control == null) {\n type = Object.deepCopy(this.customTypes[descriptor.type]);\n this.executePlaceholderFormulas(type, descriptor.id, descriptor.params);\n typeName = type.type;\n customFields = type.customFields;\n bindings = type.bindings;\n formulas = type.formulas;\n actions = type.actions;\n if (type.style != null) {\n type.styles = [type.style];\n type.style = null;\n }\n Object.mixin(type, descriptor);\n if (customFields != null) {\n Object.mixin(type.customFields, customFields);\n }\n if ((bindings != null) && bindings !== type.bindings) {\n type.bindings = type.bindings.concat(bindings);\n }\n if ((formulas != null) && formulas !== type.formulas) {\n type.formulas = type.formulas.concat(formulas);\n }\n if ((actions != null) && actions !== type.actions) {\n type.actions = actions.concat(type.actions);\n }\n type.type = typeName;\n return this.createControlFromDescriptor(type, parent);\n } else if (parent != null) {\n parent.addObject(control);\n control.index = index;\n } else {\n gs.ObjectManager.current.addObject(control);\n }\n control.ui = new ui.Component_UIBehavior();\n control.addComponent(control.ui);\n control.params = descriptor.params;\n if (descriptor.updateBehavior === \"continuous\") {\n control.updateBehavior = ui.UpdateBehavior.CONTINUOUS;\n }\n if (descriptor.inheritProperties) {\n control.inheritProperties = true;\n }\n if (descriptor.font != null) {\n control.font = new Font(descriptor.font.name, descriptor.font.size);\n control.font.bold = (ref = descriptor.font.bold) != null ? ref : control.font.bold;\n control.font.italic = (ref1 = descriptor.font.italic) != null ? ref1 : control.font.italic;\n control.font.smallCaps = (ref2 = descriptor.font.smallCaps) != null ? ref2 : control.font.smallCaps;\n control.font.underline = (ref3 = descriptor.font.underline) != null ? ref3 : control.font.underline;\n control.font.strikeThrough = (ref4 = descriptor.font.strikeThrough) != null ? ref4 : control.font.strikeThrough;\n if (descriptor.font.color != null) {\n control.font.color = Color.fromArray(descriptor.font.color);\n }\n if (descriptor.font.border != null) {\n control.font.border = (ref5 = descriptor.font.border) != null ? ref5 : false;\n control.font.borderSize = (ref6 = descriptor.font.borderSize) != null ? ref6 : 4;\n control.font.borderColor = new Color(0, 0, 0);\n }\n if (descriptor.font.outline != null) {\n control.font.border = (ref7 = descriptor.font.outline) != null ? ref7 : false;\n control.font.borderSize = (ref8 = descriptor.font.outline.size) != null ? ref8 : 4;\n if (descriptor.font.outline.color != null) {\n control.font.borderColor = Color.fromArray(descriptor.font.outline.color);\n } else {\n control.font.borderColor = new Color(0, 0, 0);\n }\n }\n }\n if (descriptor.components != null) {\n ref9 = descriptor.components;\n for (j = 0, len = ref9.length; j < len; j++) {\n c = ref9[j];\n m = c.module || \"gs\";\n component = new window[m][c.type](c.params);\n control.addComponent(component, c.id);\n control[c.id] = component;\n }\n }\n control.focusable = (ref10 = descriptor.focusable) != null ? ref10 : control.focusable;\n if (descriptor.nextKeyObject) {\n control.ui.nextKeyObjectId = descriptor.nextKeyObject;\n }\n if (descriptor.initialFocus) {\n control.ui.focus();\n }\n actions = Object.deepCopy(descriptor.action != null ? [descriptor.action] : descriptor.actions);\n if (actions != null) {\n for (l = 0, len1 = actions.length; l < len1; l++) {\n action = actions[l];\n if (action != null) {\n action.event = (ref11 = action.event) != null ? ref11 : \"onAccept\";\n if (action.target == null) {\n target = this.controllers != null ? this.controllers[descriptor.target] : controller;\n action.target = target || SceneManager.scene.behavior;\n }\n }\n }\n control.actions = actions;\n if (!control.findComponentById(\"actionHandler\")) {\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\");\n }\n }\n if (descriptor.id != null) {\n control.id = descriptor.id;\n gs.ObjectManager.current.setObjectById(control, control.id);\n }\n control.descriptor = descriptor;\n control.layoutRect = new Rect();\n control.layoutRect.set(0, 0, 0, 0);\n if (descriptor.frame != null) {\n if (((ref12 = descriptor.frame[0]) != null ? ref12.length : void 0) != null) {\n control.layoutRect.x = this.createCalcFunction(descriptor.frame[0]);\n control.dstRect.x = 0;\n } else {\n control.dstRect.x = (ref13 = descriptor.frame[0]) != null ? ref13 : control.dstRect.x;\n }\n if (((ref14 = descriptor.frame[1]) != null ? ref14.length : void 0) != null) {\n control.layoutRect.y = this.createCalcFunction(descriptor.frame[1]);\n control.dstRect.y = 0;\n } else {\n control.dstRect.y = (ref15 = descriptor.frame[1]) != null ? ref15 : control.dstRect.y;\n }\n if (((ref16 = descriptor.frame[2]) != null ? ref16.length : void 0) != null) {\n control.layoutRect.width = this.createCalcFunction(descriptor.frame[2]);\n control.dstRect.width = 1;\n } else {\n control.dstRect.width = (ref17 = descriptor.frame[2]) != null ? ref17 : control.dstRect.width;\n }\n if (((ref18 = descriptor.frame[3]) != null ? ref18.length : void 0) != null) {\n control.layoutRect.height = this.createCalcFunction(descriptor.frame[3]);\n control.dstRect.height = 1;\n } else {\n control.dstRect.height = (ref19 = descriptor.frame[3]) != null ? ref19 : control.dstRect.height;\n }\n }\n if (descriptor.sizeToParent != null) {\n control.sizeToParent = descriptor.sizeToParent;\n }\n if (descriptor.blendMode != null) {\n control.blendMode = this.blendModes[descriptor.blendMode];\n }\n if (descriptor.anchor != null) {\n control.anchor.set(descriptor.anchor[0], descriptor.anchor[1]);\n }\n control.opacity = (ref20 = descriptor.opacity) != null ? ref20 : 255;\n if (descriptor.minimumSize != null) {\n control.minimumSize = {\n width: descriptor.minimumSize[0],\n height: descriptor.minimumSize[1]\n };\n }\n if (descriptor.resizable != null) {\n control.resizable = descriptor.resizable;\n }\n if (descriptor.scrollable != null) {\n control.scrollable = descriptor.scrollable;\n }\n if (descriptor.fixedSize != null) {\n control.fixedSize = descriptor.fixedSize;\n }\n if (descriptor.draggable != null) {\n control.draggable = descriptor.draggable;\n control.draggable.step = 0;\n if (control.draggable.rect != null) {\n control.draggable.rect = Rect.fromArray(control.draggable.rect);\n }\n control.addComponent(new ui.Component_Draggable());\n }\n if (descriptor.bindings != null) {\n control.bindings = descriptor.bindings;\n control.insertComponent(new ui.Component_BindingHandler(), 0);\n }\n if (descriptor.formulas != null) {\n control.formulas = descriptor.formulas;\n control.insertComponent(new ui.Component_FormulaHandler(), 0);\n }\n control.dataField = descriptor.dataField;\n control.enabled = (ref21 = descriptor.enabled) != null ? ref21 : true;\n if (descriptor.selectable != null) {\n control.selectable = descriptor.selectable;\n }\n if (descriptor.group != null) {\n control.group = descriptor.group;\n gs.ObjectManager.current.addToGroup(control, control.group);\n }\n if (descriptor.customFields != null) {\n control.customFields = Object.deepCopy(descriptor.customFields);\n }\n if (descriptor.margin != null) {\n control.margin.left = descriptor.margin[0];\n control.margin.top = descriptor.margin[1];\n control.margin.right = descriptor.margin[2];\n control.margin.bottom = descriptor.margin[3];\n }\n if (descriptor.padding != null) {\n control.padding.left = descriptor.padding[0];\n control.padding.top = descriptor.padding[1];\n control.padding.right = descriptor.padding[2];\n control.padding.bottom = descriptor.padding[3];\n }\n if (descriptor.alignment != null) {\n control.alignment = this.alignments[descriptor.alignment];\n }\n control.alignmentY = this.alignments[descriptor.alignmentY || 0];\n control.alignmentX = this.alignments[descriptor.alignmentX || 0];\n control.zIndex = descriptor.zIndex || 0;\n control.order = descriptor.order || 0;\n control.chainOrder = ((ref22 = descriptor.chainOrder) != null ? ref22 : descriptor.zOrder) + ((parent != null ? parent.chainOrder : void 0) || 0);\n if (descriptor.zoom != null) {\n control.zoom = {\n x: descriptor.zoom[0] / 100,\n y: descriptor.zoom[1] / 100\n };\n }\n if (descriptor.visible != null) {\n control.visible = descriptor.visible;\n }\n if (descriptor.clipRect) {\n control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height);\n }\n if (descriptor.styles != null) {\n this.addControlStyles(control, descriptor.styles);\n }\n if (descriptor.template != null) {\n control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode);\n data = ui.Component_FormulaHandler.fieldValue(control, control.dataField);\n isNumber = typeof data === \"number\";\n if (data != null) {\n for (i = n = 0, ref23 = (ref24 = data.length) != null ? ref24 : data; 0 <= ref23 ? n < ref23 : n > ref23; i = 0 <= ref23 ? ++n : --n) {\n if ((data[i] != null) || isNumber) {\n valid = true;\n if ((descriptor.dataFilter != null) && !isNumber) {\n valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter);\n }\n if (valid || isNumber) {\n child = this.createControlFromDescriptor(descriptor.template, control, i);\n if ((ref25 = data[i]) != null ? ref25.dstRect : void 0) {\n child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect);\n }\n if ((child.clipRect == null) && (control.clipRect != null)) {\n child.clipRect = control.clipRect;\n }\n control.addObject(child);\n child.index = i;\n child.order = ((ref26 = data.length) != null ? ref26 : data) - i;\n control.controls.push(child);\n }\n }\n }\n }\n }\n if (descriptor.controls && descriptor.controls.exec) {\n controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls);\n } else {\n controls = descriptor.controls;\n }\n if (controls != null) {\n for (i = o = 0, len2 = controls.length; o < len2; i = ++o) {\n item = controls[i];\n childControl = this._createFromDescriptor(item, control, i);\n if ((childControl.clipRect == null) && (control.clipRect != null)) {\n childControl.clipRect = control.clipRect;\n }\n childControl.index = i;\n childControl.origin.x = control.origin.x + control.dstRect.x;\n childControl.origin.y = control.origin.y + control.dstRect.y;\n control.addObject(childControl);\n control.controls.push(childControl);\n }\n }\n if (control.styles && control.parentsByStyle) {\n parent = control.parent;\n while (parent) {\n if (parent.styles) {\n ref27 = parent.styles;\n for (p = 0, len3 = ref27.length; p < len3; p++) {\n style = ref27[p];\n if (!control.parentsByStyle[style.id]) {\n control.parentsByStyle[style.id] = [];\n }\n control.parentsByStyle[style.id].push(parent);\n }\n }\n parent = parent.parent;\n }\n }\n if (descriptor.animations != null) {\n control.animations = Object.deepCopy(descriptor.animations);\n control.animationExecutor = new ui.Component_AnimationExecutor();\n control.addComponent(control.animationExecutor);\n control.addComponent(new ui.Component_AnimationHandler());\n }\n control.ui.updateStyle();\n control.setup();\n return control;\n };\n\n\n /**\n * Creates an UI object from a specified UI descriptor.\n *\n * @method _createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n */\n\n UIManager.prototype._createFromDescriptor = function(descriptor, parent, index) {\n var control, controller;\n control = this.createControlFromDescriptor(descriptor, parent, index);\n if (descriptor.controller != null) {\n controller = this.controllers[descriptor.controller];\n control.controller = controller;\n control.addComponent(controller);\n }\n return control;\n };\n\n UIManager.prototype.createLayoutFromDescriptor = function(descriptor, parent, index) {\n return this._createFromDescriptor(descriptor, parent, index);\n };\n\n return UIManager;\n\n})();\n\nGraphics.width = $PARAMS.resolution.width;\n\nGraphics.height = $PARAMS.resolution.height;\n\nui.UiFactory = new UIManager();\n\nui.UIManager = ui.UiFactory;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7Ozs7OztFQVlhLGlCQUFDLENBQUQsRUFBSSxJQUFKLEVBQVUsS0FBVjs7QUFDVDs7Ozs7QUFBQSxRQUFBO0lBS0EsSUFBQyxDQUFBLFlBQUQsR0FBZ0I7O0FBRWhCOzs7OztJQUtBLElBQUMsQ0FBQSxLQUFELEdBQVM7O0FBRVQ7Ozs7O0lBS0EsSUFBQyxDQUFBLElBQUQsR0FBUTs7QUFFUjs7Ozs7SUFLQSxJQUFDLENBQUEsS0FBRCxHQUFTOztBQUVUOzs7Ozs7SUFNQSxJQUFDLENBQUEsT0FBRCxHQUFlLElBQUEsS0FBQSxDQUFNLEVBQU47QUFDZixTQUF5Qiw4RkFBekI7TUFBQSxJQUFDLENBQUEsT0FBUSxDQUFBLENBQUEsQ0FBVCxHQUFjO0FBQWQ7O0FBRUE7Ozs7OztJQU1BLElBQUMsQ0FBQSxPQUFELEdBQWUsSUFBQSxLQUFBLENBQU0sRUFBTjtBQUNmLFNBQTBCLG1HQUExQjtNQUFBLElBQUMsQ0FBQSxPQUFRLENBQUEsQ0FBQSxDQUFULEdBQWM7QUFBZDtFQTdDUzs7O0FBZ0RiOzs7OztvQkFJQSxJQUFBLEdBQU0sU0FBQTtBQUNILFFBQUE7SUFBQSxJQUFDLENBQUEsSUFBRCxHQUFRLElBQUMsQ0FBQTtJQUNULENBQUEsR0FBSSxJQUFDLENBQUEsS0FBSyxDQUFDLEtBQVAsQ0FBYSxJQUFiLEVBQW1CLFNBQW5CO0lBQ0osSUFBQyxDQUFBLFlBQUQsR0FBZ0I7QUFFaEIsV0FBTztFQUxKOzs7QUFPTjs7Ozs7Ozs7b0JBT0EsUUFBQSxHQUFVLFNBQUMsV0FBRDtBQUNOLFFBQUE7SUFBQSxNQUFBLEdBQVMsSUFBQyxDQUFBLE9BQVEsQ0FBQSxDQUFBLENBQVQsS0FBZTtJQUN4QixJQUFDLENBQUEsT0FBUSxDQUFBLENBQUEsQ0FBVCxHQUFjO0FBRWQsV0FBTztFQUpEOzs7QUFNVjs7Ozs7Ozs7b0JBT0Es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Q0FBeUIsSUFBQSxFQUFFLENBQUMsMEJBQUgsQ0FBQSxDQUF6QixFQUpKOztJQU1BLE9BQU8sQ0FBQyxFQUFFLENBQUMsV0FBWCxDQUFBO0lBQ0EsT0FBTyxDQUFDLEtBQVIsQ0FBQTtBQUVBLFdBQU87RUFsU2tCOzs7QUFvUzdCOzs7Ozs7Ozs7O3NCQVNBLHFCQUFBLEdBQXVCLFNBQUMsVUFBRCxFQUFhLE1BQWIsRUFBcUIsS0FBckI7QUFDbkIsUUFBQTtJQUFBLE9BQUEsR0FBVSxJQUFDLENBQUEsMkJBQUQsQ0FBNkIsVUFBN0IsRUFBeUMsTUFBekMsRUFBaUQsS0FBakQ7SUFFVixJQUFHLDZCQUFIO01BQ0ksVUFBQSxHQUFhLElBQUMsQ0FBQSxXQUFZLENBQUEsVUFBVSxDQUFDLFVBQVg7TUFDMUIsT0FBTyxDQUFDLFVBQVIsR0FBcUI7TUFDckIsT0FBTyxDQUFDLFlBQVIsQ0FBcUIsVUFBckIsRUFISjs7QUFLQSxXQUFPO0VBUlk7O3NCQVV2QiwwQkFBQSxHQUE0QixTQUFDLFVBQUQsRUFBYSxNQUFiLEVBQXFCLEtBQXJCO1dBQ3hCLElBQUMsQ0FBQSxxQkFBRCxDQUF1QixVQUF2QixFQUFtQyxNQUFuQyxFQUEyQyxLQUEzQztFQUR3Qjs7Ozs7O0FBS2hDLFFBQVEsQ0FBQyxLQUFULEdBQWlCLE9BQU8sQ0FBQyxVQUFVLENBQUM7O0FBQ3BDLFFBQVEsQ0FBQyxNQUFULEdBQWtCLE9BQU8sQ0FBQyxVQUFVLENBQUM7O0FBQ3JDLEVBQUUsQ0FBQyxTQUFILEdBQW1CLElBQUEsU0FBQSxDQUFBOztBQUNuQixFQUFFLENBQUMsU0FBSCxHQUFlLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuI1xuIyAgIFNjcmlwdDogVUlNYW5hZ2VyXG4jXG4jICAgJCRDT1BZUklHSFQkJFxuI1xuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNsYXNzIEZvcm11bGFcbiAgICAjIyMqXG4gICAgKiBFbmNhcHN1bGF0ZXMgYSBVSSBmb3JtdWxhLiBBIGZvcm11bGEgY2FuIGJlIHVzZWQgaW4gVUkgbGF5b3V0cyB0byBkZWZpbmVcbiAgICAqIHByb3BlcnR5LWJpbmRpbmdzIG9yIHRvIGltcGxlbWVudCBhIHNwZWNpZmljIGJlaGF2aW9yLlxuICAgICpcbiAgICAqIEBtb2R1bGUgdWlcbiAgICAqIEBjbGFzcyBGb3JtdWxhXG4gICAgKiBAbWVtYmVyb2YgdWlcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZiAtIFRoZSBmb3JtdWxhLWZ1bmN0aW9uLiBEZWZpbmVzIHRoZSBsb2dpYyBvZiB0aGUgZm9ybXVsYS5cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIC0gQW4gb3B0aW9uYWwgZGF0YS1vYmplY3Qgd2hpY2ggY2FuIGJlIGFjY2Vzc2VkIGluc2lkZSB0aGUgZm9ybXVsYS1mdW5jdGlvbi5cbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCAtIEFuIG9wdGlvbmFsIGV2ZW50LW5hbWUgdG8gZGVmaW5lIHdoZW4gdGhlIGZvcm11bGEgc2hvdWxkIGJlIGV4ZWN1dGVkLlxuICAgICMjI1xuICAgIGNvbnN0cnVjdG9yOiAoZiwgZGF0YSwgZXZlbnQpIC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBJbmRpY2F0ZXMgaWYgaXRzIHRoZSBmaXJzdCB0aW1lIHRoZSBmb3JtdWxhIGlzIGNhbGxlZC5cbiAgICAgICAgKiBAcHJvcGVydHkgb25Jbml0aWFsaXplXG4gICAgICAgICogQHR5cGUgYm9vbGVhblxuICAgICAgICAjIyNcbiAgICAgICAgQG9uSW5pdGlhbGl6ZSA9IHllc1xuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBmb3JtdWxhLWZ1bmN0aW9uLlxuICAgICAgICAqIEBwcm9wZXJ0eSBleGVjX1xuICAgICAgICAqIEB0eXBlIEZ1bmN0aW9uXG4gICAgICAgICMjI1xuICAgICAgICBAZXhlY18gPSBmXG4gICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFuIG9wdGlvbmFsIGRhdGEtb2JqZWN0IHdoaWNoIGNhbiBiZXMgYWNjZXNzZWQgaW5zaWRlIHRoZSBmb3JtdWxhLWZ1bmN0aW9uLlxuICAgICAgICAqIEBwcm9wZXJ0eSBkYXRhXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjIyAgIFxuICAgICAgICBAZGF0YSA9IGRhdGFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBBbiBvcHRpb25hbCBldmVudC1uYW1lIHRvIGRlZmluZSB3aGVuIHRoZSBmb3JtdWxhIHNob3VsZCBiZSBleGVjdXRlZC5cbiAgICAgICAgKiBAcHJvcGVydHkgZXZlbnRcbiAgICAgICAgKiBAdHlwZSBzdHJpbmdcbiAgICAgICAgIyMjIFxuICAgICAgICBAZXZlbnQgPSBldmVudFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFuIGFycmF5IG9mIGN1c3RvbSBudW1iZXItZGF0YSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgZGlmZmVyZW50IHB1cnBvc2VzLiBUaGUgZmlyc3QgZWxlbWVudFxuICAgICAgICAqIGlzIGFsc28gdXNlZCBpbiBvbkNoYW5nZSBtZXRob2QgdG8gc3RvcmUgdGhlIG9sZCB2YWx1ZSBhbmQgY2hlY2sgYWdhaW5zdCB0aGUgbmV3IG9uZSB0byBkZXRlY3QgYSBjaGFuZ2UuXG4gICAgICAgICogQHByb3BlcnR5IG51bWJlcnNcbiAgICAgICAgKiBAdHlwZSBudW1iZXJbXVxuICAgICAgICAjIyMgXG4gICAgICAgIEBudW1iZXJzID0gbmV3IEFycmF5KDEwKVxuICAgICAgICBAbnVtYmVyc1tpXSA9IDAgZm9yIGkgaW4gWzAuLkBudW1iZXJzLmxlbmd0aF1cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBBbiBhcnJheSBvZiBjdXN0b20gc3RyaW5nLWRhdGEgd2hpY2ggY2FuIGJlIHVzZWQgZm9yIGRpZmZlcmVudCBwdXJwb3Nlcy4gVGhlIGZpcnN0IGVsZW1lbnRcbiAgICAgICAgKiBpcyBhbHNvIHVzZWQgaW4gb25UZXh0Q2hhbmdlIG1ldGhvZCB0byBzdG9yZSB0aGUgb2xkIHZhbHVlIGFuZCBjaGVjayBhZ2FpbnN0IHRoZSBuZXcgb25lIHRvIGRldGVjdCBhIGNoYW5nZS5cbiAgICAgICAgKiBAcHJvcGVydHkgc3RyaW5nc1xuICAgICAgICAqIEB0eXBlIHN0cmluZ1tdXG4gICAgICAgICMjI1xuICAgICAgICBAc3RyaW5ncyA9IG5ldyBBcnJheSgxMClcbiAgICAgICAgQHN0cmluZ3NbaV0gPSBcIlwiIGZvciBpIGluIFswLi5Ac3RyaW5ncy5sZW5ndGhdXG4gICAgICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIFRoZSBmb3JtdWxhLWZ1bmN0aW9uLiBJdHMgYSB3cmFwcGVyLWZ1bmN0aW9uIGJlZm9yZSB0aGUgZmlyc3QtdGltZSBjYWxsIHdhcyBtYWRlLlxuICAgICogQG1ldGhvZCBleGVjXG4gICAgIyMjXG4gICAgZXhlYzogLT5cbiAgICAgICBAZXhlYyA9IEBleGVjX1xuICAgICAgIHIgPSBAZXhlY18uYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICAgICAgIEBvbkluaXRpYWxpemUgPSBub1xuICAgICAgIFxuICAgICAgIHJldHVybiByXG4gICAgICAgXG4gICAgIyMjKlxuICAgICogQ2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgbnVtYmVyLXZhbHVlIGhhcyBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IGNoZWNrLiBJdCB1c2VzXG4gICAgKiB0aGUgZmlyc3QgZW50cnkgb2YgdGhlIG51bWJlcnMtYXJyYXkgdG8gc3RvcmUgdGhlIHZhbHVlIGFuZCBjaGVjayBhZ2FpbnN0IHRoZSBuZXcgb25lLlxuICAgICpcbiAgICAqIEBtZXRob2Qgb25DaGFuZ2VcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJWYWx1ZSAtIE51bWJlciB2YWx1ZSB0byBjaGVjay5cbiAgICAjIyMgICAgXG4gICAgb25DaGFuZ2U6IChudW1iZXJWYWx1ZSkgLT5cbiAgICAgICAgcmVzdWx0ID0gQG51bWJlcnNbMF0gIT0gbnVtYmVyVmFsdWVcbiAgICAgICAgQG51bWJlcnNbMF0gPSBudW1iZXJWYWx1ZVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICBcbiAgICAjIyMqXG4gICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCB0ZXh0LXZhbHVlIGhhcyBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IGNoZWNrLiBJdCB1c2VzXG4gICAgKiB0aGUgZmlyc3QgZW50cnkgb2YgdGhlIHN0cmluZ3MtYXJyYXkgdG8gc3RvcmUgdGhlIHZhbHVlIGFuZCBjaGVjayBhZ2FpbnN0IHRoZSBuZXcgb25lLlxuICAgICpcbiAgICAqIEBtZXRob2Qgb25UZXh0Q2hhbmdlXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFZhbHVlIC0gVGV4dCB2YWx1ZSB0byBjaGVjay5cbiAgICAjIyMgICAgIFxuICAgIG9uVGV4dENoYW5nZTogKHRleHRWYWx1ZSkgLT5cbiAgICAgICAgcmVzdWx0ID0gQHN0cmluZ3NbMF0gIT0gdGV4dFZhbHVlXG4gICAgICAgIEBzdHJpbmdzWzBdID0gdGV4dFZhbHVlXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICAgIFxudWkuRm9ybXVsYSA9IEZvcm11bGFcblxuY2xhc3MgU3BhY2VcbiAgICAjIyMqXG4gICAgKiBEZXNjcmliZXMgYSBzcGFjZSBpbnNpZGUgb3IgYXJvdW5kIHNvbWV0aGluZyBsaWtlIGEgbWFyZ2luIG9yIHBhZGRpbmcuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIFNwYWNlXG4gICAgKiBAbWVtYmVyb2YgdWlcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtudW1iZXJ9IGxlZnQgLSBTcGFjZSBhdCB0aGUgbGVmdCBpbiBwaXhlbHMuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdG9wIC0gU3BhY2UgYXQgdGhlIHRvcCBpbiBwaXhlbHMuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gcmlnaHQgLSBTcGFjZSBhdCB0aGUgcmlnaHQgaW4gcGl4ZWxzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IGJvdHRvbSAtIFNwYWNlIGF0IHRoZSBib3R0b20gaW4gcGl4ZWxzLlxuICAgICMjI1xuICAgIGNvbnN0cnVjdG9yOiAobGVmdCwgdG9wLCByaWdodCwgYm90dG9tKSAtPlxuICAgICAgICAjIyMqXG4gICAgICAgICogU3BhY2UgYXQgdGhlIGxlZnQgaW4gcGl4ZWxzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBsZWZ0XG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAbGVmdCA9IGxlZnRcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgdG9wIGluIHBpeGVscy5cbiAgICAgICAgKiBAcHJvcGVydHkgdG9wXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAdG9wID0gdG9wXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3BhY2UgYXQgdGhlIHJpZ2h0IGluIHBpeGVscy5cbiAgICAgICAgKiBAcHJvcGVydHkgcmlnaHRcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEByaWdodCA9IHJpZ2h0XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3BhY2UgYXQgdGhlIGJvdHRvbSBpbiBwaXhlbHMuXG4gICAgICAgICogQHByb3BlcnR5IGJvdHRvbVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQGJvdHRvbSA9IGJvdHRvbVxuICAgICAgXG4gICAgIyMjKlxuICAgICogU2V0cyB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHNwYWNlIGJ5IGNvcHlpbmcgdGhlbSBmcm9tIGEgc3BlY2lmaWVkIHNwYWNlLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0RnJvbU9iamVjdFxuICAgICogQHBhcmFtIHtPYmplY3R9IHNwYWNlIC0gQSBzcGFjZSB0byBjb3B5LlxuICAgICMjIyAgIFxuICAgIHNldEZyb21PYmplY3Q6IChzcGFjZSkgLT5cbiAgICAgICAgQGxlZnQgPSBzcGFjZS5sZWZ0XG4gICAgICAgIEB0b3AgPSBzcGFjZS50b3BcbiAgICAgICAgQHJpZ2h0ID0gc3BhY2UucmlnaHRcbiAgICAgICAgQGJvdHRvbSA9IHNwYWNlLmJvdHRvbVxuICAgICAgXG4gICAgIyMjKlxuICAgICogU2V0cyB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHNwYWNlLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0XG4gICAgKiBAcGFyYW0ge251bWJlcn0gbGVmdCAtIFNwYWNlIGF0IHRoZSBsZWZ0IGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB0b3AgLSBTcGFjZSBhdCB0aGUgdG9wIGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByaWdodCAtIFNwYWNlIGF0IHRoZSByaWdodCBpbiBwaXhlbHMuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gYm90dG9tIC0gU3BhY2UgYXQgdGhlIGJvdHRvbSBpbiBwaXhlbHMuXG4gICAgIyMjICAgIFxuICAgIHNldDogKGxlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbSkgLT5cbiAgICAgICAgQGxlZnQgPSBsZWZ0XG4gICAgICAgIEB0b3AgPSB0b3BcbiAgICAgICAgQHJpZ2h0ID0gcmlnaHRcbiAgICAgICAgQGJvdHRvbSA9IGJvdHRvbVxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBuZXcgc3BhY2Ugb2JqZWN0IGZyb20gYW4gYXJyYXkgb2YgY29vcmRpbmF0ZXMuXG4gICAgKlxuICAgICogQG1ldGhvZCBmcm9tQXJyYXlcbiAgICAqIEBzdGF0aWNcbiAgICAqIEBwYXJhbSB7bnVtYmVyW119IGFycmF5IC0gQW4gYXJyYXkgb2YgY29vcmRpbmF0ZXMgKGxlZnQsIHRvcCByaWdodCwgYm90dG9tKS5cbiAgICAjIyMgICAgXG4gICAgQGZyb21BcnJheTogKGFycmF5KSAtPiBuZXcgdWkuU3BhY2UoYXJyYXlbMF0sIGFycmF5WzFdLCBhcnJheVsyXSwgYXJyYXlbM10pXG4gICAgICAgIFxudWkuU3BhY2UgPSBTcGFjZVxuXG5jbGFzcyBTdHlsZVxuICAgICMjIypcbiAgICAqIEEgVUkgc3R5bGUgY2FuIGFwcGxpZWQgdG8gYSBVSSBvYmplY3QgdG8gbW9kaWZ5IGl0IHByb3BlcnRpZXMgbGlrZSBjb2xvciwgaW1hZ2UsIGV0Yy4gdG8gZ2l2ZSBhIGNlcnRhaW4gXCJzdHlsZVwiIHRvIGl0LlxuICAgICpcbiAgICAqIEBtb2R1bGUgdWlcbiAgICAqIEBjbGFzcyBTdHlsZVxuICAgICogQG1lbWJlcm9mIHVpXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gQSBzdHlsZS1kZXNjcmlwdG9yIHRvIGluaXRpYWxpemUgdGhlIHN0eWxlIGZyb20uXG4gICAgKiBAcGFyYW0ge251bWJlcn0gaWQgLSBBIHVuaXF1ZSBudW1lcmljIElEIHRvIGFjY2VzcyB0aGUgc3R5bGUgdGhyb3VnaCBVSU1hbmFnZXIuc3R5bGVzQnlJZCBjb2xsZWN0aW9uLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHNlbGVjdG9yIC0gQSBzZWxlY3RvciBJRCB3aGljaCBjb250cm9scyB1bmRlciB3aGljaCBjb25kaXRpb25zIHRoZSBzdHlsZXMgd2lsbCBiZSBhcHBsaWVkLlxuICAgICMjI1xuICAgIGNvbnN0cnVjdG9yOiAoZGVzY3JpcHRvciwgaWQsIHNlbGVjdG9yKSAtPlxuICAgICAgICAjIyMqXG4gICAgICAgICogSUQgbnVtYmVyIHRvIHF1aWNrbHkgYWNjZXNzIHRoaXMgc3R5bGUgYW5kIGxpbmsgdG8gdGhpcyBzdHlsZS5cbiAgICAgICAgKiBAcHJvcGVydHkgaWRcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBpZCA9IGlkXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3R5bGUtSUQgb2YgdGFyZ2V0IG9iamVjdC4gVGhpcyBzdHlsZSB3aWxsIG9ubHkgYmUgYXBwbGllZCBvbiBVSSBvYmplY3RzIHdpdGggdGhhdCBzdHlsZSBJRCB3aGljaCBhcmVcbiAgICAgICAgKiBjaGlsZHJlbiBvZiBVSSBvYmplY3RzIHdoZXJlIHRoaXMgc3R5bGUgaXMgYXBwbGllZC5cbiAgICAgICAgKiBAcHJvcGVydHkgdGFyZ2V0XG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAdGFyZ2V0ID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTZWxlY3Rvci1JRCB3aGljaCBjb250cm9scyB1bmRlciB3aGljaCBjb25kaXRpb25zIHRoZSBzdHlsZSBiZWNvbWVzIGFjdGl2ZS5cbiAgICAgICAgKiBAcHJvcGVydHkgc2VsZWN0b3JcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBzZWxlY3RvciA9IHNlbGVjdG9yXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGZvbnQgdXNlZCBmb3IgdGhlIHRleHQtZGlzcGxheS5cbiAgICAgICAgKiBAZGVmYXVsdCBudWxsXG4gICAgICAgICogQHByb3BlcnR5IGZvbnRcbiAgICAgICAgKiBAdHlwZSBncy5Gb250XG4gICAgICAgICMjI1xuICAgICAgICBAZm9udCA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgaW1hZ2UgdXNlZCBmb3IgdmlzdWFsIHByZXNlbnRhdGlvbi5cbiAgICAgICAgKiBAcHJvcGVydHkgaW1hZ2VcbiAgICAgICAgKiBAdHlwZSBzdHJpbmdcbiAgICAgICAgIyMjXG4gICAgICAgIEBpbWFnZSA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgYW5pbWF0aW9ucyB1c2VkIGZvciB2aXN1YWwgcHJlc2VudGF0aW9uLlxuICAgICAgICAqIEBkZWZhdWx0IG51bGxcbiAgICAgICAgKiBAcHJvcGVydHkgYW5pbWF0aW9uc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFtdXG4gICAgICAgICMjI1xuICAgICAgICBAYW5pbWF0aW9ucyA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgY29sb3IuXG4gICAgICAgICogQHByb3BlcnR5IGNvbG9yXG4gICAgICAgICogQHR5cGUgZ3MuQ29sb3JcbiAgICAgICAgIyMjXG4gICAgICAgIEBjb2xvciA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgYW5jaG9yLXBvaW50LiBGb3IgZXhhbXBsZTogQW4gYW5jaG9yLXBvaW50IHdpdGggMCwwIHBsYWNlcyB0aGUgb2JqZWN0IHdpdGggaXRzIHRvcC1sZWZ0IGNvcm5lclxuICAgICAgICAqIGF0IGl0cyBwb3NpdGlvbiBidXQgd2l0aCBhbiAwLjUsIDAuNSBhbmNob3ItcG9pbnQgdGhlIG9iamVjdCBpcyBwbGFjZWQgd2l0aCBpdHMgY2VudGVyLiBBbiBhbmNob3ItcG9pbnQgb2YgMSwxXG4gICAgICAgICogcGxhY2VzIHRoZSBvYmplY3Qgd2l0aCBpdHMgbG93ZXItcmlnaHQgY29ybmVyLlxuICAgICAgICAqIEBwcm9wZXJ0eSBhbmNob3JcbiAgICAgICAgKiBAdHlwZSBncy5Qb2ludFxuICAgICAgICAjIyNcbiAgICAgICAgQGFuY2hvciA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3Mgem9vbS1zZXR0aW5nIGZvciB4IGFuZCB5IGF4aXMuXG4gICAgICAgICogQGRlZmF1bHQgbmV3IGdzLlBvaW50KDEuMCwgMS4wKVxuICAgICAgICAqIEBwcm9wZXJ0eSB6b29tXG4gICAgICAgICogQHR5cGUgZ3MuUG9pbnRcbiAgICAgICAgIyMjXG4gICAgICAgIEB6b29tID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBtYXJnaW4uIFRoZSBtYXJnaW4gZGVmaW5lcyBhbiBleHRyYSBzcGFjZSBhcm91bmQgdGhlIFVJIG9iamVjdC4gXG4gICAgICAgICogVGhlIGRlZmF1bHQgaXMgeyBsZWZ0OiAwLCB0b3A6IDAsIHJpZ2h0OiAwLCBib3R0b206IDAgfS5cbiAgICAgICAgKiBAcHJvcGVydHkgbWFyZ2luXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAbWFyZ2luID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBwYWRkaW5nLiBUaGUgZGVmYXVsdCBpcyB7IGxlZnQ6IDAsIHRvcDogMCwgcmlnaHQ6IDAsIGJvdHRvbTogMCB9LlxuICAgICAgICAqIEBwcm9wZXJ0eSBwYWRkaW5nXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAcGFkZGluZyA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgbWFzayBmb3IgbWFza2luZy1lZmZlY3RzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBtYXNrXG4gICAgICAgICogQHR5cGUgZ3MuTWFza1xuICAgICAgICAjIyNcbiAgICAgICAgQG1hc2sgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIGFsaWdubWVudC5cbiAgICAgICAgKiBAcHJvcGVydHkgYWxpZ25tZW50XG4gICAgICAgICogQHR5cGUgdWkuQWxpZ25tZW50XG4gICAgICAgICMjI1xuICAgICAgICBAYWxpZ25tZW50ID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3Mgb3BhY2l0eSB0byBjb250cm9sIHRyYW5zcGFyZW5jeS4gRm9yIGV4YW1wbGU6IDAgPSBUcmFuc3BhcmVudCwgMjU1ID0gT3BhcXVlLCAxMjggPSBTZW1pLVRyYW5zcGFyZW50LlxuICAgICAgICAqIEBwcm9wZXJ0eSBvcGFjaXR5XG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAb3BhY2l0eSA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIG9iamVjdCdzIGNsaXAtcmVjdCBmb3IgdmlzdWFsIHByZXNlbnRhdGlvbi5cbiAgICAgICAgKiBAZGVmYXVsdCBudWxsXG4gICAgICAgICogQHByb3BlcnR5IGNsaXBSZWN0XG4gICAgICAgICogQHR5cGUgZ3MuUmVjdFxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjXG4gICAgICAgIEBjbGlwUmVjdCA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgY29ybmVyLXNpemUgb2YgdGhlIGZyYW1lLlxuICAgICAgICAqIEBwcm9wZXJ0eSBmcmFtZUNvcm5lclNpemVcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBmcmFtZUNvcm5lclNpemUgPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSB0aGlja25lc3Mgb2YgdGhlIGZyYW1lLlxuICAgICAgICAqIEBwcm9wZXJ0eSBmcmFtZVRoaWNrbmVzc1xuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQGZyYW1lVGhpY2tuZXNzID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgbG9vcGluZyBvZiB0aGUgaW1hZ2UuXG4gICAgICAgICogQHByb3BlcnR5IGxvb3BpbmdcbiAgICAgICAgKiBAdHlwZSB1aS5PcmllbnRhdGlvblxuICAgICAgICAjIyNcbiAgICAgICAgQGxvb3BpbmcgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIG9iamVjdCdzIHotaW5kZXggY29udHJvbHMgcmVuZGVyaW5nLW9yZGVyL2ltYWdlLW92ZXJsYXBwaW5nLiBBbiBvYmplY3Qgd2l0aCBhIHNtYWxsZXIgei1pbmRleCBpcyByZW5kZXJlZFxuICAgICAgICAqIGJlZm9yZSBhbiBvYmplY3Qgd2l0aCBhIGxhcmdlciBpbmRleC4gRm9yIGV4YW1wbGU6IFRvIG1ha2Ugc3VyZSBhIGdhbWUgb2JqZWN0IGlzIGFsd2F5cyBvbiB0b3Agb2YgdGhlIHNjcmVlbiwgaXRcbiAgICAgICAgKiBzaG91bGQgaGF2ZSB0aGUgbGFyZ2VzdCB6LWluZGV4IG9mIGFsbCBnYW1lIG9iamVjdHMuXG4gICAgICAgICogQHByb3BlcnR5IHpJbmRleFxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQHpJbmRleCA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIG9iamVjdCdzIGFsaWdubWVudCBvbiB4LWF4aXMuIE5lZWRzIHRvIGJlIHN1cHBvcnRlZCBieSBsYXlvdXQuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudFhcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBhbGlnbm1lbnRYID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgb2JqZWN0J3MgYWxpZ25tZW50IG9uIHktYXhpcy4gTmVlZHMgdG8gYmUgc3VwcG9ydGVkIGJ5IGxheW91dC5cbiAgICAgICAgKiBAcHJvcGVydHkgYWxpZ25tZW50WVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQGFsaWdubWVudFkgPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyByZXNpemUgYmVoYXZpb3IuXG4gICAgICAgICogQHByb3BlcnR5IHJlc2l6YWJsZVxuICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgIyMjXG4gICAgICAgIEByZXNpemFibGUgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIG9yaWdpbmFsIHN0eWxlIGRlc2NyaXB0b3IuXG4gICAgICAgICogQHByb3BlcnR5IGRlc2NyaXB0b3JcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBkZXNjcmlwdG9yID0gZGVzY3JpcHRvclxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvclxuICAgICAgICAgICAgQHNldEZyb21EZXNjcmlwdG9yKGRlc2NyaXB0b3IpXG5cbiAgICAjIyMqXG4gICAgKiBJbml0aWFsaXplcyB0aGUgc3R5bGUgZnJvbSBhIHN0eWxlLWRlc2NyaXB0b3IuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXRGcm9tRGVzY3JpcHRvclxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgc3R5bGUtZGVzY3JpcHRvci5cbiAgICAjIyMgXG4gICAgc2V0RnJvbURlc2NyaXB0b3I6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBAZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JcbiAgICAgICAgQGltYWdlID0gZGVzY3JpcHRvci5pbWFnZVxuICAgICAgICBAY29sb3IgPSBncy5Db2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcikgaWYgZGVzY3JpcHRvci5jb2xvclxuICAgICAgICBAYW5jaG9yID0gbmV3IGdzLlBvaW50KGRlc2NyaXB0b3IuYW5jaG9yWzBdLCBkZXNjcmlwdG9yLmFuY2hvclsxXSkgaWYgZGVzY3JpcHRvci5hbmNob3JcbiAgICAgICAgQHpvb20gPSBuZXcgZ3MuUG9pbnQoZGVzY3JpcHRvci56b29tWzBdLCBkZXNjcmlwdG9yLnpvb21bMV0pIGlmIGRlc2NyaXB0b3Iuem9vbVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb250XG4gICAgICAgICAgICBAc2V0dXBGb250KGRlc2NyaXB0b3IpXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jbGlwUmVjdFxuICAgICAgICAgICAgQGNsaXBSZWN0ID0gZ3MuUmVjdC5mcm9tQXJyYXkoZGVzY3JpcHRvci5jbGlwUmVjdClcbiAgICAgICAgICAgIFxuICAgICAgICBAb3BhY2l0eSA9IGRlc2NyaXB0b3Iub3BhY2l0eSBpZiBkZXNjcmlwdG9yLm9wYWNpdHkgPj0gMFxuICAgICAgICBAYWxpZ25tZW50ID0gZGVzY3JpcHRvci5hbGlnbm1lbnQgaWYgZGVzY3JpcHRvci5hbGlnbm1lbnQgPj0gMFxuICAgICAgICBAbWFyZ2luID0gdWkuU3BhY2UuZnJvbUFycmF5KGRlc2NyaXB0b3IubWFyZ2luKSBpZiBkZXNjcmlwdG9yLm1hcmdpblxuICAgICAgICBAcGFkZGluZyA9IHVpLlNwYWNlLmZyb21BcnJheShkZXNjcmlwdG9yLnBhZGRpbmcpIGlmIGRlc2NyaXB0b3IucGFkZGluZ1xuICAgICAgICBAYW5pbWF0aW9ucyA9IGRlc2NyaXB0b3IuYW5pbWF0aW9uc1xuICAgICAgICBAZnJhbWVDb3JuZXJTaXplID0gZGVzY3JpcHRvci5mcmFtZUNvcm5lclNpemUgaWYgZGVzY3JpcHRvci5mcmFtZUNvcm5lclNpemVcbiAgICAgICAgQGZyYW1lVGhpY2tuZXNzID0gZGVzY3JpcHRvci5mcmFtZVRoaWNrbmVzcyBpZiBkZXNjcmlwdG9yLmZyYW1lVGhpY2tuZXNzXG4gICAgICAgIEBmcmFtZSA9IGRlc2NyaXB0b3IuZnJhbWUgaWYgZGVzY3JpcHRvci5mcmFtZVxuICAgICAgICBAbG9vcGluZyA9IGRlc2NyaXB0b3IubG9vcGluZyBpZiBkZXNjcmlwdG9yLmxvb3BpbmdcbiAgICAgICAgQHJlc2l6YWJsZSA9IGRlc2NyaXB0b3IucmVzaXphYmxlIGlmIGRlc2NyaXB0b3IucmVzaXphYmxlP1xuICAgICAgICBAekluZGV4ID0gZGVzY3JpcHRvci56SW5kZXggaWYgZGVzY3JpcHRvci56SW5kZXhcbiAgICAgICAgQGFsaWdubWVudFggPSB1aS5VSU1hbmFnZXIuYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudFhdIGlmIGRlc2NyaXB0b3IuYWxpZ25tZW50WFxuICAgICAgICBAYWxpZ25tZW50WSA9IHVpLlVJTWFuYWdlci5hbGlnbm1lbnRzW2Rlc2NyaXB0b3IuYWxpZ25tZW50WV0gaWYgZGVzY3JpcHRvci5hbGlnbm1lbnRZXG4gICAgICAgIFxuICAgIHNldDogKHN0eWxlKSAtPlxuICAgICAgICBAaW1hZ2UgPSBzdHlsZS5pbWFnZVxuICAgICAgICBAY29sb3Iuc2V0RnJvbU9iamVjdChzdHlsZS5jb2xvcilcbiAgICAgICAgQGFuY2hvci5zZXQoc3R5bGUuYW5jaG9yLngsIHN0eWxlLmFuY2hvci55KVxuICAgICAgICBAem9vbS5zZXQoc3R5bGUuem9vbS54LCBzdHlsZS56b29tLnkpXG4gICAgICAgIFxuICAgICAgICBpZiBzdHlsZS5mb250XG4gICAgICAgICAgICBpZiAhQGZvbnQgdGhlbiBAZm9udCA9IG5ldyBncy5Gb250KHN0eWxlLmZvbnQubmFtZSwgc3R5bGUuZm9udC5zaXplKVxuICAgICAgICAgICAgQGZvbnQuc2V0KHN0eWxlLmZvbnQpXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgc3R5bGUuY2xpcFJlY3RcbiAgICAgICAgICAgIGlmICFAY2xpcFJlY3QgdGhlbiBAY2xpcFJlY3QgPSBuZXcgZ3MuUmVjdCgpXG4gICAgICAgICAgICBAY2xpcFJlY3Quc2V0RnJvbU9iamVjdChzdHlsZS5jbGlwUmVjdClcbiAgICAgICAgICAgIFxuICAgICAgICBAb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHpcbiAgICAgICAgQGFsaWdubWVudCA9IHN0eWxlLmFsaWdubWVudFxuICAgICAgICBAbWFyZ2luLnNldEZyb21PYmplY3Qoc3R5bGUubWFyZ2luKVxuICAgICAgICBAcGFkZGluZy5zZXRGcm9tT2JqZWN0KHN0eWxlLnBhZGRpbmcpXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIEluaXRpYWxpemVzIGZvbnQtZGF0YSBmcm9tIGEgc3R5bGUtZGVzY3JpcHRvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldHVwRm9udFxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgc3R5bGUtZGVzY3JpcHRvci5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgXG4gICAgc2V0dXBGb250OiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb250XG4gICAgICAgICAgICBpZiAhQGZvbnRcbiAgICAgICAgICAgICAgICBAZm9udCA9IG5ldyBGb250KGRlc2NyaXB0b3IuZm9udC5uYW1lLCBkZXNjcmlwdG9yLmZvbnQuc2l6ZSA/IDApXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgQGZvbnQubmFtZSA9IGRlc2NyaXB0b3IuZm9udC5uYW1lXG4gICAgICAgICAgICAgICAgQGZvbnQuc2l6ZSA9IGRlc2NyaXB0b3IuZm9udC5zaXplID8gMFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgQGZvbnQuYm9sZCA9IGRlc2NyaXB0b3IuZm9udC5ib2xkID8gQGZvbnQuYm9sZFxuICAgICAgICAgICAgQGZvbnQuaXRhbGljID0gZGVzY3JpcHRvci5mb250Lml0YWxpYyA/IEBmb250Lml0YWxpY1xuICAgICAgICAgICAgQGZvbnQuc21hbGxDYXBzID0gZGVzY3JpcHRvci5mb250LnNtYWxsQ2FwcyA/IEBmb250LnNtYWxsQ2Fwc1xuICAgICAgICAgICAgQGZvbnQudW5kZXJsaW5lID0gZGVzY3JpcHRvci5mb250LnVuZGVybGluZSA/IEBmb250LnVuZGVybGluZVxuICAgICAgICAgICAgQGZvbnQuc3RyaWtlVGhyb3VnaCA9IGRlc2NyaXB0b3IuZm9udC5zdHJpa2VUaHJvdWdoID8gQGZvbnQuc3RyaWtlVGhyb3VnaFxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQuY29sb3I/XG4gICAgICAgICAgICAgICAgQGZvbnQuY29sb3Iuc2V0RnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5jb2xvcilcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mb250LmJvcmRlcj9cbiAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXIgPSBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyID8gbm9cbiAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJTaXplID0gZGVzY3JpcHRvci5mb250LmJvcmRlclNpemUgPyA0XG4gICAgICAgICAgICAgICAgQGZvbnQuYm9yZGVyQ29sb3Iuc2V0KDAsIDAsIDAsIDI1NSlcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lP1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlciA9IGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lID8gbm9cbiAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJTaXplID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUuc2l6ZSA/IDRcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQub3V0bGluZS5jb2xvcj9cbiAgICAgICAgICAgICAgICAgICAgQGZvbnQuYm9yZGVyQ29sb3Iuc2V0RnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lLmNvbG9yKVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgQGZvbnQuYm9yZGVyQ29sb3Iuc2V0KDAsIDAsIDAsIDI1NSlcbiAgICBcbiAgICAjIyMqXG4gICAgKiBBcHBsaWVzIHRoZSBzdHlsZSB0byBhIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFwcGx5XG4gICAgKiBAcGFyYW0ge3VpLk9iamVjdF9VSUVsZW1lbnR9IG9iamVjdCAtIFRoZSBVSSBvYmplY3Qgd2hlcmUgdGhlIHN0eWxlIHNob3VsZCBiZSBhcHBsaWVkIHRvLlxuICAgICMjIyAgICAgICAgICAgICAgICBcbiAgICBhcHBseTogKG9iamVjdCkgLT5cbiAgICAgICAgaWYgbm90IG9iamVjdC5hY3RpdmVTdHlsZXMuY29udGFpbnModGhpcylcbiAgICAgICAgICAgIG9iamVjdC5hY3RpdmVTdHlsZXMucHVzaCh0aGlzKVxuICAgICAgICAgICAgaWYgQGZvbnQgdGhlbiBvYmplY3QuZm9udD8uc2V0KEBmb250KVxuICAgICAgICAgICAgaWYgQGNvbG9yIHRoZW4gb2JqZWN0LmNvbG9yLnNldChAY29sb3IpXG4gICAgICAgICAgICBpZiBAaW1hZ2UgdGhlbiBvYmplY3QuaW1hZ2UgPSBAaW1hZ2VcbiAgICAgICAgICAgIGlmIEBhbmNob3IgdGhlbiBvYmplY3QuYW5jaG9yLnNldChAYW5jaG9yLngsIEBhbmNob3IueSlcbiAgICAgICAgICAgIGlmIEB6b29tIHRoZW4gb2JqZWN0Lnpvb20uc2V0KEB6b29tLngsIEB6b29tLnkpXG4gICAgICAgICAgICBpZiBAcGFkZGluZyB0aGVuIG9iamVjdC5wYWRkaW5nLnNldEZyb21PYmplY3QoQHBhZGRpbmcpXG4gICAgICAgICAgICBpZiBAbWFyZ2luIHRoZW4gb2JqZWN0Lm1hcmdpbi5zZXRGcm9tT2JqZWN0KEBtYXJnaW4pXG4gICAgICAgICAgICBpZiBAb3BhY2l0eSA+PSAwIHRoZW4gb2JqZWN0Lm9wYWNpdHkgPSBAb3BhY2l0eVxuICAgICAgICAgICAgaWYgQGFsaWdubWVudCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudCA9IEBhbGlnbm1lbnRcbiAgICAgICAgICAgIGlmIEBmcmFtZVRoaWNrbmVzcyA+PSAwIHRoZW4gb2JqZWN0LmZyYW1lVGhpY2tuZXNzID0gQGZyYW1lVGhpY2tuZXNzXG4gICAgICAgICAgICBpZiBAZnJhbWVDb3JuZXJTaXplID49IDAgdGhlbiBvYmplY3QuZnJhbWVDb3JuZXJTaXplID0gQGZyYW1lQ29ybmVyU2l6ZVxuICAgICAgICAgICAgaWYgQG1hc2sgdGhlbiBvYmplY3QubWFzay5zZXQoQG1hc2spXG4gICAgICAgICAgICBpZiBAekluZGV4ID49IDAgdGhlbiBvYmplY3QuekluZGV4ID0gQHpJbmRleFxuICAgICAgICAgICAgaWYgQGFsaWdubWVudFggPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRYID0gQGFsaWdubWVudFhcbiAgICAgICAgICAgIGlmIEBhbGlnbm1lbnRZID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50WSA9IEBhbGlnbm1lbnRZXG4gICAgICAgICAgICBpZiBAcmVzaXphYmxlPyB0aGVuIG9iamVjdC5yZXNpemFibGUgPSBAcmVzaXphYmxlXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEBhcHBseUxvb3Bpbmcob2JqZWN0KVxuICAgICAgICAgICAgQGFwcGx5QW5pbWF0aW9ucyhvYmplY3QpXG4gICAgIFxuICAgICMjIypcbiAgICAqIEFwcGxpZXMgdGhlIGxvb3BpbmctZGF0YSBvZiB0aGUgc3R5bGUgdG8gYSBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBhcHBseUxvb3BpbmdcbiAgICAqIEBwYXJhbSB7dWkuT2JqZWN0X1VJRWxlbWVudH0gb2JqZWN0IC0gVGhlIFVJIG9iamVjdCB3aGVyZSB0aGUgbG9vcGluZy1kYXRhIHNob3VsZCBiZSBhcHBsaWVkIHRvLlxuICAgICogQHByb3RlY3RlZFxuICAgICMjIyAgICAgXG4gICAgYXBwbHlMb29waW5nOiAob2JqZWN0KSAtPlxuICAgICAgICBpZiBAbG9vcGluZ1xuICAgICAgICAgICAgaWYgIW9iamVjdC52aXN1YWwubG9vcGluZ1xuICAgICAgICAgICAgICAgIG9iamVjdC52aXN1YWwuZGlzcG9zZSgpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnJlbW92ZUNvbXBvbmVudChvYmplY3QudmlzdWFsKVxuICAgICAgICAgICAgICAgIG9iamVjdC52aXN1YWwgPSBuZXcgZ3MuQ29tcG9uZW50X1RpbGluZ1Nwcml0ZSgpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmFkZENvbXBvbmVudChvYmplY3QudmlzdWFsKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBAbG9vcGluZy52ZXJ0aWNhbFxuICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5sb29waW5nLmhvcml6b250YWwgPSBAbG9vcGluZy5ob3Jpem9udGFsXG4gICAgIFxuICAgICMjIypcbiAgICAqIEFwcGxpZXMgdGhlIGFuaW1hdGlvbi1kYXRhIG9mIHRoZSBzdHlsZSB0byBhIFVJIG9iamVjdC4gVGhpcyBhdXRvbWF0aWNhbGx5IGFkZHMgYW4gYW5pbWF0aW9uLWhhbmRsZXJcbiAgICAqIGNvbXBvbmVudCh1aS5Db21wb25lbnRfQW5pbWF0aW9uSGFuZGxlcikgd2l0aCB0aGUgaWQgXCJhbmltYXRpb25IYW5kbGVyXCIgdG8gdGhlIFVJIG9iamVjdCBpZiBub3QgYWxyZWFkeSBleGlzdHMuXG4gICAgKlxuICAgICogQG1ldGhvZCBhcHBseUFuaW1hdGlvbnNcbiAgICAqIEBwYXJhbSB7dWkuT2JqZWN0X1VJRWxlbWVudH0gb2JqZWN0IC0gVGhlIFVJIG9iamVjdCB3aGVyZSB0aGUgYW5pbWF0aW9uLWRhdGEgc2hvdWxkIGJlIGFwcGxpZWQgdG8uXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICAgICBcbiAgICBhcHBseUFuaW1hdGlvbnM6IChvYmplY3QpIC0+XG4gICAgICAgIGlmIEBhbmltYXRpb25zXG4gICAgICAgICAgICBvYmplY3QuYW5pbWF0aW9ucyA9IE9iamVjdC5kZWVwQ29weShAYW5pbWF0aW9ucylcbiAgICAgICAgICAgIGlmICFvYmplY3QuZmluZENvbXBvbmVudEJ5SWQoXCJhbmltYXRpb25IYW5kbGVyXCIpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmFuaW1hdGlvbkV4ZWN1dG9yID0gbmV3IHVpLkNvbXBvbmVudF9BbmltYXRpb25FeGVjdXRvcigpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmFkZENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkhhbmRsZXIoKSwgXCJhbmltYXRpb25IYW5kbGVyXCIpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmFkZENvbXBvbmVudChvYmplY3QuYW5pbWF0aW9uRXhlY3V0b3IsIFwiYW5pbWF0aW9uRXhlY3V0b3JcIilcbiAgICAgICAgICAgICAgICBcbiAgICAgIFxuICAgICMjIypcbiAgICAqIFJldmVydHMgdGhlIGNoYW5nZXMgZnJvbSBhIFVJIG9iamVjdCBtYWRlIGJ5IHRoaXMgc3R5bGUuIEhvd2V2ZXIsIHRoaXMgcmVzZXRzIGFsbCBzdHlsZWFibGUgcHJvcGVydGllc1xuICAgICogd2VyZSBzZXQgYnkgdGhpcyBzdHlsZS4gU28gaXQgaXMgbmVjZXNzYXJ5IHRvIGFwcGx5IGFsbCBvdGhlciBzdHlsZXMgYWdhaW4sIGJ1dCB0aGF0IGlzIGFscmVhZHkgaGFuZGxlcyBpblxuICAgICogdWkuQ29tcG9uZW50X1VJQmVoYXZpb3IuXG4gICAgKlxuICAgICogQG1ldGhvZCByZXZlcnRcbiAgICAqIEBwYXJhbSB7dWkuT2JqZWN0X1VJRWxlbWVudH0gb2JqZWN0IC0gVGhlIFVJIG9iamVjdCB3aGVyZSB0aGUgc3R5bGUgc2hvdWxkIGJlIHJldmVydGVkLlxuICAgICMjIyAgICAgICAgICAgICBcbiAgICByZXZlcnQ6IChvYmplY3QpIC0+XG4gICAgICAgIGFjdGl2ZVN0eWxlcyA9IG9iamVjdC5hY3RpdmVTdHlsZXNcbiAgICAgICAgaWYgb2JqZWN0LmFjdGl2ZVN0eWxlcy5jb250YWlucyh0aGlzKVxuICAgICAgICAgICAgb2JqZWN0LmFjdGl2ZVN0eWxlcy5yZW1vdmUodGhpcylcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgQGZvbnQgdGhlbiBvYmplY3QuZm9udC5zZXQoZ3MuRm9udHMuVEVYVCk7ICAgICAgICAgICAgICAgKGlmIHMuZm9udCB0aGVuIG9iamVjdC5mb250LnNldChzLmZvbnQpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAY29sb3IgdGhlbiBvYmplY3QuY29sb3Iuc2V0KENvbG9yLldISVRFKTsgICAgICAgICAgICAgICAoaWYgcy5jb2xvciB0aGVuIG9iamVjdC5jb2xvci5zZXQocy5jb2xvcik7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBpbWFnZSB0aGVuIG9iamVjdC5pbWFnZSA9IG51bGw7ICAgICAgICAgICAgICAgICAgICAgICAgIChpZiBzLmltYWdlIHRoZW4gb2JqZWN0LmltYWdlID0gcy5pbWFnZTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGFuY2hvciB0aGVuIG9iamVjdC5hbmNob3Iuc2V0KDAsIDApOyAgICAgICAgICAgICAgICAgICAgKGlmIHMuYW5jaG9yIHRoZW4gb2JqZWN0LmFuY2hvci5zZXRGcm9tT2JqZWN0KHMuYW5jaG9yKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQHpvb20gdGhlbiBvYmplY3Quem9vbS5zZXQoMS4wLCAxLjApOyAgICAgICAgICAgICAgICAgICAgKGlmIHMuem9vbSB0aGVuIG9iamVjdC56b29tLnNldEZyb21PYmplY3Qocy56b29tKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQHBhZGRpbmcgdGhlbiBvYmplY3QucGFkZGluZy5zZXQoMCwgMCwgMCwgMCk7ICAgICAgICAgICAgKGlmIHMucGFkZGluZyB0aGVuIG9iamVjdC5wYWRkaW5nLnNldEZyb21PYmplY3Qocy5wYWRkaW5nKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQG1hcmdpbiB0aGVuIG9iamVjdC5tYXJnaW4uc2V0KDAsIDAsIDAsIDApOyAgICAgICAgICAgICAgKGlmIHMubWFyZ2luIHRoZW4gb2JqZWN0Lm1hcmdpbi5zZXRGcm9tT2JqZWN0KHMubWFyZ2luKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQG9wYWNpdHkgPj0gMCB0aGVuIG9iamVjdC5vcGFjaXR5ID0gMjU1OyAgICAgICAgICAgICAgICAgKGlmIHMub3BhY2l0eSA+PSAwIHRoZW4gb2JqZWN0Lm9wYWNpdHkgPSBzLm9wYWNpdHk7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBhbGlnbm1lbnQgPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnQgPSAwOyAgICAgICAgICAgICAgIChpZiBzLmFsaWdubWVudCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudCA9IHMuYWxpZ25tZW50OyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAZnJhbWVDb3JuZXJTaXplID49IDAgdGhlbiBvYmplY3QuZnJhbWVDb3JuZXJTaXplID0gMTY7ICAoaWYgcy5mcmFtZUNvcm5lclNpemUgPj0gMCB0aGVuIG9iamVjdC5mcmFtZUNvcm5lclNpemUgPSBzLmZyYW1lQ29ybmVyU2l6ZTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGZyYW1lVGhpY2tuZXNzID49IDAgdGhlbiBvYmplY3QuZnJhbWVUaGlja25lc3MgPSAxNjsgICAgKGlmIHMuZnJhbWVUaGlja25lc3MgPj0gMCB0aGVuIG9iamVjdC5mcmFtZVRoaWNrbmVzcyA9IHMuZnJhbWVUaGlja25lc3M7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBtYXNrIHRoZW4gb2JqZWN0Lm1hc2suc2V0KG51bGwpOyAgICAgICAgICAgICAgICAgICAgICAgIChpZiBzLm1hc2sgdGhlbiBvYmplY3QubWFzay5zZXQocy5mb250KTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQHpJbmRleCA+PSAwIHRoZW4gb2JqZWN0LnpJbmRleCA9IDA7ICAgICAgICAgICAgICAgICAgICAgKGlmIHMuekluZGV4ID49IDAgdGhlbiBvYmplY3QuekluZGV4ID0gcy56SW5kZXg7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBhbGlnbm1lbnRYID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50WCA9IDA7ICAgICAgICAgICAgIChpZiBzLmFsaWdubWVudFggPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRYID0gcy5hbGlnbm1lbnRYOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAYWxpZ25tZW50WSA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudFkgPSAwOyAgICAgICAgICAgICAoaWYgcy5hbGlnbm1lbnRZID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50WSA9IHMuYWxpZ25tZW50WTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQHJlc2l6YWJsZT8gdGhlbiBvYmplY3QucmVzaXphYmxlID0gbm87ICAgICAgICAgICAgICAgICAgKGlmIHMucmVzaXphYmxlPyB0aGVuIG9iamVjdC5yZXNpemFibGUgPSBzLnJlc2l6YWJsZTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBAcmV2ZXJ0QW5pbWF0aW9ucyhvYmplY3QpXG4gICAgICAgICAgICBAcmV2ZXJ0TG9vcGluZyhvYmplY3QpXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICMjIypcbiAgICAqIFJldmVydHMgdGhlIGFuaW1hdGlvbi1kYXRhIGNoYW5nZXMgYXBwbGllZCB0byBhIFVJIG9iamVjdCBieSB0aGlzIHN0eWxlLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmV2ZXJ0QW5pbWF0aW9uc1xuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBhbmltYXRpb24tZGF0YSBjaGFuZ2VzIHNob3VsZCBiZSByZXZlcnRlZC5cbiAgICAjIyMgICAgICAgICAgICAgICAgIFxuICAgIHJldmVydEFuaW1hdGlvbnM6IChvYmplY3QpIC0+XG4gICAgICAgIGFjdGl2ZVN0eWxlcyA9IG9iamVjdC5hY3RpdmVTdHlsZXNcbiAgICAgICAgaWYgQGFuaW1hdGlvbnNcbiAgICAgICAgICAgIG9iamVjdC5hbmltYXRpb25zID0gbnVsbDsgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgICAgIGlmIHMuYW5pbWF0aW9uc1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuYW5pbWF0aW9ucyA9IE9iamVjdC5kZWVwQ29weShzLmFuaW1hdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgIGlmICFvYmplY3QuZmluZENvbXBvbmVudEJ5SWQoXCJhbmltYXRpb25IYW5kbGVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQW5pbWF0aW9uSGFuZGxlcigpLCBcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogUmV2ZXJ0cyB0aGUgbG9vcGluZy1kYXRhIGNoYW5nZXMgYXBwbGllZCB0byBhIFVJIG9iamVjdCBieSB0aGlzIHN0eWxlLlxuICAgICpcbiAgICAqIEBtZXRob2QgcmV2ZXJ0TG9vcGluZ1xuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBsb29waW5nLWRhdGEgY2hhbmdlcyBzaG91bGQgYmUgcmV2ZXJ0ZWQuXG4gICAgIyMjICAgICAgICAgICAgICAgICBcbiAgICByZXZlcnRMb29waW5nOiAob2JqZWN0KSAtPlxuICAgICAgICBhY3RpdmVTdHlsZXMgPSBvYmplY3QuYWN0aXZlU3R5bGVzXG4gICAgICAgIGlmIEBsb29waW5nXG4gICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBub1xuICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5sb29waW5nLmhvcml6b250YWwgPSBub1xuICAgICAgICAgICAgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICAgICAgaWYgcy5sb29waW5nXG4gICAgICAgICAgICAgICAgICAgIGlmICFvYmplY3QudmlzdWFsLmxvb3BpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC52aXN1YWwuZGlzcG9zZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QucmVtb3ZlQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QudmlzdWFsID0gbmV3IGdzLkNvbXBvbmVudF9UaWxpbmdTcHJpdGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmFkZENvbXBvbmVudChvYmplY3QudmlzdWFsKVxuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5sb29waW5nLnZlcnRpY2FsID0gcy5sb29waW5nLnZlcnRpY2FsXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52aXN1YWwubG9vcGluZy5ob3Jpem9udGFsID0gcy5sb29waW5nLmhvcml6b250YWxcbiAgICAgICAgICAgIFxudWkuU3R5bGUgPSBTdHlsZVxuXG5jbGFzcyBVSU1hbmFnZXJcbiAgICAjIyMqXG4gICAgKiBIYW5kbGVzIHRoZSBjcmVhdGlvbiBvZiBJbiBHYW1lIFVJIGVsZW1lbnRzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dFxuICAgICogSW4tR2FtZSBVSSBzZWUgaGVscCBmaWxlLlxuICAgICpcbiAgICAqIEBtb2R1bGUgdWlcbiAgICAqIEBjbGFzcyBVSU1hbmFnZXJcbiAgICAqIEBtZW1iZXJvZiB1aVxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIHJlZ2lzdGVyZWQgVUkgbGF5b3V0cyBieSBuYW1lL2lkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBsYXlvdXRzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAbGF5b3V0cyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCByZWdpc3RlcmVkIFVJIHN0eWxlcyBieSBuYW1lL2lkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdHlsZXNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBzdHlsZXMgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgVUkgc3R5bGVzIGJ5IG51bWJlciBpZC5cbiAgICAgICAgKiBAcHJvcGVydHkgc3R5bGVzQnlJZFxuICAgICAgICAqIEB0eXBlIHVpLlN0eWxlW11cbiAgICAgICAgIyMjXG4gICAgICAgIEBzdHlsZXNCeUlkID0gbmV3IEFycmF5KClcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIFVJIHN0eWxlcyBieSBzdHlsZS1uYW1lLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdHlsZXNCeU5hbWVcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBzdHlsZXNCeU5hbWUgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBjdXN0b20gVUkgdHlwZXMvdGVtcGxhdGVzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IGN1c3RvbVR5cGVzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAY3VzdG9tVHlwZXMgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBVSSBjb250cm9sbGVycyBieSBuYW1lL2lkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBjdXN0b21UeXBlc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQGNvbnRyb2xsZXJzID0ge31cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIHJlZ2lzdGVyZWQgVUkgZGF0YSBzb3VyY2VzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IGN1c3RvbVR5cGVzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAZGF0YVNvdXJjZXMgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIE1hcHBpbmcgdG8gdGFibGUgdG8gbWFwIGFsaWdubWVudCBuYW1lcyB0byBudW1iZXIgdmFsdWVzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBhbGlnbm1lbnRzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyNcbiAgICAgICAgQGFsaWdubWVudHMgPSB7IFwibGVmdFwiOiAwLCBcInRvcFwiOiAwLCBcImNlbnRlclwiOiAxLCBcImJvdHRvbVwiOiAyLCBcInJpZ2h0XCI6IDIsIFwiMFwiOiAwLCBcIjFcIjogMSwgXCIyXCI6IDIgfVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIE1hcHBpbmcgdG8gdGFibGUgdG8gbWFwIGJsZW5kLW1vZGUgbmFtZXMgdG8gbnVtYmVyIHZhbHVlcy5cbiAgICAgICAgKiBAcHJvcGVydHkgYmxlbmRNb2Rlc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjXG4gICAgICAgIEBibGVuZE1vZGVzID0geyBcIm5vcm1hbFwiOiAwLCBcImFkZFwiOiAxLCBcInN1YlwiOiAyIH1cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBNYXBwaW5nIHRvIHRhYmxlIHRvIG1hcCBzZWxlY3RvciBuYW1lcyB0byBudW1iZXIgdmFsdWVzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzZWxlY3RvcnNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBzZWxlY3RvcnMgPSB7IG5vcm1hbDogMCwgaG92ZXI6IDEsIHNlbGVjdGVkOiAyLCBlbmFibGVkOiAzLCBmb2N1c2VkOiA0IH1cbiAgICAgICAgQGRlZmF1bHRQbGFjZWhvbGRlclBhcmFtcyA9IHt9XG4gICAgXG4gICAgIyMjKlxuICAgICogU2V0cyB1cCBVSSBNYW5hZ2VyLCBvcHRpbWl6ZXMgc3R5bGVzLCBldGMuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXR1cFxuICAgICMjI1xuICAgIHNldHVwOiAtPlxuICAgICAgICBAc2V0dXBTdHlsZXMoKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHVwIHRoZSBVSSBzdHlsZXMgYnkgd3JhcHBpbmcgdGhlbSBpbnRvIHVpLlN0eWxlIG9iamVjdHMgYW5kIG9wdGltaXppbmcgdGhlIGFjY2Vzcy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldHVwU3R5bGVzXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjXG4gICAgc2V0dXBTdHlsZXM6IC0+XG4gICAgICAgIGlkID0gMFxuICAgICAgICBzZWxlY3Rvck1hcCA9IEBzZWxlY3RvcnNcbiAgICAgICAgZm9yIGsgb2YgQHN0eWxlc1xuICAgICAgICAgICAgc3VicyA9IGsuc3BsaXQoXCIgXCIpXG4gICAgICAgICAgICBzZWxlY3RvciA9IHN1YnNbMF0uc3BsaXQoXCI6XCIpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIHNlbGVjdG9yTWFwW3NlbGVjdG9yWzFdXVxuICAgICAgICAgICAgICAgIEBzdHlsZXNCeUlkW2lkXSA9IG5ldyB1aS5TdHlsZShAc3R5bGVzW2tdLCBpZCwgc2VsZWN0b3JNYXBbc2VsZWN0b3JbMV1dKVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIEBzdHlsZXNCeUlkW2lkXSA9IG5ldyB1aS5TdHlsZShAc3R5bGVzW2tdLCBpZCwgMClcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgIUBzdHlsZXNCeU5hbWVbc2VsZWN0b3JbMF1dXG4gICAgICAgICAgICAgICAgQHN0eWxlc0J5TmFtZVtzZWxlY3RvclswXV0gPSBbXVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgQHN0eWxlc0J5TmFtZVtzZWxlY3RvclswXV0ucHVzaChAc3R5bGVzQnlJZFtpZF0pXG4gICAgICAgICAgICBAc3R5bGVzW2tdID0gQHN0eWxlc0J5SWRbaWRdXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlkKytcbiAgICAgICAgXG4gICAgICAgIGZvciBrIG9mIEBzdHlsZXNcbiAgICAgICAgICAgIHN1YnMgPSBrLnNwbGl0KFwiIFwiKVxuICAgICAgICAgICAgaWYgc3Vicy5sZW5ndGggPiAxXG4gICAgICAgICAgICAgICAgQHN0eWxlc0J5TmFtZVtzdWJzWzFdXS5wdXNoKEBzdHlsZXNba10pXG4gICAgICAgICAgICAgICAgQHN0eWxlc1trXS50YXJnZXQgPSBAc3R5bGVzW2suc3BsaXQoXCI6XCIpWzBdXT8uaWRcbiAgICAgICAgICAgICAgICAjQHN0eWxlc1tzdWJzWzFdXS50YXJnZXQgPSBAc3R5bGVzW2tdLmlkXG4gICAgICAgICAgICAgICAgI0BzdHlsZXNba10udGFyZ2V0ID0gQHN0eWxlc1tzdWJzWzFdXS5pZFxuICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIEV4ZWN1dGVzIGFsbCBwbGFjZWhvbGRlciBmb3JtdWxhcyBpbiB0aGUgc3BlY2lmaWVkIGRlc2NyaXB0b3IuIFRoZSBkZXNjcmlwdG9yIHdpbGwgYmUgY2hhbmdlZFxuICAgICogYW5kIHBsYWNlaG9sZGVyIGZvcm11bGFzIGFyZSByZXBsYWNlZCB3aXRoIHRoZWlyIGV2YWx1YXRlZCByZXN1bHQgdmFsdWUuXG4gICAgKlxuICAgICogQG1ldGhvZCBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhc1xuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgZGVzY3JpcHRvci5cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBPYmplY3QgY29udGFpbmluZyB0aGUgcGxhY2Vob2xkZXIgcGFyYW1zLlxuICAgICogQHByb3RlY3RlZFxuICAgICMjIyAgICBcbiAgICBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhczogKGRlc2NyaXB0b3IsIGlkLCBwYXJhbXMpIC0+XG4gICAgICAgIHJldHVybiBpZiBub3QgZGVzY3JpcHRvcj9cbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICBcbiAgICAgICAgZm9yIGsgaW4ga2V5c1xuICAgICAgICAgICAgdiA9IGRlc2NyaXB0b3Jba11cbiAgICAgICAgICAgIGlmIHY/XG4gICAgICAgICAgICAgICAgaWYgdiBpbnN0YW5jZW9mIEFycmF5XG4gICAgICAgICAgICAgICAgICAgIGZvciBpLCBjIGluIHZcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGk/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgdHlwZW9mIGkgPT0gXCJvYmplY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZXhlY3V0ZVBsYWNlaG9sZGVyRm9ybXVsYXMoaSwgaWQsIHBhcmFtcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIGMgIT0gXCJleGVjXCIgYW5kIHR5cGVvZiBpID09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cucCA9IHBhcmFtcyB8fCAgQGRlZmF1bHRQbGFjZWhvbGRlclBhcmFtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuZCA9IGRlc2NyaXB0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdltjXSA9IGkoKVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgdHlwZW9mIHYgPT0gXCJvYmplY3RcIlxuICAgICAgICAgICAgICAgICAgICBAZXhlY3V0ZVBsYWNlaG9sZGVyRm9ybXVsYXModiwgaWQsIHBhcmFtcylcbiAgICAgICAgICAgICAgICBlbHNlIGlmIGsgIT0gXCJleGVjX1wiIGFuZCB0eXBlb2YgdiA9PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnAgPSBwYXJhbXMgfHwgQGRlZmF1bHRQbGFjZWhvbGRlclBhcmFtc1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuZCA9IGRlc2NyaXB0b3JcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvcltrXSA9IHYoKVxuICAgICAgICByZXR1cm4gbnVsbFxuXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIGNhbGN1bGF0aW9uIGZvciBhIHNwZWNpZmllZCBleHByZXNzaW9uLlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlQ2FsY0Z1bmN0aW9uXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwcmVzc2lvbiAtIFRoZSBleHByZXNzaW9uIHRvIGNyZWF0ZSBhIGNhbGN1bGF0aW9uIGZ1bmN0aW9uIGZvci5cbiAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgY2FsY3VsYXRpb24gZnVuY3Rpb24uXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICAgICAgICAgICAgXG4gICAgY3JlYXRlQ2FsY0Z1bmN0aW9uOiAoZXhwcmVzc2lvbikgLT5cbiAgICAgICAgZXhwcmVzc2lvbiA9IGV4cHJlc3Npb24ucmVwbGFjZSgvKFswLTldKyklL2dtLCBcIigkMSAvIDEwMCAqIHYpXCIpXG4gICAgICAgIHJldHVybiBldmFsKFwiKGZ1bmN0aW9uKHYpeyByZXR1cm4gXCIgKyBleHByZXNzaW9uICsgXCJ9KVwiKVxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGZyb20gdGhlIHNwZWNpZmllZCBvYmplY3QgdHlwZS4gVGhlIHR5cGUgaGFzIHRoZSBmb3JtYXRcbiAgICAqIDxuYW1lc3BhY2U+Ljx0eXBlbmFtZT4gbGlrZSB2bi5Db21wb25lbnRfSG90c3BvdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZU9iamVjdFxuICAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBuYW1lLlxuICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgY3JlYXRlZCBvYmplY3QuXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICAgICAgICAgIFxuICAgIGNyZWF0ZU9iamVjdDogKHR5cGUpIC0+XG4gICAgICAgIHN1YnMgPSB0eXBlLnNwbGl0KFwiLlwiKVxuICAgICAgICByZXR1cm4gbmV3IHdpbmRvd1tzdWJzWzBdXVtzdWJzWzFdXSgpXG4gICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGFuIFVJIG9iamVjdCBmcm9tIGEgc3BlY2lmaWVkIFVJIGRlc2NyaXB0b3IuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVGcm9tRGVzY3JpcHRvclxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcGFyYW0ge2dzLk9iamVjdF9VSUVsZW1lbnR9IHBhcmVudCAtIFRoZSBVSSBwYXJlbnQgb2JqZWN0LiAoQSBsYXlvdXQgZm9yIGV4YW1wbGUpLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgVUkgb2JqZWN0LlxuICAgICMjIyAgIFxuICAgIGNyZWF0ZUZyb21EZXNjcmlwdG9yOiAoZGVzY3JpcHRvciwgcGFyZW50KSAtPlxuICAgICAgICBjb250cm9sID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgZm9yIGsgb2YgQGNvbnRyb2xsZXJzXG4gICAgICAgICAgICBpZiBAY29udHJvbGxlcnNba10udHlwZT9cbiAgICAgICAgICAgICAgICBAY29udHJvbGxlcnNba10gPSBAY3JlYXRlT2JqZWN0KEBjb250cm9sbGVyc1trXS50eXBlKVxuICAgICAgICAgICAgXG4gICAgICAgIEBfY3JlYXRlRnJvbURlc2NyaXB0b3IoZGVzY3JpcHRvciwgcGFyZW50KVxuICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUltYWdlQnV0dG9uXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICBcbiAgICBjcmVhdGVJbWFnZUJ1dHRvbjogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0hvdHNwb3QoZGVzY3JpcHRvci5pbWFnZSwgZGVzY3JpcHRvci5pbWFnZUhhbmRsaW5nKSBcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgY29udHJvbC5iZWhhdmlvci5zb3VuZCA9IGRlc2NyaXB0b3Iuc291bmRcbiAgICAgICAgY29udHJvbC5iZWhhdmlvci5zb3VuZHMgPSBkZXNjcmlwdG9yLnNvdW5kc1xuICAgICAgICBjb250cm9sLmltYWdlID0gZGVzY3JpcHRvci5pbWFnZVxuICAgICAgICBjb250cm9sLmltYWdlcyA9IGRlc2NyaXB0b3IuaW1hZ2VzXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuaW1hZ2VGb2xkZXI/XG4gICAgICAgICAgICBjb250cm9sLmltYWdlRm9sZGVyID0gZGVzY3JpcHRvci5pbWFnZUZvbGRlclxuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IubG9vcGluZz9cbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmRpc3Bvc2UoKVxuICAgICAgICAgICAgY29udHJvbC5yZW1vdmVDb21wb25lbnQoY29udHJvbC52aXN1YWwpXG4gICAgICAgICAgICBjb250cm9sLnZpc3VhbCA9IG5ldyBncy5Db21wb25lbnRfVGlsaW5nU3ByaXRlKClcbiAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbnRyb2wudmlzdWFsKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBjb250cm9sLnZpc3VhbC5sb29waW5nLnZlcnRpY2FsID0gZGVzY3JpcHRvci5sb29waW5nLnZlcnRpY2FsXG4gICAgICAgICAgICBjb250cm9sLnZpc3VhbC5sb29waW5nLmhvcml6b250YWwgPSBkZXNjcmlwdG9yLmxvb3BpbmcuaG9yaXpvbnRhbFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmNvbG9yP1xuICAgICAgICAgICAgY29udHJvbC5jb2xvciA9IENvbG9yLmZyb21BcnJheShkZXNjcmlwdG9yLmNvbG9yKVxuICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gaW1hZ2UgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlSW1hZ2VcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgIFxuICAgIGNyZWF0ZUltYWdlOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfSW1hZ2UoZGVzY3JpcHRvci5pbWFnZSwgZGVzY3JpcHRvci5pbWFnZUhhbmRsaW5nKSBcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5pbWFnZUZvbGRlcj9cbiAgICAgICAgICAgIGNvbnRyb2wuaW1hZ2VGb2xkZXIgPSBkZXNjcmlwdG9yLmltYWdlRm9sZGVyXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5sb29waW5nP1xuICAgICAgICAgICAgY29udHJvbC52aXN1YWwuZGlzcG9zZSgpXG4gICAgICAgICAgICBjb250cm9sLnJlbW92ZUNvbXBvbmVudChjb250cm9sLnZpc3VhbClcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsID0gbmV3IGdzLkNvbXBvbmVudF9UaWxpbmdTcHJpdGUoKVxuICAgICAgICAgICAgY29udHJvbC5hZGRDb21wb25lbnQoY29udHJvbC52aXN1YWwpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBkZXNjcmlwdG9yLmxvb3BpbmcudmVydGljYWxcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IGRlc2NyaXB0b3IubG9vcGluZy5ob3Jpem9udGFsXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuY29sb3I/XG4gICAgICAgICAgICBjb250cm9sLmNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuY29sb3IpXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gaW1hZ2UgbWFwIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUltYWdlTWFwXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICAgICBcbiAgICBjcmVhdGVJbWFnZU1hcDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0ltYWdlTWFwKClcbiAgICAgICAgY29udHJvbC5ob3RzcG90cyA9IChkZXNjcmlwdG9yLmhvdHNwb3RzfHxbXSkuc2VsZWN0IChoKSAtPiBcbiAgICAgICAgICAgIHsgeDogaC5yZWN0WzBdLCB5OiBoLnJlY3RbMV0sIHNpemU6IHsgd2lkdGg6IGgucmVjdFsyXSwgaGVpZ2h0OiBoLnJlY3RbM10gfSwgZGF0YTogeyBhY3Rpb246IDMsIGFjdGlvbnM6IGguYWN0aW9ucyB9IH1cbiAgICAgICAgY29udHJvbC5pbWFnZXMgPSBkZXNjcmlwdG9yLmltYWdlc1xuICAgICAgICBjb250cm9sLmluc2VydENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0FjdGlvbkhhbmRsZXIoKSwgMSwgXCJhY3Rpb25IYW5kbGVyXCIpXG4gICAgICAgIGNvbnRyb2wudGFyZ2V0ID0gU2NlbmVNYW5hZ2VyLnNjZW5lLmJlaGF2aW9yXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSB2aWRlbyBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVWaWRlb1xuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICBcbiAgICBjcmVhdGVWaWRlbzogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1ZpZGVvKClcbiAgICAgICAgY29udHJvbC52aWRlbyA9IGRlc2NyaXB0b3IudmlkZW9cbiAgICAgICAgY29udHJvbC5sb29wID0gZGVzY3JpcHRvci5sb29wID8geWVzXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBwYW5lbCBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVQYW5lbFxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgICBcbiAgICBjcmVhdGVQYW5lbDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1BhbmVsKClcbiAgICAgICAgY29udHJvbC5tb2RhbCA9IGRlc2NyaXB0b3IubW9kYWwgPyBub1xuICAgICAgICBpZiBkZXNjcmlwdG9yLmNvbG9yP1xuICAgICAgICAgICAgY29udHJvbC5jb2xvciA9IENvbG9yLmZyb21BcnJheShkZXNjcmlwdG9yLmNvbG9yKVxuICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIGZyYW1lIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUZyYW1lXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICAgICAgICBcbiAgICBjcmVhdGVGcmFtZTogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0ZyYW1lKGRlc2NyaXB0b3IuZnJhbWVTa2luKVxuICAgICAgICBjb250cm9sLmZyYW1lVGhpY2tuZXNzID0gZGVzY3JpcHRvci5mcmFtZVRoaWNrbmVzcyB8fCAxNlxuICAgICAgICBjb250cm9sLmZyYW1lQ29ybmVyU2l6ZSA9IGRlc2NyaXB0b3IuZnJhbWVDb3JuZXJTaXplIHx8IDE2XG4gICAgICAgIGNvbnRyb2wuaW1hZ2UgPSBkZXNjcmlwdG9yLmltYWdlXG4gICAgICAgIGNvbnRyb2wuaW1hZ2VzID0gZGVzY3JpcHRvci5pbWFnZXNcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIHRocmVlLXBhcnQgaW1hZ2UgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlVGhyZWVQYXJ0SW1hZ2VcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgIFxuICAgIGNyZWF0ZVRocmVlUGFydEltYWdlOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfVGhyZWVQYXJ0SW1hZ2UoZGVzY3JpcHRvci5mcmFtZVNraW4pXG4gICAgICAgIGNvbnRyb2wuZmlyc3RQYXJ0U2l6ZSA9IGRlc2NyaXB0b3IuZmlyc3RQYXJ0U2l6ZSB8fCAxNlxuICAgICAgICBjb250cm9sLm1pZGRsZVBhcnRTaXplID0gZGVzY3JpcHRvci5taWRkbGVQYXJ0U2l6ZSB8fCAxXG4gICAgICAgIGNvbnRyb2wubGFzdFBhcnRTaXplID0gZGVzY3JpcHRvci5sYXN0UGFydFNpemUgfHwgMTZcbiAgICAgICAgY29udHJvbC5pbWFnZSA9IGRlc2NyaXB0b3IuaW1hZ2VcbiAgICAgICAgY29udHJvbC5pbWFnZXMgPSBkZXNjcmlwdG9yLmltYWdlc1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIHRleHQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlVGV4dFxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgXG4gICAgY3JlYXRlVGV4dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1RleHQoKVxuICAgICAgICBjb250cm9sLnRleHQgPSBsY3MoZGVzY3JpcHRvci50ZXh0KVxuICAgICAgICBjb250cm9sLnNpemVUb0ZpdCA9IGRlc2NyaXB0b3Iuc2l6ZVRvRml0XG4gICAgICAgIGNvbnRyb2wuZm9ybWF0dGluZyA9IGRlc2NyaXB0b3IuZm9ybWF0dGluZ1xuICAgICAgICBjb250cm9sLndvcmRXcmFwID0gZGVzY3JpcHRvci53b3JkV3JhcCA/IG5vXG4gICAgICAgIGNvbnRyb2wuYmVoYXZpb3IuZm9ybWF0ID0gZGVzY3JpcHRvci5mb3JtYXRcbiAgICAgICAgaWYgZGVzY3JpcHRvci50ZXh0UGFkZGluZ1xuICAgICAgICAgICAgY29udHJvbC5iZWhhdmlvci5wYWRkaW5nID0gdWkuU3BhY2UuZnJvbUFycmF5KGRlc2NyaXB0b3IudGV4dFBhZGRpbmcpXG4gICAgICAgIGlmIGRlc2NyaXB0b3IucmVzb2x2ZVBsYWNlaG9sZGVycz9cbiAgICAgICAgICAgIGNvbnRyb2wucmVzb2x2ZVBsYWNlaG9sZGVycyA9IGRlc2NyaXB0b3IucmVzb2x2ZVBsYWNlaG9sZGVyc1xuICAgICAgICBpZiBkZXNjcmlwdG9yLmNvbG9yP1xuICAgICAgICAgICAgY29udHJvbC5jb2xvciA9IENvbG9yLmZyb21BcnJheShkZXNjcmlwdG9yLmNvbG9yKVxuICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIGZyZWUtbGF5b3V0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUZyZWVMYXlvdXRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgXG4gICAgY3JlYXRlRnJlZUxheW91dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9GcmVlTGF5b3V0KGRlc2NyaXB0b3IuZnJhbWVbMF0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsxXSB8fCAwLCBkZXNjcmlwdG9yLmZyYW1lWzJdIHx8IDEsIGRlc2NyaXB0b3IuZnJhbWVbM10gfHwgMSlcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfRnJlZUxheW91dCgwLCAwLCAxLCAxKVxuICAgICAgICBjb250cm9sLnNpemVUb0ZpdCA9IGRlc2NyaXB0b3Iuc2l6ZVRvRml0XG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBzdGFjay1sYXlvdXQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlU3RhY2tMYXlvdXRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgIFxuICAgIGNyZWF0ZVN0YWNrTGF5b3V0OiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgaWYgZGVzY3JpcHRvci5mcmFtZT9cbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1N0YWNrTGF5b3V0KGRlc2NyaXB0b3IuZnJhbWVbMF0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsxXSB8fCAwLCBkZXNjcmlwdG9yLmZyYW1lWzJdIHx8IDEsIGRlc2NyaXB0b3IuZnJhbWVbM10gfHwgMSwgZGVzY3JpcHRvci5vcmllbnRhdGlvbilcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfU3RhY2tMYXlvdXQoMCwgMCwgMSwgMSwgZGVzY3JpcHRvci5vcmllbnRhdGlvbilcbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgc3ByZWFkLWxheW91dCBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVTcHJlYWRMYXlvdXRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgIFxuICAgIGNyZWF0ZVNwcmVhZExheW91dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9TcHJlYWRMYXlvdXQoZGVzY3JpcHRvci5mcmFtZVswXSB8fCAwLCBkZXNjcmlwdG9yLmZyYW1lWzFdIHx8IDAsIGRlc2NyaXB0b3IuZnJhbWVbMl0gfHwgMSwgZGVzY3JpcHRvci5mcmFtZVszXSB8fCAxLCBkZXNjcmlwdG9yLm9yaWVudGF0aW9uKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9TcHJlYWRMYXlvdXQoMCwgMCwgMSwgMSwgZGVzY3JpcHRvci5vcmllbnRhdGlvbilcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgZ3JpZC1sYXlvdXQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlR3JpZExheW91dFxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICBcbiAgICBjcmVhdGVHcmlkTGF5b3V0OiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgaWYgZGVzY3JpcHRvci5mcmFtZT9cbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0dyaWRMYXlvdXQoZGVzY3JpcHRvci5mcmFtZVswXSwgZGVzY3JpcHRvci5mcmFtZVsxXSwgZGVzY3JpcHRvci5mcmFtZVsyXSwgZGVzY3JpcHRvci5mcmFtZVszXSwgZGVzY3JpcHRvci5yb3dzLCBkZXNjcmlwdG9yLmNvbHVtbnMsIGRlc2NyaXB0b3IudGVtcGxhdGUpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0dyaWRMYXlvdXQoMCwgMCwgMSwgMSwgZGVzY3JpcHRvci5yb3dzLCBkZXNjcmlwdG9yLmNvbHVtbnMsIGRlc2NyaXB0b3IudGVtcGxhdGUpXG4gICAgICAgIGNvbnRyb2wuY2VsbFNwYWNpbmcgPSBkZXNjcmlwdG9yLmNlbGxTcGFjaW5nIHx8IFswLCAwLCAwLCAwXVxuICAgICAgICBjb250cm9sLnNpemVUb0ZpdCA9IGRlc2NyaXB0b3Iuc2l6ZVRvRml0XG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgbWVzc2FnZSBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVNZXNzYWdlXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVNZXNzYWdlOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfTWVzc2FnZSgpIFxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIGRhdGEtZ3JpZCBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVEYXRhR3JpZFxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICBcbiAgICBjcmVhdGVEYXRhR3JpZDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0RhdGFHcmlkKGRlc2NyaXB0b3IpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGFuIFVJIG9iamVjdCBkZXBlbmRpbmcgb24gdGhlIG9iamVjdC10eXBlIG9mIHRoZSBzcGVjaWZpZWQgVUkgZGVzY3JpcHRvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUNvbnRyb2xcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgVUkgb2JqZWN0LlxuICAgICogQHByb3RlY3RlZFxuICAgICMjIyAgXG4gICAgY3JlYXRlQ29udHJvbDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBudWxsXG4gICAgICAgIFxuICAgICAgICBzd2l0Y2ggZGVzY3JpcHRvci50eXBlXG4gICAgICAgICAgICB3aGVuIFwidWkuSW1hZ2VCdXR0b25cIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlSW1hZ2VCdXR0b24oZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5JbWFnZVwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVJbWFnZShkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLkltYWdlTWFwXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUltYWdlTWFwKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuVmlkZW9cIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlVmlkZW8oZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5QYW5lbFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVQYW5lbChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLkZyYW1lXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUZyYW1lKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuVGhyZWVQYXJ0SW1hZ2VcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlVGhyZWVQYXJ0SW1hZ2UoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5UZXh0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVRleHQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5NZXNzYWdlXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZU1lc3NhZ2UoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5EYXRhR3JpZFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVEYXRhR3JpZChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLkZyZWVMYXlvdXRcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlRnJlZUxheW91dChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlN0YWNrTGF5b3V0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVN0YWNrTGF5b3V0KGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuU3ByZWFkTGF5b3V0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVNwcmVhZExheW91dChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLkdyaWRMYXlvdXRcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlR3JpZExheW91dChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgIFxuICAgIGNyZWF0ZUxheW91dFJlY3Q6IChmcmFtZSwgY29udHJvbCkgLT5cbiAgICAgICAgaWYgIWNvbnRyb2wubGF5b3V0UmVjdFxuICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0ID0gbmV3IHVpLkxheW91dFJlY3QoKVxuICAgICAgICBjb250cm9sLmxheW91dFJlY3Quc2V0KDAsIDAsIDAsIDApXG4gICAgICAgIFxuICAgICAgICBpZiBmcmFtZT9cbiAgICAgICAgICAgIGlmIGZyYW1lWzBdPy5sZW5ndGg/XG4gICAgICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnggPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGZyYW1lWzBdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC54ID0gMFxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC54ID0gKGRlc2NyaXB0b3IuZnJhbWVbMF0gPyBjb250cm9sLmRzdFJlY3QueClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGZyYW1lWzFdPy5sZW5ndGg/XG4gICAgICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnkgPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGZyYW1lWzFdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC55ID0gMFxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC55ID0gKGZyYW1lWzFdID8gY29udHJvbC5kc3RSZWN0LnkpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBmcmFtZVsyXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC53aWR0aCA9IEBjcmVhdGVDYWxjRnVuY3Rpb24oZnJhbWVbMl0pXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LndpZHRoID0gMVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC53aWR0aCA9IChmcmFtZVsyXSA/IGNvbnRyb2wuZHN0UmVjdC53aWR0aClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGZyYW1lWzNdPy5sZW5ndGg/XG4gICAgICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LmhlaWdodCA9IEBjcmVhdGVDYWxjRnVuY3Rpb24oZnJhbWVbM10pXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LmhlaWdodCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QuaGVpZ2h0ID0gKGZyYW1lWzNdID8gY29udHJvbC5kc3RSZWN0LmhlaWdodClcbiAgICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyB0aGUgc3R5bGVzIGRlZmluZWQgaW4gYW4gYXJyYXkgb2Ygc3R5bGUtbmFtZXMgdG8gdGhlIHNwZWNpZmllZCBjb250cm9sLlxuICAgICpcbiAgICAqIEBtZXRob2QgYWRkQ29udHJvbFN0eWxlc1xuICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRyb2wgLSBUaGUgY29udHJvbCB0byBhZGQgdGhlIHN0eWxlcyB0by5cbiAgICAqIEBwYXJhbSB7c3RyaW5nW119IHN0eWxlcyAtIEFycmF5IG9mIHN0eWxlLW5hbWVzIHRvIGFkZC5cbiAgICAjIyMgICAgIFxuICAgIGFkZENvbnRyb2xTdHlsZXM6IChjb250cm9sLCBzdHlsZXMpIC0+XG4gICAgICAgIGZvciBzdHlsZU5hbWUgaW4gc3R5bGVzXG4gICAgICAgICAgICBpZiBAc3R5bGVzQnlOYW1lW3N0eWxlTmFtZV0/XG4gICAgICAgICAgICAgICAgZm9yIHN0eWxlIGluIEBzdHlsZXNCeU5hbWVbc3R5bGVOYW1lXVxuICAgICAgICAgICAgICAgICAgICBjb250cm9sLnN0eWxlcy5wdXNoKHN0eWxlKVxuICAgICAgICAgICAgICAgICAgICBpZiBzdHlsZS50YXJnZXQgPT0gLTEgYW5kIHN0eWxlLnNlbGVjdG9yID09IDBcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlLmFwcGx5KGNvbnRyb2wpXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBVSSBvYmplY3QgZnJvbSBhIHNwZWNpZmllZCBVSSBkZXNjcmlwdG9yLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWRcbiAgICAqIHJlY3Vyc2l2ZWx5IGZvciBhbGwgY2hpbGQtZGVzY3JpcHRvcnMuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVDb250cm9sRnJvbURlc2NyaXB0b3JcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHBhcmFtIHtncy5PYmplY3RfVUlFbGVtZW50fSBwYXJlbnQgLSBUaGUgVUkgcGFyZW50IG9iamVjdC4gKEEgbGF5b3V0IGZvciBleGFtcGxlKS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIFRoZSBpbmRleC5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIFVJIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgIFxuICAgIGNyZWF0ZUNvbnRyb2xGcm9tRGVzY3JpcHRvcjogKGRlc2NyaXB0b3IsIHBhcmVudCwgaW5kZXgpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBudWxsXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnN0eWxlP1xuICAgICAgICAgICAgZGVzY3JpcHRvci5zdHlsZXMgPSBbZGVzY3JpcHRvci5zdHlsZV1cbiAgICAgICAgICAgIGRlbGV0ZSBkZXNjcmlwdG9yLnN0eWxlXG4gICAgICAgICAgICBcbiAgICAgICAgZGVzY3JpcHRvciA9IE9iamVjdC5kZWVwQ29weShkZXNjcmlwdG9yKVxuICAgICAgICBAZXhlY3V0ZVBsYWNlaG9sZGVyRm9ybXVsYXMoZGVzY3JpcHRvciwgZGVzY3JpcHRvci5pZCwgZGVzY3JpcHRvci5wYXJhbXMpXG4gICAgICAgICAgICBcbiAgICAgICAgY29udHJvbCA9IEBjcmVhdGVDb250cm9sKGRlc2NyaXB0b3IpXG4gICAgICAgIFxuICAgICAgICBpZiBub3QgY29udHJvbD9cbiAgICAgICAgICAgIHR5cGUgPSBPYmplY3QuZGVlcENvcHkoQGN1c3RvbVR5cGVzW2Rlc2NyaXB0b3IudHlwZV0pXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhcyh0eXBlLCBkZXNjcmlwdG9yLmlkLCBkZXNjcmlwdG9yLnBhcmFtcylcbiAgICAgICBcbiAgICAgICAgICAgIHR5cGVOYW1lID0gdHlwZS50eXBlXG4gICAgICAgICAgICBjdXN0b21GaWVsZHMgPSB0eXBlLmN1c3RvbUZpZWxkc1xuICAgICAgICAgICAgYmluZGluZ3MgPSB0eXBlLmJpbmRpbmdzXG4gICAgICAgICAgICBmb3JtdWxhcyA9IHR5cGUuZm9ybXVsYXNcbiAgICAgICAgICAgIGFjdGlvbnMgPSB0eXBlLmFjdGlvbnNcbiAgICAgICAgICAgIGlmIHR5cGUuc3R5bGU/XG4gICAgICAgICAgICAgICAgdHlwZS5zdHlsZXMgPSBbdHlwZS5zdHlsZV1cbiAgICAgICAgICAgICAgICB0eXBlLnN0eWxlID0gbnVsbFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgT2JqZWN0Lm1peGluKHR5cGUsIGRlc2NyaXB0b3IpXG4gICAgICAgICAgICBpZiBjdXN0b21GaWVsZHM/IHRoZW4gT2JqZWN0Lm1peGluKHR5cGUuY3VzdG9tRmllbGRzLCBjdXN0b21GaWVsZHMpXG4gICAgICAgICAgICBpZiBiaW5kaW5ncz8gYW5kIGJpbmRpbmdzICE9IHR5cGUuYmluZGluZ3MgdGhlbiB0eXBlLmJpbmRpbmdzID0gdHlwZS5iaW5kaW5ncy5jb25jYXQoYmluZGluZ3MpXG4gICAgICAgICAgICBpZiBmb3JtdWxhcz8gYW5kIGZvcm11bGFzICE9IHR5cGUuZm9ybXVsYXMgdGhlbiB0eXBlLmZvcm11bGFzID0gdHlwZS5mb3JtdWxhcy5jb25jYXQoZm9ybXVsYXMpXG4gICAgICAgICAgICBpZiBhY3Rpb25zPyBhbmQgYWN0aW9ucyAhPSB0eXBlLmFjdGlvbnMgdGhlbiB0eXBlLmFjdGlvbnMgPSBhY3Rpb25zLmNvbmNhdCh0eXBlLmFjdGlvbnMpXG4gICAgICAgICAgICB0eXBlLnR5cGUgPSB0eXBlTmFtZVxuICAgICAgICAgICAgXG4gICAgICAgICAgICByZXR1cm4gQGNyZWF0ZUNvbnRyb2xGcm9tRGVzY3JpcHRvcih0eXBlLCBwYXJlbnQpXG4gICAgICAgIGVsc2UgaWYgcGFyZW50P1xuICAgICAgICAgICAgcGFyZW50LmFkZE9iamVjdChjb250cm9sKVxuICAgICAgICAgICAgY29udHJvbC5pbmRleCA9IGluZGV4XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudC5hZGRPYmplY3QoY29udHJvbClcbiAgICAgICAgIFxuICAgICAgICBjb250cm9sLnVpID0gbmV3IHVpLkNvbXBvbmVudF9VSUJlaGF2aW9yKClcbiAgICAgICAgY29udHJvbC5hZGRDb21wb25lbnQoY29udHJvbC51aSlcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLnBhcmFtcyA9IGRlc2NyaXB0b3IucGFyYW1zXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnVwZGF0ZUJlaGF2aW9yID09IFwiY29udGludW91c1wiXG4gICAgICAgICAgICBjb250cm9sLnVwZGF0ZUJlaGF2aW9yID0gdWkuVXBkYXRlQmVoYXZpb3IuQ09OVElOVU9VU1xuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuaW5oZXJpdFByb3BlcnRpZXNcbiAgICAgICAgICAgIGNvbnRyb2wuaW5oZXJpdFByb3BlcnRpZXMgPSB5ZXNcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQ/XG4gICAgICAgICAgICBjb250cm9sLmZvbnQgPSBuZXcgRm9udChkZXNjcmlwdG9yLmZvbnQubmFtZSwgZGVzY3JpcHRvci5mb250LnNpemUpXG4gICAgICAgICAgICBjb250cm9sLmZvbnQuYm9sZCA9IGRlc2NyaXB0b3IuZm9udC5ib2xkID8gY29udHJvbC5mb250LmJvbGRcbiAgICAgICAgICAgIGNvbnRyb2wuZm9udC5pdGFsaWMgPSBkZXNjcmlwdG9yLmZvbnQuaXRhbGljID8gY29udHJvbC5mb250Lml0YWxpY1xuICAgICAgICAgICAgY29udHJvbC5mb250LnNtYWxsQ2FwcyA9IGRlc2NyaXB0b3IuZm9udC5zbWFsbENhcHMgPyBjb250cm9sLmZvbnQuc21hbGxDYXBzXG4gICAgICAgICAgICBjb250cm9sLmZvbnQudW5kZXJsaW5lID0gZGVzY3JpcHRvci5mb250LnVuZGVybGluZSA/IGNvbnRyb2wuZm9udC51bmRlcmxpbmVcbiAgICAgICAgICAgIGNvbnRyb2wuZm9udC5zdHJpa2VUaHJvdWdoID0gZGVzY3JpcHRvci5mb250LnN0cmlrZVRocm91Z2ggPyBjb250cm9sLmZvbnQuc3RyaWtlVGhyb3VnaFxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQuY29sb3I/XG4gICAgICAgICAgICAgICAgY29udHJvbC5mb250LmNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5jb2xvcilcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5ib3JkZXI/XG4gICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlciA9IGRlc2NyaXB0b3IuZm9udC5ib3JkZXIgPyBub1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5ib3JkZXJTaXplID0gZGVzY3JpcHRvci5mb250LmJvcmRlclNpemUgPyA0XG4gICAgICAgICAgICAgICNpZiBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyLmNvbG9yXG4gICAgICAgICAgICAjICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyQ29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5mb250LmJvcmRlci5jb2xvcilcbiAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyQ29sb3IgPSBuZXcgQ29sb3IoMCwgMCwgMClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5ib3JkZXIgPSBkZXNjcmlwdG9yLmZvbnQub3V0bGluZSA/IG5vXG4gICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlclNpemUgPSBkZXNjcmlwdG9yLmZvbnQub3V0bGluZS5zaXplID8gNFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lLmNvbG9yP1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyQ29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5mb250Lm91dGxpbmUuY29sb3IpXG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyQ29sb3IgPSBuZXcgQ29sb3IoMCwgMCwgMClcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmNvbXBvbmVudHM/XG4gICAgICAgICAgICBmb3IgYyBpbiBkZXNjcmlwdG9yLmNvbXBvbmVudHNcbiAgICAgICAgICAgICAgICBtID0gYy5tb2R1bGUgfHwgXCJnc1wiXG4gICAgICAgICAgICAgICAgY29tcG9uZW50ID0gbmV3IHdpbmRvd1ttXVtjLnR5cGVdKGMucGFyYW1zKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbXBvbmVudCwgYy5pZClcbiAgICAgICAgICAgICAgICBjb250cm9sW2MuaWRdID0gY29tcG9uZW50XG4gICAgICAgICAgICAgICAgI2NvbXBvbmVudC5zZXR1cD8oKVxuICAgICAgICAgXG4gICAgICAgIGNvbnRyb2wuZm9jdXNhYmxlID0gZGVzY3JpcHRvci5mb2N1c2FibGUgPyBjb250cm9sLmZvY3VzYWJsZSAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5uZXh0S2V5T2JqZWN0XG4gICAgICAgICAgICBjb250cm9sLnVpLm5leHRLZXlPYmplY3RJZCA9IGRlc2NyaXB0b3IubmV4dEtleU9iamVjdFxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5pbml0aWFsRm9jdXNcbiAgICAgICAgICAgIGNvbnRyb2wudWkuZm9jdXMoKVxuICAgICAgICAgICAgXG4gICAgICAgIGFjdGlvbnMgPSBPYmplY3QuZGVlcENvcHkoaWYgZGVzY3JpcHRvci5hY3Rpb24/IHRoZW4gW2Rlc2NyaXB0b3IuYWN0aW9uXSBlbHNlIGRlc2NyaXB0b3IuYWN0aW9ucykgXG4gICAgICAgIGlmIGFjdGlvbnM/XG4gICAgICAgICAgICBmb3IgYWN0aW9uIGluIGFjdGlvbnNcbiAgICAgICAgICAgICAgICBpZiBhY3Rpb24/XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbi5ldmVudCA9IGFjdGlvbi5ldmVudCA/IFwib25BY2NlcHRcIlxuICAgICAgICAgICAgICAgICAgICBpZiBub3QgYWN0aW9uLnRhcmdldD9cbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IGlmIEBjb250cm9sbGVycz8gdGhlbiBAY29udHJvbGxlcnNbZGVzY3JpcHRvci50YXJnZXRdIGVsc2UgY29udHJvbGxlclxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uLnRhcmdldCA9IHRhcmdldCB8fCBTY2VuZU1hbmFnZXIuc2NlbmUuYmVoYXZpb3JcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29udHJvbC5hY3Rpb25zID0gYWN0aW9uc1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZighY29udHJvbC5maW5kQ29tcG9uZW50QnlJZChcImFjdGlvbkhhbmRsZXJcIikpXG4gICAgICAgICAgICAgICAgY29udHJvbC5pbnNlcnRDb21wb25lbnQobmV3IHVpLkNvbXBvbmVudF9BY3Rpb25IYW5kbGVyKCksIDEsIFwiYWN0aW9uSGFuZGxlclwiKVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5pZD9cbiAgICAgICAgICAgIGNvbnRyb2wuaWQgPSBkZXNjcmlwdG9yLmlkXG4gICAgICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQuc2V0T2JqZWN0QnlJZChjb250cm9sLCBjb250cm9sLmlkKVxuICAgICAgICAgICAgXG4gICAgICAgIGNvbnRyb2wuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JcbiAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0ID0gbmV3IFJlY3QoKVxuICAgICAgICBjb250cm9sLmxheW91dFJlY3Quc2V0KDAsIDAsIDAsIDApXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lWzBdPy5sZW5ndGg/XG4gICAgICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnggPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGRlc2NyaXB0b3IuZnJhbWVbMF0pXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LnggPSAwXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LnggPSAoZGVzY3JpcHRvci5mcmFtZVswXSA/IGNvbnRyb2wuZHN0UmVjdC54KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mcmFtZVsxXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC55ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzFdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC55ID0gMFxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC55ID0gKGRlc2NyaXB0b3IuZnJhbWVbMV0gPyBjb250cm9sLmRzdFJlY3QueSlcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWVbMl0/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3Qud2lkdGggPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGRlc2NyaXB0b3IuZnJhbWVbMl0pXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LndpZHRoID0gMVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC53aWR0aCA9IChkZXNjcmlwdG9yLmZyYW1lWzJdID8gY29udHJvbC5kc3RSZWN0LndpZHRoKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mcmFtZVszXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC5oZWlnaHQgPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGRlc2NyaXB0b3IuZnJhbWVbM10pICNwYXJzZUludChkZXNjcmlwdG9yLmZyYW1lWzNdLnNwbGl0KFwiJVwiKVswXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QuaGVpZ2h0ID0gMVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQgPSAoZGVzY3JpcHRvci5mcmFtZVszXSA/IGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQpXG4gICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnNpemVUb1BhcmVudD9cbiAgICAgICAgICAgIGNvbnRyb2wuc2l6ZVRvUGFyZW50ID0gZGVzY3JpcHRvci5zaXplVG9QYXJlbnRcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmJsZW5kTW9kZT9cbiAgICAgICAgICAgIGNvbnRyb2wuYmxlbmRNb2RlID0gQGJsZW5kTW9kZXNbZGVzY3JpcHRvci5ibGVuZE1vZGVdXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5hbmNob3I/XG4gICAgICAgICAgICBjb250cm9sLmFuY2hvci5zZXQoZGVzY3JpcHRvci5hbmNob3JbMF0sIGRlc2NyaXB0b3IuYW5jaG9yWzFdKVxuICAgICAgICBcblxuICAgICAgICBjb250cm9sLm9wYWNpdHkgPSBkZXNjcmlwdG9yLm9wYWNpdHkgPyAyNTUgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IubWluaW11bVNpemU/XG4gICAgICAgICAgICBjb250cm9sLm1pbmltdW1TaXplID0geyB3aWR0aDogZGVzY3JpcHRvci5taW5pbXVtU2l6ZVswXSwgaGVpZ2h0OiBkZXNjcmlwdG9yLm1pbmltdW1TaXplWzFdIH1cbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnJlc2l6YWJsZT8gdGhlbiBjb250cm9sLnJlc2l6YWJsZSA9IGRlc2NyaXB0b3IucmVzaXphYmxlXG4gICAgICAgIGlmIGRlc2NyaXB0b3Iuc2Nyb2xsYWJsZT8gdGhlbiBjb250cm9sLnNjcm9sbGFibGUgPSBkZXNjcmlwdG9yLnNjcm9sbGFibGUgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZml4ZWRTaXplPyB0aGVuIGNvbnRyb2wuZml4ZWRTaXplID0gZGVzY3JpcHRvci5maXhlZFNpemVcbiAgICAgICAgaWYgZGVzY3JpcHRvci5kcmFnZ2FibGU/XG4gICAgICAgICAgICBjb250cm9sLmRyYWdnYWJsZSA9IGRlc2NyaXB0b3IuZHJhZ2dhYmxlXG4gICAgICAgICAgICBjb250cm9sLmRyYWdnYWJsZS5zdGVwID0gMFxuICAgICAgICAgICAgaWYgY29udHJvbC5kcmFnZ2FibGUucmVjdD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmRyYWdnYWJsZS5yZWN0ID0gUmVjdC5mcm9tQXJyYXkoY29udHJvbC5kcmFnZ2FibGUucmVjdClcbiAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfRHJhZ2dhYmxlKCkpXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmJpbmRpbmdzP1xuICAgICAgICAgICAgY29udHJvbC5iaW5kaW5ncyA9IGRlc2NyaXB0b3IuYmluZGluZ3NcbiAgICAgICAgICAgIGNvbnRyb2wuaW5zZXJ0Q29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQmluZGluZ0hhbmRsZXIoKSwgMClcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZvcm11bGFzP1xuICAgICAgICAgICAgY29udHJvbC5mb3JtdWxhcyA9IGRlc2NyaXB0b3IuZm9ybXVsYXNcbiAgICAgICAgICAgIGNvbnRyb2wuaW5zZXJ0Q29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfRm9ybXVsYUhhbmRsZXIoKSwgMClcbiAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmRhdGFGaWVsZCA9IGRlc2NyaXB0b3IuZGF0YUZpZWxkXG4gICAgICAgIGNvbnRyb2wuZW5hYmxlZCA9IGRlc2NyaXB0b3IuZW5hYmxlZCA/IHllc1xuICAgICAgICBpZiBkZXNjcmlwdG9yLnNlbGVjdGFibGU/IHRoZW4gY29udHJvbC5zZWxlY3RhYmxlID0gZGVzY3JpcHRvci5zZWxlY3RhYmxlXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZ3JvdXA/IFxuICAgICAgICAgICAgY29udHJvbC5ncm91cCA9IGRlc2NyaXB0b3IuZ3JvdXBcbiAgICAgICAgICAgIGdzLk9iamVjdE1hbmFnZXIuY3VycmVudC5hZGRUb0dyb3VwKGNvbnRyb2wsIGNvbnRyb2wuZ3JvdXApXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmN1c3RvbUZpZWxkcz9cbiAgICAgICAgICAgIGNvbnRyb2wuY3VzdG9tRmllbGRzID0gT2JqZWN0LmRlZXBDb3B5KGRlc2NyaXB0b3IuY3VzdG9tRmllbGRzKVxuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IubWFyZ2luP1xuICAgICAgICAgICAgY29udHJvbC5tYXJnaW4ubGVmdCA9IGRlc2NyaXB0b3IubWFyZ2luWzBdXG4gICAgICAgICAgICBjb250cm9sLm1hcmdpbi50b3AgPSBkZXNjcmlwdG9yLm1hcmdpblsxXVxuICAgICAgICAgICAgY29udHJvbC5tYXJnaW4ucmlnaHQgPSBkZXNjcmlwdG9yLm1hcmdpblsyXVxuICAgICAgICAgICAgY29udHJvbC5tYXJnaW4uYm90dG9tID0gZGVzY3JpcHRvci5tYXJnaW5bM11cbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnBhZGRpbmc/XG4gICAgICAgICAgICBjb250cm9sLnBhZGRpbmcubGVmdCA9IGRlc2NyaXB0b3IucGFkZGluZ1swXVxuICAgICAgICAgICAgY29udHJvbC5wYWRkaW5nLnRvcCA9IGRlc2NyaXB0b3IucGFkZGluZ1sxXVxuICAgICAgICAgICAgY29udHJvbC5wYWRkaW5nLnJpZ2h0ID0gZGVzY3JpcHRvci5wYWRkaW5nWzJdXG4gICAgICAgICAgICBjb250cm9sLnBhZGRpbmcuYm90dG9tID0gZGVzY3JpcHRvci5wYWRkaW5nWzNdXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5hbGlnbm1lbnQ/XG4gICAgICAgICAgICBjb250cm9sLmFsaWdubWVudCA9IEBhbGlnbm1lbnRzW2Rlc2NyaXB0b3IuYWxpZ25tZW50XVxuICAgICAgICAgICAgXG4gICAgICAgIGNvbnRyb2wuYWxpZ25tZW50WSA9IEBhbGlnbm1lbnRzW2Rlc2NyaXB0b3IuYWxpZ25tZW50WSB8fCAwXVxuICAgICAgICBjb250cm9sLmFsaWdubWVudFggPSBAYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudFggfHwgMF1cbiAgICAgICAgY29udHJvbC56SW5kZXggPSBkZXNjcmlwdG9yLnpJbmRleCB8fCAwXG4gICAgICAgIGNvbnRyb2wub3JkZXIgPSBkZXNjcmlwdG9yLm9yZGVyIHx8IDBcbiAgICAgICAgY29udHJvbC5jaGFpbk9yZGVyID0gKGRlc2NyaXB0b3IuY2hhaW5PcmRlciA/IGRlc2NyaXB0b3Iuek9yZGVyKSArIChwYXJlbnQ/LmNoYWluT3JkZXIgfHwgMClcbiAgICAgICAgaWYgZGVzY3JpcHRvci56b29tP1xuICAgICAgICAgICAgY29udHJvbC56b29tID0geDogZGVzY3JpcHRvci56b29tWzBdIC8gMTAwLCB5OiBkZXNjcmlwdG9yLnpvb21bMV0gLyAxMDBcbiAgICAgICAgI2NvbnRyb2wuZGF0YUZpZWxkcyA9IGRhdGFGaWVsZHNcbiAgICAgICAgI2NvbnRyb2wuY29udHJvbGxlcnMgPSBAY29udHJvbGxlcnNcbiAgICAgICAgI2NvbnRyb2wuY29udHJvbGxlciA9IGNvbnRyb2xsZXJcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IudmlzaWJsZT9cbiAgICAgICAgICAgIGNvbnRyb2wudmlzaWJsZSA9IGRlc2NyaXB0b3IudmlzaWJsZVxuICAgICAgICBpZiBkZXNjcmlwdG9yLmNsaXBSZWN0XG4gICAgICAgICAgICBjb250cm9sLmNsaXBSZWN0ID0gbmV3IFJlY3QoY29udHJvbC5kc3RSZWN0LngsIGNvbnRyb2wuZHN0UmVjdC55LCBjb250cm9sLmRzdFJlY3Qud2lkdGgsIGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQpXG5cbiAgICAgICAgaWYgZGVzY3JpcHRvci5zdHlsZXM/XG4gICAgICAgICAgICBAYWRkQ29udHJvbFN0eWxlcyhjb250cm9sLCBkZXNjcmlwdG9yLnN0eWxlcylcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci50ZW1wbGF0ZT9cbiAgICAgICAgICAgIGNvbnRyb2wuYmVoYXZpb3IubWFuYWdlbWVudE1vZGUgPSB1aS5MYXlvdXRNYW5hZ2VtZW50TW9kZS5mcm9tU3RyaW5nKGRlc2NyaXB0b3IubWFuYWdlbWVudE1vZGUpXG4gICAgICAgICAgICBkYXRhID0gdWkuQ29tcG9uZW50X0Zvcm11bGFIYW5kbGVyLmZpZWxkVmFsdWUoY29udHJvbCwgY29udHJvbC5kYXRhRmllbGQpICNjb250cm9sLmRhdGFGaWVsZHNbY29udHJvbC5kYXRhRmllbGRdXG4gICAgICAgICAgICBpc051bWJlciA9IHR5cGVvZiBkYXRhID09IFwibnVtYmVyXCJcbiAgICAgICAgICAgIGlmIGRhdGE/XG4gICAgICAgICAgICAgICAgZm9yIGkgaW4gWzAuLi4oZGF0YS5sZW5ndGggPyBkYXRhKV1cbiAgICAgICAgICAgICAgICAgICAgaWYgZGF0YVtpXT8gb3IgaXNOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkID0geWVzXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmRhdGFGaWx0ZXI/IGFuZCBub3QgaXNOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IHVpLkNvbXBvbmVudF9IYW5kbGVyLmNoZWNrQ29uZGl0aW9uKGRhdGFbaV0sIGRlc2NyaXB0b3IuZGF0YUZpbHRlcilcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHZhbGlkIG9yIGlzTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBAY3JlYXRlQ29udHJvbEZyb21EZXNjcmlwdG9yKGRlc2NyaXB0b3IudGVtcGxhdGUsIGNvbnRyb2wsIGkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgI2NoaWxkLmRhdGFGaWVsZHMgPSBjb250cm9sLmRhdGFGaWVsZHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBkYXRhW2ldPy5kc3RSZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmRzdFJlY3QgPSB1aS5VSUVsZW1lbnRSZWN0YW5nbGUuZnJvbVJlY3QoY2hpbGQsIGRhdGFbaV0uZHN0UmVjdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm90IGNoaWxkLmNsaXBSZWN0PykgYW5kIGNvbnRyb2wuY2xpcFJlY3Q/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmNsaXBSZWN0ID0gY29udHJvbC5jbGlwUmVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICNjaGlsZC5wYXJlbnQgPSBjb250cm9sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hZGRPYmplY3QoY2hpbGQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuaW5kZXggPSBpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQub3JkZXIgPSAoZGF0YS5sZW5ndGggPyBkYXRhKSAtIGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLmNvbnRyb2xzLnB1c2goY2hpbGQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmNvbnRyb2xzIGFuZCBkZXNjcmlwdG9yLmNvbnRyb2xzLmV4ZWNcbiAgICAgICAgICAgIGNvbnRyb2xzID0gdWkuQ29tcG9uZW50X0Zvcm11bGFIYW5kbGVyLmZpZWxkVmFsdWUoZGVzY3JpcHRvciwgZGVzY3JpcHRvci5jb250cm9scylcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29udHJvbHMgPSBkZXNjcmlwdG9yLmNvbnRyb2xzXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgY29udHJvbHM/XG4gICAgICAgICAgICBmb3IgaXRlbSwgaSBpbiBjb250cm9sc1xuICAgICAgICAgICAgICAgIGNoaWxkQ29udHJvbCA9IEBfY3JlYXRlRnJvbURlc2NyaXB0b3IoaXRlbSwgY29udHJvbCwgaSlcbiAgICAgICAgICAgICAgICBpZiAobm90IGNoaWxkQ29udHJvbC5jbGlwUmVjdD8pIGFuZCBjb250cm9sLmNsaXBSZWN0P1xuICAgICAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wuY2xpcFJlY3QgPSBjb250cm9sLmNsaXBSZWN0XG4gICAgICAgICAgICAgICAgY2hpbGRDb250cm9sLmluZGV4ID0gaVxuICAgICAgICAgICAgICAgIGNoaWxkQ29udHJvbC5vcmlnaW4ueCA9IGNvbnRyb2wub3JpZ2luLnggKyBjb250cm9sLmRzdFJlY3QueFxuICAgICAgICAgICAgICAgIGNoaWxkQ29udHJvbC5vcmlnaW4ueSA9IGNvbnRyb2wub3JpZ2luLnkgKyBjb250cm9sLmRzdFJlY3QueVxuICAgICAgICAgICAgICAgICNjaGlsZENvbnRyb2wucGFyZW50ID0gY29udHJvbFxuICAgICAgICAgICAgICAgIGNvbnRyb2wuYWRkT2JqZWN0KGNoaWxkQ29udHJvbClcbiAgICAgICAgICAgICAgICBjb250cm9sLmNvbnRyb2xzLnB1c2goY2hpbGRDb250cm9sKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICBpZiBjb250cm9sLnN0eWxlcyBhbmQgY29udHJvbC5wYXJlbnRzQnlTdHlsZVxuICAgICAgICAgICAgI2ZvciBzdHlsZSBpbiBjb250cm9sLnN0eWxlc1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBwYXJlbnQgPSBjb250cm9sLnBhcmVudFxuICAgICAgICAgICAgd2hpbGUgcGFyZW50XG4gICAgICAgICAgICAgICAgaWYgcGFyZW50LnN0eWxlc1xuICAgICAgICAgICAgICAgICAgICBmb3Igc3R5bGUgaW4gcGFyZW50LnN0eWxlc1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgIWNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5wYXJlbnRzQnlTdHlsZVtzdHlsZS5pZF0gPSBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5wYXJlbnRzQnlTdHlsZVtzdHlsZS5pZF0ucHVzaChwYXJlbnQpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgI3doaWxlIHBhcmVudFxuICAgICAgICAgICAgICAgICAgICAjaWYgcGFyZW50LmNvbnRyb2xzQnlTdHlsZVxuICAgICAgICAgICAgICAgICAgICAjICAgIGlmKCFwYXJlbnQuY29udHJvbHNCeVN0eWxlW3N0eWxlLmlkXSlcbiAgICAgICAgICAgICAgICAgICAgIyAgICAgICAgcGFyZW50LmNvbnRyb2xzQnlTdHlsZVtzdHlsZS5pZF0gPSBbXVxuICAgICAgICAgICAgICAgICAgICAjICAgIHBhcmVudC5jb250cm9sc0J5U3R5bGVbc3R5bGUuaWRdLnB1c2goY29udHJvbClcbiAgICAgICAgICAgICAgICAgICMgIGlmIGNvbnRyb2wucGFyZW50c0J5U3R5bGVcbiAgICAgICAgICAgICAgICAgICMgICAgICBpZiAhY29udHJvbC5wYXJlbnRzQnlTdHlsZVtzdHlsZS5pZF1cbiAgICAgICAgICAgICAgICAgICMgICAgICAgICAgY29udHJvbC5wYXJlbnRzQnlTdHlsZVtzdHlsZS5pZF0gPSBbXVxuICAgICAgICAgICAgICAgICAgIyAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdLnB1c2gocGFyZW50KVxuICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmFuaW1hdGlvbnM/XG4gICAgICAgICAgICBjb250cm9sLmFuaW1hdGlvbnMgPSBPYmplY3QuZGVlcENvcHkoZGVzY3JpcHRvci5hbmltYXRpb25zKVxuICAgICAgICAgICAgY29udHJvbC5hbmltYXRpb25FeGVjdXRvciA9IG5ldyB1aS5Db21wb25lbnRfQW5pbWF0aW9uRXhlY3V0b3IoKVxuICAgICAgICAgICAgY29udHJvbC5hZGRDb21wb25lbnQoY29udHJvbC5hbmltYXRpb25FeGVjdXRvcilcbiAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQW5pbWF0aW9uSGFuZGxlcigpKVxuICAgICAgICAgXG4gICAgICAgIGNvbnRyb2wudWkudXBkYXRlU3R5bGUoKVxuICAgICAgICBjb250cm9sLnNldHVwKClcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gVUkgb2JqZWN0IGZyb20gYSBzcGVjaWZpZWQgVUkgZGVzY3JpcHRvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIF9jcmVhdGVGcm9tRGVzY3JpcHRvclxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcGFyYW0ge2dzLk9iamVjdF9VSUVsZW1lbnR9IHBhcmVudCAtIFRoZSBVSSBwYXJlbnQgb2JqZWN0LiAoQSBsYXlvdXQgZm9yIGV4YW1wbGUpLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgVUkgb2JqZWN0LlxuICAgICogQHByb3RlY3RlZCBcbiAgICAjIyMgICBcbiAgICBfY3JlYXRlRnJvbURlc2NyaXB0b3I6IChkZXNjcmlwdG9yLCBwYXJlbnQsIGluZGV4KSAtPiAgICAgXG4gICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlQ29udHJvbEZyb21EZXNjcmlwdG9yKGRlc2NyaXB0b3IsIHBhcmVudCwgaW5kZXgpXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmNvbnRyb2xsZXI/XG4gICAgICAgICAgICBjb250cm9sbGVyID0gQGNvbnRyb2xsZXJzW2Rlc2NyaXB0b3IuY29udHJvbGxlcl1cbiAgICAgICAgICAgIGNvbnRyb2wuY29udHJvbGxlciA9IGNvbnRyb2xsZXJcbiAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbnRyb2xsZXIpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgICAgIFxuICAgIGNyZWF0ZUxheW91dEZyb21EZXNjcmlwdG9yOiAoZGVzY3JpcHRvciwgcGFyZW50LCBpbmRleCkgLT5cbiAgICAgICAgQF9jcmVhdGVGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLCBwYXJlbnQsIGluZGV4KVxuICAgICAgICBcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgXG5HcmFwaGljcy53aWR0aCA9ICRQQVJBTVMucmVzb2x1dGlvbi53aWR0aFxuR3JhcGhpY3MuaGVpZ2h0ID0gJFBBUkFNUy5yZXNvbHV0aW9uLmhlaWdodFxudWkuVWlGYWN0b3J5ID0gbmV3IFVJTWFuYWdlcigpXG51aS5VSU1hbmFnZXIgPSB1aS5VaUZhY3RvcnkiXX0=\n//# sourceURL=UIManager_103.js"
12 + "compiledContent": "var Formula, Space, Style, UIManager;\n\nFormula = (function() {\n\n /**\n * Encapsulates a UI formula. A formula can be used in UI layouts to define\n * property-bindings or to implement a specific behavior.\n *\n * @module ui\n * @class Formula\n * @memberof ui\n * @constructor\n * @param {Function} f - The formula-function. Defines the logic of the formula.\n * @param {Object} data - An optional data-object which can be accessed inside the formula-function.\n * @param {string} event - An optional event-name to define when the formula should be executed.\n */\n function Formula(f, data, event) {\n\n /**\n * Indicates if its the first time the formula is called.\n * @property onInitialize\n * @type boolean\n */\n var i, j, l, ref, ref1;\n this.onInitialize = true;\n\n /**\n * The formula-function.\n * @property exec_\n * @type Function\n */\n this.exec_ = f;\n\n /**\n * An optional data-object which can bes accessed inside the formula-function.\n * @property data\n * @type Object\n */\n this.data = data;\n\n /**\n * An optional event-name to define when the formula should be executed.\n * @property event\n * @type string\n */\n this.event = event;\n\n /**\n * An array of custom number-data which can be used for different purposes. The first element\n * is also used in onChange method to store the old value and check against the new one to detect a change.\n * @property numbers\n * @type number[]\n */\n this.numbers = new Array(10);\n for (i = j = 0, ref = this.numbers.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {\n this.numbers[i] = 0;\n }\n\n /**\n * An array of custom string-data which can be used for different purposes. The first element\n * is also used in onTextChange method to store the old value and check against the new one to detect a change.\n * @property strings\n * @type string[]\n */\n this.strings = new Array(10);\n for (i = l = 0, ref1 = this.strings.length; 0 <= ref1 ? l <= ref1 : l >= ref1; i = 0 <= ref1 ? ++l : --l) {\n this.strings[i] = \"\";\n }\n }\n\n\n /**\n * The formula-function. Its a wrapper-function before the first-time call was made.\n * @method exec\n */\n\n Formula.prototype.exec = function() {\n var r;\n this.exec = this.exec_;\n r = this.exec_.apply(this, arguments);\n this.onInitialize = false;\n return r;\n };\n\n\n /**\n * Checks if the specified number-value has changed since the last check. It uses\n * the first entry of the numbers-array to store the value and check against the new one.\n *\n * @method onChange\n * @param {number} numberValue - Number value to check.\n */\n\n Formula.prototype.onChange = function(numberValue) {\n var result;\n result = this.numbers[0] !== numberValue;\n this.numbers[0] = numberValue;\n return result;\n };\n\n\n /**\n * Checks if the specified text-value has changed since the last check. It uses\n * the first entry of the strings-array to store the value and check against the new one.\n *\n * @method onTextChange\n * @param {string} textValue - Text value to check.\n */\n\n Formula.prototype.onTextChange = function(textValue) {\n var result;\n result = this.strings[0] !== textValue;\n this.strings[0] = textValue;\n return result;\n };\n\n return Formula;\n\n})();\n\nui.Formula = Formula;\n\nSpace = (function() {\n\n /**\n * Describes a space inside or around something like a margin or padding.\n *\n * @module ui\n * @class Space\n * @memberof ui\n * @constructor\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n */\n function Space(left, top, right, bottom) {\n\n /**\n * Space at the left in pixels.\n * @property left\n * @type number\n */\n this.left = left;\n\n /**\n * Space at the top in pixels.\n * @property top\n * @type number\n */\n this.top = top;\n\n /**\n * Space at the right in pixels.\n * @property right\n * @type number\n */\n this.right = right;\n\n /**\n * Space at the bottom in pixels.\n * @property bottom\n * @type number\n */\n this.bottom = bottom;\n }\n\n\n /**\n * Sets the coordinates of the space by copying them from a specified space.\n *\n * @method setFromObject\n * @param {Object} space - A space to copy.\n */\n\n Space.prototype.setFromObject = function(space) {\n this.left = space.left;\n this.top = space.top;\n this.right = space.right;\n return this.bottom = space.bottom;\n };\n\n\n /**\n * Sets the coordinates of the space.\n *\n * @method set\n * @param {number} left - Space at the left in pixels.\n * @param {number} top - Space at the top in pixels.\n * @param {number} right - Space at the right in pixels.\n * @param {number} bottom - Space at the bottom in pixels.\n */\n\n Space.prototype.set = function(left, top, right, bottom) {\n this.left = left;\n this.top = top;\n this.right = right;\n return this.bottom = bottom;\n };\n\n\n /**\n * Creates a new space object from an array of coordinates.\n *\n * @method fromArray\n * @static\n * @param {number[]} array - An array of coordinates (left, top right, bottom).\n */\n\n Space.fromArray = function(array) {\n return new ui.Space(array[0], array[1], array[2], array[3]);\n };\n\n return Space;\n\n})();\n\nui.Space = Space;\n\nStyle = (function() {\n\n /**\n * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain \"style\" to it.\n *\n * @module ui\n * @class Style\n * @memberof ui\n * @constructor\n * @param {Object} descriptor - A style-descriptor to initialize the style from.\n * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.\n * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.\n */\n function Style(descriptor, id, selector) {\n\n /**\n * ID number to quickly access this style and link to this style.\n * @property id\n * @type number\n */\n this.id = id;\n\n /**\n * Style-ID of target object. This style will only be applied on UI objects with that style ID which are\n * children of UI objects where this style is applied.\n * @property target\n * @type number\n */\n this.target = -1;\n\n /**\n * Selector-ID which controls under which conditions the style becomes active.\n * @property selector\n * @type number\n */\n this.selector = selector;\n\n /**\n * The font used for the text-display.\n * @default null\n * @property font\n * @type gs.Font\n */\n this.font = null;\n\n /**\n * The UI object's image used for visual presentation.\n * @property image\n * @type string\n */\n this.image = null;\n\n /**\n * The UI object's animations used for visual presentation.\n * @default null\n * @property animations\n * @type Object[]\n */\n this.animations = null;\n\n /**\n * The UI object's color.\n * @property color\n * @type gs.Color\n */\n this.color = null;\n\n /**\n * The UI object's tone.\n * @property tone\n * @type gs.Tone\n */\n this.tone = null;\n\n /**\n * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner\n * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1\n * places the object with its lower-right corner.\n * @property anchor\n * @type gs.Point\n */\n this.anchor = null;\n\n /**\n * The UI object's zoom-setting for x and y axis.\n * @default new gs.Point(1.0, 1.0)\n * @property zoom\n * @type gs.Point\n */\n this.zoom = null;\n\n /**\n * The UI object's margin. The margin defines an extra space around the UI object. \n * The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property margin\n * @type Object\n */\n this.margin = null;\n\n /**\n * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n * @property padding\n * @type Object\n */\n this.padding = null;\n\n /**\n * The UI object's mask for masking-effects.\n * @property mask\n * @type gs.Mask\n */\n this.mask = null;\n\n /**\n * The UI object's alignment.\n * @property alignment\n * @type ui.Alignment\n */\n this.alignment = -1;\n\n /**\n * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.\n * @property opacity\n * @type number\n */\n this.opacity = -1;\n\n /**\n * The object's clip-rect for visual presentation.\n * @default null\n * @property clipRect\n * @type gs.Rect\n * @protected\n */\n this.clipRect = null;\n\n /**\n * The corner-size of the frame.\n * @property frameCornerSize\n * @type number\n */\n this.frameCornerSize = -1;\n\n /**\n * The thickness of the frame.\n * @property frameThickness\n * @type number\n */\n this.frameThickness = -1;\n\n /**\n * The looping of the image.\n * @property looping\n * @type ui.Orientation\n */\n this.looping = null;\n\n /**\n * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered\n * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it\n * should have the largest z-index of all game objects.\n * @property zIndex\n * @type number\n */\n this.zIndex = -1;\n\n /**\n * The object's alignment on x-axis. Needs to be supported by layout.\n * @property alignmentX\n * @type number\n */\n this.alignmentX = -1;\n\n /**\n * The object's alignment on y-axis. Needs to be supported by layout.\n * @property alignmentY\n * @type number\n */\n this.alignmentY = -1;\n\n /**\n * The object's resize behavior.\n * @property resizable\n * @type boolean\n */\n this.resizable = null;\n\n /**\n * The original style descriptor.\n * @property descriptor\n * @type Object\n */\n this.descriptor = descriptor;\n if (descriptor) {\n this.setFromDescriptor(descriptor);\n }\n }\n\n\n /**\n * Initializes the style from a style-descriptor.\n *\n * @method setFromDescriptor\n * @param {Object} descriptor - The style-descriptor.\n */\n\n Style.prototype.setFromDescriptor = function(descriptor) {\n this.descriptor = descriptor;\n this.image = descriptor.image;\n if (descriptor.color) {\n this.color = gs.Color.fromArray(descriptor.color);\n }\n if (descriptor.tone) {\n this.tone = gs.Tone.fromArray(descriptor.tone);\n }\n if (descriptor.anchor) {\n this.anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]);\n }\n if (descriptor.zoom) {\n this.zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]);\n }\n if (descriptor.font) {\n this.setupFont(descriptor);\n }\n if (descriptor.clipRect) {\n this.clipRect = gs.Rect.fromArray(descriptor.clipRect);\n }\n if (descriptor.opacity >= 0) {\n this.opacity = descriptor.opacity;\n }\n if (descriptor.alignment >= 0) {\n this.alignment = descriptor.alignment;\n }\n if (descriptor.margin) {\n this.margin = ui.Space.fromArray(descriptor.margin);\n }\n if (descriptor.padding) {\n this.padding = ui.Space.fromArray(descriptor.padding);\n }\n this.animations = descriptor.animations;\n if (descriptor.frameCornerSize) {\n this.frameCornerSize = descriptor.frameCornerSize;\n }\n if (descriptor.frameThickness) {\n this.frameThickness = descriptor.frameThickness;\n }\n if (descriptor.frame) {\n this.frame = descriptor.frame;\n }\n if (descriptor.looping) {\n this.looping = descriptor.looping;\n }\n if (descriptor.resizable != null) {\n this.resizable = descriptor.resizable;\n }\n if (descriptor.zIndex) {\n this.zIndex = descriptor.zIndex;\n }\n if (descriptor.alignmentX) {\n this.alignmentX = ui.UIManager.alignments[descriptor.alignmentX];\n }\n if (descriptor.alignmentY) {\n return this.alignmentY = ui.UIManager.alignments[descriptor.alignmentY];\n }\n };\n\n Style.prototype.set = function(style) {\n this.image = style.image;\n this.color.setFromObject(style.color);\n this.tone.setFromObject(style.tone);\n this.anchor.set(style.anchor.x, style.anchor.y);\n this.zoom.set(style.zoom.x, style.zoom.y);\n if (style.font) {\n if (!this.font) {\n this.font = new gs.Font(style.font.name, style.font.size);\n }\n this.font.set(style.font);\n }\n if (style.clipRect) {\n if (!this.clipRect) {\n this.clipRect = new gs.Rect();\n }\n this.clipRect.setFromObject(style.clipRect);\n }\n this.opacity = style.opacitz;\n this.alignment = style.alignment;\n this.margin.setFromObject(style.margin);\n return this.padding.setFromObject(style.padding);\n };\n\n\n /**\n * Initializes font-data from a style-descriptor.\n *\n * @method setupFont\n * @param {Object} descriptor - The style-descriptor.\n * @protected\n */\n\n Style.prototype.setupFont = function(descriptor) {\n var ref, ref1, ref10, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9;\n if (descriptor.font) {\n if (!this.font) {\n this.font = new Font(descriptor.font.name, (ref = descriptor.font.size) != null ? ref : 0);\n } else {\n this.font.name = descriptor.font.name;\n this.font.size = (ref1 = descriptor.font.size) != null ? ref1 : 0;\n }\n this.font.bold = (ref2 = descriptor.font.bold) != null ? ref2 : this.font.bold;\n this.font.italic = (ref3 = descriptor.font.italic) != null ? ref3 : this.font.italic;\n this.font.smallCaps = (ref4 = descriptor.font.smallCaps) != null ? ref4 : this.font.smallCaps;\n this.font.underline = (ref5 = descriptor.font.underline) != null ? ref5 : this.font.underline;\n this.font.strikeThrough = (ref6 = descriptor.font.strikeThrough) != null ? ref6 : this.font.strikeThrough;\n if (descriptor.font.color != null) {\n this.font.color.setFromArray(descriptor.font.color);\n }\n if (descriptor.font.border != null) {\n this.font.border = (ref7 = descriptor.font.border) != null ? ref7 : false;\n this.font.borderSize = (ref8 = descriptor.font.borderSize) != null ? ref8 : 4;\n this.font.borderColor.set(0, 0, 0, 255);\n }\n if (descriptor.font.outline != null) {\n this.font.border = (ref9 = descriptor.font.outline) != null ? ref9 : false;\n this.font.borderSize = (ref10 = descriptor.font.outline.size) != null ? ref10 : 4;\n if (descriptor.font.outline.color != null) {\n return this.font.borderColor.setFromArray(descriptor.font.outline.color);\n } else {\n return this.font.borderColor.set(0, 0, 0, 255);\n }\n }\n }\n };\n\n\n /**\n * Applies the style to a UI object.\n *\n * @method apply\n * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.\n */\n\n Style.prototype.apply = function(object) {\n var ref, ref1;\n if (!object.activeStyles.contains(this)) {\n object.activeStyles.push(this);\n if (this.font) {\n if ((ref = object.font) != null) {\n ref.set(this.font);\n }\n }\n if (this.color) {\n object.color.set(this.color);\n }\n if (this.tone) {\n if ((ref1 = object.tone) != null) {\n ref1.set(this.tone);\n }\n }\n if (this.image) {\n object.image = this.image;\n }\n if (this.anchor) {\n object.anchor.set(this.anchor.x, this.anchor.y);\n }\n if (this.zoom) {\n object.zoom.set(this.zoom.x, this.zoom.y);\n }\n if (this.padding) {\n object.padding.setFromObject(this.padding);\n }\n if (this.margin) {\n object.margin.setFromObject(this.margin);\n }\n if (this.opacity >= 0) {\n object.opacity = this.opacity;\n }\n if (this.alignment >= 0) {\n object.alignment = this.alignment;\n }\n if (this.frameThickness >= 0) {\n object.frameThickness = this.frameThickness;\n }\n if (this.frameCornerSize >= 0) {\n object.frameCornerSize = this.frameCornerSize;\n }\n if (this.mask) {\n object.mask.set(this.mask);\n }\n if (this.zIndex >= 0) {\n object.zIndex = this.zIndex;\n }\n if (this.alignmentX >= 0) {\n object.alignmentX = this.alignmentX;\n }\n if (this.alignmentY >= 0) {\n object.alignmentY = this.alignmentY;\n }\n if (this.resizable != null) {\n object.resizable = this.resizable;\n }\n this.applyLooping(object);\n return this.applyAnimations(object);\n }\n };\n\n\n /**\n * Applies the looping-data of the style to a UI object.\n *\n * @method applyLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.\n * @protected\n */\n\n Style.prototype.applyLooping = function(object) {\n if (this.looping) {\n if (!object.visual.looping) {\n object.visual.dispose();\n object.removeComponent(object.visual);\n object.visual = new gs.Component_TilingSprite();\n object.addComponent(object.visual);\n }\n object.visual.looping.vertical = this.looping.vertical;\n return object.visual.looping.horizontal = this.looping.horizontal;\n }\n };\n\n\n /**\n * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler\n * component(ui.Component_AnimationHandler) with the id \"animationHandler\" to the UI object if not already exists.\n *\n * @method applyAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.\n * @protected\n */\n\n Style.prototype.applyAnimations = function(object) {\n if (this.animations) {\n object.animations = Object.deepCopy(this.animations);\n if (!object.findComponentById(\"animationHandler\")) {\n object.animationExecutor = new ui.Component_AnimationExecutor();\n object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\");\n return object.addComponent(object.animationExecutor, \"animationExecutor\");\n }\n }\n };\n\n\n /**\n * Reverts the changes from a UI object made by this style. However, this resets all styleable properties\n * were set by this style. So it is necessary to apply all other styles again, but that is already handles in\n * ui.Component_UIBehavior.\n *\n * @method revert\n * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.\n */\n\n Style.prototype.revert = function(object) {\n var activeStyles, i1, j, j1, k1, l, l1, m1, n, o, p, q, ref, ref1, s, t, u, w, x, y, z;\n activeStyles = object.activeStyles;\n if (object.activeStyles.contains(this)) {\n object.activeStyles.remove(this);\n if (this.font) {\n object.font.set(gs.Fonts.TEXT);\n for (j = activeStyles.length - 1; j >= 0; j += -1) {\n s = activeStyles[j];\n if (s.font) {\n object.font.set(s.font);\n break;\n }\n }\n }\n if (this.color) {\n object.color.set(Color.WHITE);\n for (l = activeStyles.length - 1; l >= 0; l += -1) {\n s = activeStyles[l];\n if (s.color) {\n object.color.set(s.color);\n break;\n }\n }\n }\n if (this.tone) {\n if ((ref = object.tone) != null) {\n ref.set(0, 0, 0, 0);\n }\n for (n = activeStyles.length - 1; n >= 0; n += -1) {\n s = activeStyles[n];\n if (s.tone) {\n if ((ref1 = object.tone) != null) {\n ref1.set(s.tone);\n }\n break;\n }\n }\n }\n if (this.image) {\n object.image = null;\n for (o = activeStyles.length - 1; o >= 0; o += -1) {\n s = activeStyles[o];\n if (s.image) {\n object.image = s.image;\n break;\n }\n }\n }\n if (this.anchor) {\n object.anchor.set(0, 0);\n for (p = activeStyles.length - 1; p >= 0; p += -1) {\n s = activeStyles[p];\n if (s.anchor) {\n object.anchor.setFromObject(s.anchor);\n break;\n }\n }\n }\n if (this.zoom) {\n object.zoom.set(1.0, 1.0);\n for (q = activeStyles.length - 1; q >= 0; q += -1) {\n s = activeStyles[q];\n if (s.zoom) {\n object.zoom.setFromObject(s.zoom);\n break;\n }\n }\n }\n if (this.padding) {\n object.padding.set(0, 0, 0, 0);\n for (t = activeStyles.length - 1; t >= 0; t += -1) {\n s = activeStyles[t];\n if (s.padding) {\n object.padding.setFromObject(s.padding);\n break;\n }\n }\n }\n if (this.margin) {\n object.margin.set(0, 0, 0, 0);\n for (u = activeStyles.length - 1; u >= 0; u += -1) {\n s = activeStyles[u];\n if (s.margin) {\n object.margin.setFromObject(s.margin);\n break;\n }\n }\n }\n if (this.opacity >= 0) {\n object.opacity = 255;\n for (w = activeStyles.length - 1; w >= 0; w += -1) {\n s = activeStyles[w];\n if (s.opacity >= 0) {\n object.opacity = s.opacity;\n break;\n }\n }\n }\n if (this.alignment >= 0) {\n object.alignment = 0;\n for (x = activeStyles.length - 1; x >= 0; x += -1) {\n s = activeStyles[x];\n if (s.alignment >= 0) {\n object.alignment = s.alignment;\n break;\n }\n }\n }\n if (this.frameCornerSize >= 0) {\n object.frameCornerSize = 16;\n for (y = activeStyles.length - 1; y >= 0; y += -1) {\n s = activeStyles[y];\n if (s.frameCornerSize >= 0) {\n object.frameCornerSize = s.frameCornerSize;\n break;\n }\n }\n }\n if (this.frameThickness >= 0) {\n object.frameThickness = 16;\n for (z = activeStyles.length - 1; z >= 0; z += -1) {\n s = activeStyles[z];\n if (s.frameThickness >= 0) {\n object.frameThickness = s.frameThickness;\n break;\n }\n }\n }\n if (this.mask) {\n object.mask.set(null);\n for (i1 = activeStyles.length - 1; i1 >= 0; i1 += -1) {\n s = activeStyles[i1];\n if (s.mask) {\n object.mask.set(s.font);\n break;\n }\n }\n }\n if (this.zIndex >= 0) {\n object.zIndex = 0;\n for (j1 = activeStyles.length - 1; j1 >= 0; j1 += -1) {\n s = activeStyles[j1];\n if (s.zIndex >= 0) {\n object.zIndex = s.zIndex;\n break;\n }\n }\n }\n if (this.alignmentX >= 0) {\n object.alignmentX = 0;\n for (k1 = activeStyles.length - 1; k1 >= 0; k1 += -1) {\n s = activeStyles[k1];\n if (s.alignmentX >= 0) {\n object.alignmentX = s.alignmentX;\n break;\n }\n }\n }\n if (this.alignmentY >= 0) {\n object.alignmentY = 0;\n for (l1 = activeStyles.length - 1; l1 >= 0; l1 += -1) {\n s = activeStyles[l1];\n if (s.alignmentY >= 0) {\n object.alignmentY = s.alignmentY;\n break;\n }\n }\n }\n if (this.resizable != null) {\n object.resizable = false;\n for (m1 = activeStyles.length - 1; m1 >= 0; m1 += -1) {\n s = activeStyles[m1];\n if (s.resizable != null) {\n object.resizable = s.resizable;\n break;\n }\n }\n }\n this.revertAnimations(object);\n return this.revertLooping(object);\n }\n };\n\n\n /**\n * Reverts the animation-data changes applied to a UI object by this style.\n *\n * @method revertAnimations\n * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.\n */\n\n Style.prototype.revertAnimations = function(object) {\n var activeStyles, j, results, s;\n activeStyles = object.activeStyles;\n if (this.animations) {\n object.animations = null;\n results = [];\n for (j = activeStyles.length - 1; j >= 0; j += -1) {\n s = activeStyles[j];\n if (s.animations) {\n object.animations = Object.deepCopy(s.animations);\n if (!object.findComponentById(\"animationHandler\")) {\n results.push(object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\"));\n } else {\n results.push(void 0);\n }\n } else {\n results.push(void 0);\n }\n }\n return results;\n }\n };\n\n\n /**\n * Reverts the looping-data changes applied to a UI object by this style.\n *\n * @method revertLooping\n * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.\n */\n\n Style.prototype.revertLooping = function(object) {\n var activeStyles, j, results, s;\n activeStyles = object.activeStyles;\n if (this.looping) {\n object.visual.looping.vertical = false;\n object.visual.looping.horizontal = false;\n results = [];\n for (j = activeStyles.length - 1; j >= 0; j += -1) {\n s = activeStyles[j];\n if (s.looping) {\n if (!object.visual.looping) {\n object.visual.dispose();\n object.removeComponent(object.visual);\n object.visual = new gs.Component_TilingSprite();\n object.addComponent(object.visual);\n }\n object.visual.looping.vertical = s.looping.vertical;\n results.push(object.visual.looping.horizontal = s.looping.horizontal);\n } else {\n results.push(void 0);\n }\n }\n return results;\n }\n };\n\n return Style;\n\n})();\n\nui.Style = Style;\n\nUIManager = (function() {\n\n /**\n * Handles the creation of In Game UI elements. For more information about\n * In-Game UI see help file.\n *\n * @module ui\n * @class UIManager\n * @memberof ui\n * @constructor\n */\n function UIManager() {\n\n /**\n * Stores all registered UI layouts by name/id.\n * @property layouts\n * @type Object\n */\n this.layouts = {};\n\n /**\n * Stores all registered UI styles by name/id.\n * @property styles\n * @type Object\n */\n this.styles = {};\n\n /**\n * Stores all UI styles by number id.\n * @property stylesById\n * @type ui.Style[]\n */\n this.stylesById = new Array();\n\n /**\n * Stores all UI styles by style-name.\n * @property stylesByName\n * @type Object\n */\n this.stylesByName = {};\n\n /**\n * Stores all registered custom UI types/templates by name/id.\n * @property customTypes\n * @type Object\n */\n this.customTypes = {};\n\n /**\n * Stores all registered UI controllers by name/id.\n * @property customTypes\n * @type Object\n */\n this.controllers = {};\n\n /**\n * Stores all registered UI data sources by name/id.\n * @property customTypes\n * @type Object\n */\n this.dataSources = {};\n\n /**\n * Mapping to table to map alignment names to number values.\n * @property alignments\n * @type Object\n * @protected\n */\n this.alignments = {\n \"left\": 0,\n \"top\": 0,\n \"center\": 1,\n \"bottom\": 2,\n \"right\": 2,\n \"0\": 0,\n \"1\": 1,\n \"2\": 2\n };\n\n /**\n * Mapping to table to map blend-mode names to number values.\n * @property blendModes\n * @type Object\n * @protected\n */\n this.blendModes = {\n \"normal\": 0,\n \"add\": 1,\n \"sub\": 2\n };\n\n /**\n * Mapping to table to map selector names to number values.\n * @property selectors\n * @type Object\n */\n this.selectors = {\n normal: 0,\n hover: 1,\n selected: 2,\n enabled: 3,\n focused: 4\n };\n this.defaultPlaceholderParams = {};\n }\n\n\n /**\n * Sets up UI Manager, optimizes styles, etc.\n *\n * @method setup\n */\n\n UIManager.prototype.setup = function() {\n return this.setupStyles();\n };\n\n\n /**\n * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.\n *\n * @method setupStyles\n * @protected\n */\n\n UIManager.prototype.setupStyles = function() {\n var id, k, ref, selector, selectorMap, subs;\n id = 0;\n selectorMap = this.selectors;\n for (k in this.styles) {\n subs = k.split(\" \");\n selector = subs[0].split(\":\");\n if (selectorMap[selector[1]]) {\n this.stylesById[id] = new ui.Style(this.styles[k], id, selectorMap[selector[1]]);\n } else {\n this.stylesById[id] = new ui.Style(this.styles[k], id, 0);\n }\n if (!this.stylesByName[selector[0]]) {\n this.stylesByName[selector[0]] = [];\n }\n this.stylesByName[selector[0]].push(this.stylesById[id]);\n this.styles[k] = this.stylesById[id];\n id++;\n }\n for (k in this.styles) {\n subs = k.split(\" \");\n if (subs.length > 1) {\n this.stylesByName[subs[1]].push(this.styles[k]);\n this.styles[k].target = (ref = this.styles[k.split(\":\")[0]]) != null ? ref.id : void 0;\n }\n }\n return null;\n };\n\n\n /**\n * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed\n * and placeholder formulas are replaced with their evaluated result value.\n *\n * @method executePlaceholderFormulas\n * @param {Object} descriptor - The descriptor.\n * @param {Object} params - Object containing the placeholder params.\n * @protected\n */\n\n UIManager.prototype.executePlaceholderFormulas = function(descriptor, id, params) {\n var c, i, j, k, keys, l, len, len1, v;\n if (descriptor == null) {\n return;\n }\n keys = Object.keys(descriptor);\n for (j = 0, len = keys.length; j < len; j++) {\n k = keys[j];\n v = descriptor[k];\n if (v != null) {\n if (v instanceof Array) {\n for (c = l = 0, len1 = v.length; l < len1; c = ++l) {\n i = v[c];\n if (i != null) {\n if (typeof i === \"object\") {\n this.executePlaceholderFormulas(i, id, params);\n } else if (c !== \"exec\" && typeof i === \"function\") {\n window.p = params || this.defaultPlaceholderParams;\n window.d = descriptor;\n v[c] = i();\n }\n }\n }\n } else if (typeof v === \"object\") {\n this.executePlaceholderFormulas(v, id, params);\n } else if (k !== \"exec_\" && typeof v === \"function\") {\n window.p = params || this.defaultPlaceholderParams;\n window.d = descriptor;\n descriptor[k] = v();\n }\n }\n }\n return null;\n };\n\n\n /**\n * Creates a calculation for a specified expression.\n *\n * @method createCalcFunction\n * @param {String} expression - The expression to create a calculation function for.\n * @return {Function} The calculation function.\n * @protected\n */\n\n UIManager.prototype.createCalcFunction = function(expression) {\n expression = expression.replace(/([0-9]+)%/gm, \"($1 / 100 * v)\");\n return eval(\"(function(v){ return \" + expression + \"})\");\n };\n\n\n /**\n * Creates an object from the specified object type. The type has the format\n * <namespace>.<typename> like vn.Component_Hotspot.\n *\n * @method createObject\n * @param {String} type - The type name.\n * @return {Object} The created object.\n * @protected\n */\n\n UIManager.prototype.createObject = function(type) {\n var subs;\n subs = type.split(\".\");\n return new window[subs[0]][subs[1]]();\n };\n\n\n /**\n * Creates an UI object from a specified UI descriptor.\n *\n * @method createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n */\n\n UIManager.prototype.createFromDescriptor = function(descriptor, parent) {\n var control, k;\n control = null;\n for (k in this.controllers) {\n if (this.controllers[k].type != null) {\n this.controllers[k] = this.createObject(this.controllers[k].type);\n }\n }\n return this._createFromDescriptor(descriptor, parent);\n };\n\n\n /**\n * Creates an image button UI object.\n *\n * @method createImageButton\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createImageButton = function(descriptor) {\n var control;\n control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling);\n control.behavior.sound = descriptor.sound;\n control.behavior.sounds = descriptor.sounds;\n control.image = descriptor.image;\n control.images = descriptor.images;\n if (descriptor.imageFolder != null) {\n control.imageFolder = descriptor.imageFolder;\n }\n if (descriptor.looping != null) {\n control.visual.dispose();\n control.removeComponent(control.visual);\n control.visual = new gs.Component_TilingSprite();\n control.addComponent(control.visual);\n control.visual.looping.vertical = descriptor.looping.vertical;\n control.visual.looping.horizontal = descriptor.looping.horizontal;\n }\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates an image UI object.\n *\n * @method createImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createImage = function(descriptor) {\n var control;\n control = new ui.Object_Image(descriptor.image, descriptor.imageHandling);\n if (descriptor.imageFolder != null) {\n control.imageFolder = descriptor.imageFolder;\n }\n if (descriptor.looping != null) {\n control.visual.dispose();\n control.removeComponent(control.visual);\n control.visual = new gs.Component_TilingSprite();\n control.addComponent(control.visual);\n control.visual.looping.vertical = descriptor.looping.vertical;\n control.visual.looping.horizontal = descriptor.looping.horizontal;\n }\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates an image map UI object.\n *\n * @method createImageMap\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createImageMap = function(descriptor) {\n var control;\n control = new ui.Object_ImageMap();\n control.hotspots = (descriptor.hotspots || []).select(function(h) {\n return {\n x: h.rect[0],\n y: h.rect[1],\n size: {\n width: h.rect[2],\n height: h.rect[3]\n },\n data: {\n action: 3,\n actions: h.actions\n }\n };\n });\n control.images = descriptor.images;\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\");\n control.target = SceneManager.scene.behavior;\n control.visual.variableContext = new gs.InterpreterContext(SceneManager.scene.layoutName, SceneManager.scene);\n return control;\n };\n\n\n /**\n * Creates a video UI object.\n *\n * @method createVideo\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createVideo = function(descriptor) {\n var control, ref;\n control = new ui.Object_Video();\n control.video = descriptor.video;\n control.loop = (ref = descriptor.loop) != null ? ref : true;\n return control;\n };\n\n\n /**\n * Creates a panel UI object.\n *\n * @method createPanel\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createPanel = function(descriptor) {\n var control, ref;\n control = new ui.Object_Panel();\n control.modal = (ref = descriptor.modal) != null ? ref : false;\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates a frame UI object.\n *\n * @method createFrame\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createFrame = function(descriptor) {\n var control;\n control = new ui.Object_Frame(descriptor.frameSkin);\n control.frameThickness = descriptor.frameThickness || 16;\n control.frameCornerSize = descriptor.frameCornerSize || 16;\n control.image = descriptor.image;\n control.images = descriptor.images;\n return control;\n };\n\n\n /**\n * Creates a three-part image UI object.\n *\n * @method createThreePartImage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createThreePartImage = function(descriptor) {\n var control;\n control = new ui.Object_ThreePartImage(descriptor.frameSkin);\n control.firstPartSize = descriptor.firstPartSize || 16;\n control.middlePartSize = descriptor.middlePartSize || 1;\n control.lastPartSize = descriptor.lastPartSize || 16;\n control.image = descriptor.image;\n control.images = descriptor.images;\n return control;\n };\n\n\n /**\n * Creates a text UI object.\n *\n * @method createText\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createText = function(descriptor) {\n var control, ref;\n control = new ui.Object_Text();\n control.text = lcs(descriptor.text);\n control.sizeToFit = descriptor.sizeToFit;\n control.formatting = descriptor.formatting;\n control.wordWrap = (ref = descriptor.wordWrap) != null ? ref : false;\n control.behavior.format = descriptor.format;\n if (descriptor.textPadding) {\n control.behavior.padding = ui.Space.fromArray(descriptor.textPadding);\n }\n if (descriptor.resolvePlaceholders != null) {\n control.resolvePlaceholders = descriptor.resolvePlaceholders;\n }\n if (descriptor.color != null) {\n control.color = Color.fromArray(descriptor.color);\n }\n return control;\n };\n\n\n /**\n * Creates a free-layout UI object.\n *\n * @method createFreeLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createFreeLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1);\n } else {\n control = new ui.Object_FreeLayout(0, 0, 1, 1);\n }\n control.sizeToFit = descriptor.sizeToFit;\n return control;\n };\n\n\n /**\n * Creates a stack-layout UI object.\n *\n * @method createStackLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createStackLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation);\n } else {\n control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation);\n }\n control.sizeToFit = descriptor.sizeToFit;\n return control;\n };\n\n\n /**\n * Creates a spread-layout UI object.\n *\n * @method createSpreadLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createSpreadLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation);\n } else {\n control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation);\n }\n return control;\n };\n\n\n /**\n * Creates a grid-layout UI object.\n *\n * @method createGridLayout\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createGridLayout = function(descriptor) {\n var control;\n if (descriptor.frame != null) {\n control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template);\n } else {\n control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template);\n }\n control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0];\n control.sizeToFit = descriptor.sizeToFit;\n return control;\n };\n\n\n /**\n * Creates a message UI object.\n *\n * @method createMessage\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createMessage = function(descriptor) {\n var control;\n control = new ui.Object_Message();\n return control;\n };\n\n\n /**\n * Creates a data-grid UI object.\n *\n * @method createDataGrid\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created image button UI object.\n */\n\n UIManager.prototype.createDataGrid = function(descriptor) {\n var control;\n control = new ui.Object_DataGrid(descriptor);\n return control;\n };\n\n\n /**\n * Creates an UI object depending on the object-type of the specified UI descriptor.\n *\n * @method createControl\n * @param {Object} descriptor - The UI object descriptor.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n */\n\n UIManager.prototype.createControl = function(descriptor) {\n var control;\n control = null;\n switch (descriptor.type) {\n case \"ui.ImageButton\":\n control = this.createImageButton(descriptor);\n break;\n case \"ui.Image\":\n control = this.createImage(descriptor);\n break;\n case \"ui.ImageMap\":\n control = this.createImageMap(descriptor);\n break;\n case \"ui.Video\":\n control = this.createVideo(descriptor);\n break;\n case \"ui.Panel\":\n control = this.createPanel(descriptor);\n break;\n case \"ui.Frame\":\n control = this.createFrame(descriptor);\n break;\n case \"ui.ThreePartImage\":\n control = this.createThreePartImage(descriptor);\n break;\n case \"ui.Text\":\n control = this.createText(descriptor);\n break;\n case \"ui.Message\":\n control = this.createMessage(descriptor);\n break;\n case \"ui.DataGrid\":\n control = this.createDataGrid(descriptor);\n break;\n case \"ui.FreeLayout\":\n control = this.createFreeLayout(descriptor);\n break;\n case \"ui.StackLayout\":\n control = this.createStackLayout(descriptor);\n break;\n case \"ui.SpreadLayout\":\n control = this.createSpreadLayout(descriptor);\n break;\n case \"ui.GridLayout\":\n control = this.createGridLayout(descriptor);\n }\n return control;\n };\n\n UIManager.prototype.createLayoutRect = function(frame, control) {\n var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7;\n if (!control.layoutRect) {\n control.layoutRect = new ui.LayoutRect();\n }\n control.layoutRect.set(0, 0, 0, 0);\n if (frame != null) {\n if (((ref = frame[0]) != null ? ref.length : void 0) != null) {\n control.layoutRect.x = this.createCalcFunction(frame[0]);\n control.dstRect.x = 0;\n } else {\n control.dstRect.x = (ref1 = descriptor.frame[0]) != null ? ref1 : control.dstRect.x;\n }\n if (((ref2 = frame[1]) != null ? ref2.length : void 0) != null) {\n control.layoutRect.y = this.createCalcFunction(frame[1]);\n control.dstRect.y = 0;\n } else {\n control.dstRect.y = (ref3 = frame[1]) != null ? ref3 : control.dstRect.y;\n }\n if (((ref4 = frame[2]) != null ? ref4.length : void 0) != null) {\n control.layoutRect.width = this.createCalcFunction(frame[2]);\n control.dstRect.width = 1;\n } else {\n control.dstRect.width = (ref5 = frame[2]) != null ? ref5 : control.dstRect.width;\n }\n if (((ref6 = frame[3]) != null ? ref6.length : void 0) != null) {\n control.layoutRect.height = this.createCalcFunction(frame[3]);\n return control.dstRect.height = 1;\n } else {\n return control.dstRect.height = (ref7 = frame[3]) != null ? ref7 : control.dstRect.height;\n }\n }\n };\n\n\n /**\n * Adds the styles defined in an array of style-names to the specified control.\n *\n * @method addControlStyles\n * @param {Object} control - The control to add the styles to.\n * @param {string[]} styles - Array of style-names to add.\n */\n\n UIManager.prototype.addControlStyles = function(control, styles) {\n var j, len, results, style, styleName;\n results = [];\n for (j = 0, len = styles.length; j < len; j++) {\n styleName = styles[j];\n if (this.stylesByName[styleName] != null) {\n results.push((function() {\n var l, len1, ref, results1;\n ref = this.stylesByName[styleName];\n results1 = [];\n for (l = 0, len1 = ref.length; l < len1; l++) {\n style = ref[l];\n control.styles.push(style);\n if (style.target === -1 && style.selector === 0) {\n results1.push(style.apply(control));\n } else {\n results1.push(void 0);\n }\n }\n return results1;\n }).call(this));\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Creates an UI object from a specified UI descriptor. This method is called\n * recursively for all child-descriptors.\n *\n * @method createControlFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @param {number} index - The index.\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n */\n\n UIManager.prototype.createControlFromDescriptor = function(descriptor, parent, index) {\n var action, actions, bindings, c, child, childControl, component, control, controls, customFields, data, formulas, i, isNumber, item, j, l, len, len1, len2, len3, m, n, o, p, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, ref19, ref2, ref20, ref21, ref22, ref23, ref24, ref25, ref26, ref27, ref3, ref4, ref5, ref6, ref7, ref8, ref9, style, target, type, typeName, valid;\n control = null;\n if (descriptor.style != null) {\n descriptor.styles = [descriptor.style];\n delete descriptor.style;\n }\n descriptor = Object.deepCopy(descriptor);\n this.executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params);\n control = this.createControl(descriptor);\n if (control == null) {\n type = Object.deepCopy(this.customTypes[descriptor.type]);\n this.executePlaceholderFormulas(type, descriptor.id, descriptor.params);\n typeName = type.type;\n customFields = type.customFields;\n bindings = type.bindings;\n formulas = type.formulas;\n actions = type.actions;\n if (type.style != null) {\n type.styles = [type.style];\n type.style = null;\n }\n Object.mixin(type, descriptor);\n if (customFields != null) {\n Object.mixin(type.customFields, customFields);\n }\n if ((bindings != null) && bindings !== type.bindings) {\n type.bindings = type.bindings.concat(bindings);\n }\n if ((formulas != null) && formulas !== type.formulas) {\n type.formulas = type.formulas.concat(formulas);\n }\n if ((actions != null) && actions !== type.actions) {\n type.actions = actions.concat(type.actions);\n }\n type.type = typeName;\n return this.createControlFromDescriptor(type, parent);\n } else if (parent != null) {\n parent.addObject(control);\n control.index = index;\n } else {\n gs.ObjectManager.current.addObject(control);\n }\n control.ui = new ui.Component_UIBehavior();\n control.addComponent(control.ui);\n control.params = descriptor.params;\n if (descriptor.updateBehavior === \"continuous\") {\n control.updateBehavior = ui.UpdateBehavior.CONTINUOUS;\n }\n if (descriptor.inheritProperties) {\n control.inheritProperties = true;\n }\n if (descriptor.font != null) {\n control.font = new Font(descriptor.font.name, descriptor.font.size);\n control.font.bold = (ref = descriptor.font.bold) != null ? ref : control.font.bold;\n control.font.italic = (ref1 = descriptor.font.italic) != null ? ref1 : control.font.italic;\n control.font.smallCaps = (ref2 = descriptor.font.smallCaps) != null ? ref2 : control.font.smallCaps;\n control.font.underline = (ref3 = descriptor.font.underline) != null ? ref3 : control.font.underline;\n control.font.strikeThrough = (ref4 = descriptor.font.strikeThrough) != null ? ref4 : control.font.strikeThrough;\n if (descriptor.font.color != null) {\n control.font.color = Color.fromArray(descriptor.font.color);\n }\n if (descriptor.font.border != null) {\n control.font.border = (ref5 = descriptor.font.border) != null ? ref5 : false;\n control.font.borderSize = (ref6 = descriptor.font.borderSize) != null ? ref6 : 4;\n control.font.borderColor = new Color(0, 0, 0);\n }\n if (descriptor.font.outline != null) {\n control.font.border = (ref7 = descriptor.font.outline) != null ? ref7 : false;\n control.font.borderSize = (ref8 = descriptor.font.outline.size) != null ? ref8 : 4;\n if (descriptor.font.outline.color != null) {\n control.font.borderColor = Color.fromArray(descriptor.font.outline.color);\n } else {\n control.font.borderColor = new Color(0, 0, 0);\n }\n }\n }\n if (descriptor.components != null) {\n ref9 = descriptor.components;\n for (j = 0, len = ref9.length; j < len; j++) {\n c = ref9[j];\n m = c.module || \"gs\";\n component = new window[m][c.type](c.params);\n control.addComponent(component, c.id);\n control[c.id] = component;\n }\n }\n control.focusable = (ref10 = descriptor.focusable) != null ? ref10 : control.focusable;\n if (descriptor.nextKeyObject) {\n control.ui.nextKeyObjectId = descriptor.nextKeyObject;\n }\n if (descriptor.initialFocus) {\n control.ui.focus();\n }\n actions = Object.deepCopy(descriptor.action != null ? [descriptor.action] : descriptor.actions);\n if (actions != null) {\n for (l = 0, len1 = actions.length; l < len1; l++) {\n action = actions[l];\n if (action != null) {\n action.event = (ref11 = action.event) != null ? ref11 : \"onAccept\";\n if (action.target == null) {\n target = this.controllers != null ? this.controllers[descriptor.target] : controller;\n action.target = target || SceneManager.scene.behavior;\n }\n }\n }\n control.actions = actions;\n if (!control.findComponentById(\"actionHandler\")) {\n control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\");\n }\n }\n if (descriptor.id != null) {\n control.id = descriptor.id;\n gs.ObjectManager.current.setObjectById(control, control.id);\n }\n control.descriptor = descriptor;\n control.layoutRect = new Rect();\n control.layoutRect.set(0, 0, 0, 0);\n if (descriptor.frame != null) {\n if (((ref12 = descriptor.frame[0]) != null ? ref12.length : void 0) != null) {\n control.layoutRect.x = this.createCalcFunction(descriptor.frame[0]);\n control.dstRect.x = 0;\n } else {\n control.dstRect.x = (ref13 = descriptor.frame[0]) != null ? ref13 : control.dstRect.x;\n }\n if (((ref14 = descriptor.frame[1]) != null ? ref14.length : void 0) != null) {\n control.layoutRect.y = this.createCalcFunction(descriptor.frame[1]);\n control.dstRect.y = 0;\n } else {\n control.dstRect.y = (ref15 = descriptor.frame[1]) != null ? ref15 : control.dstRect.y;\n }\n if (((ref16 = descriptor.frame[2]) != null ? ref16.length : void 0) != null) {\n control.layoutRect.width = this.createCalcFunction(descriptor.frame[2]);\n control.dstRect.width = 1;\n } else {\n control.dstRect.width = (ref17 = descriptor.frame[2]) != null ? ref17 : control.dstRect.width;\n }\n if (((ref18 = descriptor.frame[3]) != null ? ref18.length : void 0) != null) {\n control.layoutRect.height = this.createCalcFunction(descriptor.frame[3]);\n control.dstRect.height = 1;\n } else {\n control.dstRect.height = (ref19 = descriptor.frame[3]) != null ? ref19 : control.dstRect.height;\n }\n }\n if (descriptor.sizeToParent != null) {\n control.sizeToParent = descriptor.sizeToParent;\n }\n if (descriptor.blendMode != null) {\n control.blendMode = this.blendModes[descriptor.blendMode];\n }\n if (descriptor.anchor != null) {\n control.anchor.set(descriptor.anchor[0], descriptor.anchor[1]);\n }\n control.opacity = (ref20 = descriptor.opacity) != null ? ref20 : 255;\n if (descriptor.minimumSize != null) {\n control.minimumSize = {\n width: descriptor.minimumSize[0],\n height: descriptor.minimumSize[1]\n };\n }\n if (descriptor.resizable != null) {\n control.resizable = descriptor.resizable;\n }\n if (descriptor.scrollable != null) {\n control.scrollable = descriptor.scrollable;\n }\n if (descriptor.fixedSize != null) {\n control.fixedSize = descriptor.fixedSize;\n }\n if (descriptor.draggable != null) {\n control.draggable = descriptor.draggable;\n control.draggable.step = 0;\n if (control.draggable.rect != null) {\n control.draggable.rect = Rect.fromArray(control.draggable.rect);\n }\n control.addComponent(new ui.Component_Draggable());\n }\n if (descriptor.bindings != null) {\n control.bindings = descriptor.bindings;\n control.insertComponent(new ui.Component_BindingHandler(), 0);\n }\n if (descriptor.formulas != null) {\n control.formulas = descriptor.formulas;\n control.insertComponent(new ui.Component_FormulaHandler(), 0);\n }\n control.dataField = descriptor.dataField;\n control.enabled = (ref21 = descriptor.enabled) != null ? ref21 : true;\n if (descriptor.selectable != null) {\n control.selectable = descriptor.selectable;\n }\n if (descriptor.group != null) {\n control.group = descriptor.group;\n gs.ObjectManager.current.addToGroup(control, control.group);\n }\n if (descriptor.customFields != null) {\n control.customFields = Object.deepCopy(descriptor.customFields);\n }\n if (descriptor.margin != null) {\n control.margin.left = descriptor.margin[0];\n control.margin.top = descriptor.margin[1];\n control.margin.right = descriptor.margin[2];\n control.margin.bottom = descriptor.margin[3];\n }\n if (descriptor.padding != null) {\n control.padding.left = descriptor.padding[0];\n control.padding.top = descriptor.padding[1];\n control.padding.right = descriptor.padding[2];\n control.padding.bottom = descriptor.padding[3];\n }\n if (descriptor.alignment != null) {\n control.alignment = this.alignments[descriptor.alignment];\n }\n control.alignmentY = this.alignments[descriptor.alignmentY || 0];\n control.alignmentX = this.alignments[descriptor.alignmentX || 0];\n control.zIndex = descriptor.zIndex || 0;\n control.order = descriptor.order || 0;\n control.chainOrder = ((ref22 = descriptor.chainOrder) != null ? ref22 : descriptor.zOrder) + ((parent != null ? parent.chainOrder : void 0) || 0);\n if (descriptor.zoom != null) {\n control.zoom = {\n x: descriptor.zoom[0] / 100,\n y: descriptor.zoom[1] / 100\n };\n }\n if (descriptor.visible != null) {\n control.visible = descriptor.visible;\n }\n if (descriptor.clipRect) {\n control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height);\n }\n if (descriptor.styles != null) {\n this.addControlStyles(control, descriptor.styles);\n }\n if (descriptor.template != null) {\n control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode);\n data = ui.Component_FormulaHandler.fieldValue(control, control.dataField);\n isNumber = typeof data === \"number\";\n if (data != null) {\n for (i = n = 0, ref23 = (ref24 = data.length) != null ? ref24 : data; 0 <= ref23 ? n < ref23 : n > ref23; i = 0 <= ref23 ? ++n : --n) {\n if ((data[i] != null) || isNumber) {\n valid = true;\n if ((descriptor.dataFilter != null) && !isNumber) {\n valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter);\n }\n if (valid || isNumber) {\n child = this.createControlFromDescriptor(descriptor.template, control, i);\n if ((ref25 = data[i]) != null ? ref25.dstRect : void 0) {\n child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect);\n }\n if ((child.clipRect == null) && (control.clipRect != null)) {\n child.clipRect = control.clipRect;\n }\n control.addObject(child);\n child.index = i;\n child.order = ((ref26 = data.length) != null ? ref26 : data) - i;\n control.controls.push(child);\n }\n }\n }\n }\n }\n if (descriptor.controls && descriptor.controls.exec) {\n controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls);\n } else {\n controls = descriptor.controls;\n }\n if (controls != null) {\n for (i = o = 0, len2 = controls.length; o < len2; i = ++o) {\n item = controls[i];\n childControl = this._createFromDescriptor(item, control, i);\n if ((childControl.clipRect == null) && (control.clipRect != null)) {\n childControl.clipRect = control.clipRect;\n }\n childControl.index = i;\n childControl.origin.x = control.origin.x + control.dstRect.x;\n childControl.origin.y = control.origin.y + control.dstRect.y;\n control.addObject(childControl);\n control.controls.push(childControl);\n }\n }\n if (control.styles && control.parentsByStyle) {\n parent = control.parent;\n while (parent) {\n if (parent.styles) {\n ref27 = parent.styles;\n for (p = 0, len3 = ref27.length; p < len3; p++) {\n style = ref27[p];\n if (!control.parentsByStyle[style.id]) {\n control.parentsByStyle[style.id] = [];\n }\n control.parentsByStyle[style.id].push(parent);\n }\n }\n parent = parent.parent;\n }\n }\n if (descriptor.animations != null) {\n control.animations = Object.deepCopy(descriptor.animations);\n control.animationExecutor = new ui.Component_AnimationExecutor();\n control.addComponent(control.animationExecutor);\n control.addComponent(new ui.Component_AnimationHandler());\n }\n control.ui.updateStyle();\n control.setup();\n return control;\n };\n\n\n /**\n * Creates an UI object from a specified UI descriptor.\n *\n * @method _createFromDescriptor\n * @param {Object} descriptor - The UI object descriptor.\n * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n * @return {gs.Object_UIElement} The created UI object.\n * @protected\n */\n\n UIManager.prototype._createFromDescriptor = function(descriptor, parent, index) {\n var control, controller;\n control = this.createControlFromDescriptor(descriptor, parent, index);\n if (descriptor.controller != null) {\n controller = this.controllers[descriptor.controller];\n control.controller = controller;\n control.addComponent(controller);\n }\n return control;\n };\n\n UIManager.prototype.createLayoutFromDescriptor = function(descriptor, parent, index) {\n return this._createFromDescriptor(descriptor, parent, index);\n };\n\n return UIManager;\n\n})();\n\nGraphics.width = $PARAMS.resolution.width;\n\nGraphics.height = $PARAMS.resolution.height;\n\nui.UiFactory = new UIManager();\n\nui.UIManager = ui.UiFactory;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7Ozs7OztFQVlhLGlCQUFDLENBQUQsRUFBSSxJQUFKLEVBQVUsS0FBVjs7QUFDVDs7Ozs7QUFBQSxRQUFBO0lBS0EsSUFBQyxDQUFBLFlBQUQsR0FBZ0I7O0FBRWhCOzs7OztJQUtBLElBQUMsQ0FBQSxLQUFELEdBQVM7O0FBRVQ7Ozs7O0lBS0EsSUFBQyxDQUFBLElBQUQsR0FBUTs7QUFFUjs7Ozs7SUFLQSxJQUFDLENBQUEsS0FBRCxHQUFTOztBQUVUOzs7Ozs7SUFNQSxJQUFDLENBQUEsT0FBRCxHQUFlLElBQUEsS0FBQSxDQUFNLEVBQU47QUFDZixTQUF5Qiw4RkFBekI7TUFBQSxJQUFDLENBQUEsT0FBUSxDQUFBLENBQUEsQ0FBVCxHQUFjO0FBQWQ7O0FBRUE7Ozs7OztJQU1BLElBQUMsQ0FBQSxPQUFELEdBQWUsSUFBQSxLQUFBLENBQU0sRUFBTjtBQUNmLFNBQTBCLG1HQUExQjtNQUFBLElBQUMsQ0FBQSxPQUFRLENBQUEsQ0FBQSxDQUFULEdBQWM7QUFBZDtFQTdDUzs7O0FBZ0RiOzs7OztvQkFJQSxJQUFBLEdBQU0sU0FBQTtBQUNILFFBQUE7SUFBQSxJQUFDLENBQUEsSUFBRCxHQUFRLElBQUMsQ0FBQTtJQUNULENBQUEsR0FBSSxJQUFDLENBQUEsS0FBSyxDQUFDLEtBQVAsQ0FBYSxJQUFiLEVBQW1CLFNBQW5CO0lBQ0osSUFBQyxDQUFBLFlBQUQsR0FBZ0I7QUFFaEIsV0FBTztFQUxKOzs7QUFPTjs7Ozs7Ozs7b0JBT0EsUUFBQSxHQUFVLFNBQUMsV0FBRDtBQUNOLFFBQUE7SUFBQSxNQUFBLEdBQVMsSUFBQyxDQUFBLE9BQVEsQ0FBQSxDQUFBLENBQVQsS0FBZTtJQUN4QixJQUFDLENBQUEsT0FBUSxDQUFBLENBQUEsQ0FBVCxHQUFjO0FBRWQsV0FBTztFQUpEOzs7QUFNVjs7Ozs7Ozs7b0JBT0Es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QUMsVUFBWDtNQUMxQixPQUFPLENBQUMsVUFBUixHQUFxQjtNQUNyQixPQUFPLENBQUMsWUFBUixDQUFxQixVQUFyQixFQUhKOztBQUtBLFdBQU87RUFSWTs7c0JBVXZCLDBCQUFBLEdBQTRCLFNBQUMsVUFBRCxFQUFhLE1BQWIsRUFBcUIsS0FBckI7V0FDeEIsSUFBQyxDQUFBLHFCQUFELENBQXVCLFVBQXZCLEVBQW1DLE1BQW5DLEVBQTJDLEtBQTNDO0VBRHdCOzs7Ozs7QUFLaEMsUUFBUSxDQUFDLEtBQVQsR0FBaUIsT0FBTyxDQUFDLFVBQVUsQ0FBQzs7QUFDcEMsUUFBUSxDQUFDLE1BQVQsR0FBa0IsT0FBTyxDQUFDLFVBQVUsQ0FBQzs7QUFDckMsRUFBRSxDQUFDLFNBQUgsR0FBbUIsSUFBQSxTQUFBLENBQUE7O0FBQ25CLEVBQUUsQ0FBQyxTQUFILEdBQWUsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4jXG4jICAgU2NyaXB0OiBVSU1hbmFnZXJcbiNcbiMgICAkJENPUFlSSUdIVCQkXG4jXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuY2xhc3MgRm9ybXVsYVxuICAgICMjIypcbiAgICAqIEVuY2Fwc3VsYXRlcyBhIFVJIGZvcm11bGEuIEEgZm9ybXVsYSBjYW4gYmUgdXNlZCBpbiBVSSBsYXlvdXRzIHRvIGRlZmluZVxuICAgICogcHJvcGVydHktYmluZGluZ3Mgb3IgdG8gaW1wbGVtZW50IGEgc3BlY2lmaWMgYmVoYXZpb3IuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIEZvcm11bGFcbiAgICAqIEBtZW1iZXJvZiB1aVxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmIC0gVGhlIGZvcm11bGEtZnVuY3Rpb24uIERlZmluZXMgdGhlIGxvZ2ljIG9mIHRoZSBmb3JtdWxhLlxuICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgLSBBbiBvcHRpb25hbCBkYXRhLW9iamVjdCB3aGljaCBjYW4gYmUgYWNjZXNzZWQgaW5zaWRlIHRoZSBmb3JtdWxhLWZ1bmN0aW9uLlxuICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IC0gQW4gb3B0aW9uYWwgZXZlbnQtbmFtZSB0byBkZWZpbmUgd2hlbiB0aGUgZm9ybXVsYSBzaG91bGQgYmUgZXhlY3V0ZWQuXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IChmLCBkYXRhLCBldmVudCkgLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIEluZGljYXRlcyBpZiBpdHMgdGhlIGZpcnN0IHRpbWUgdGhlIGZvcm11bGEgaXMgY2FsbGVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBvbkluaXRpYWxpemVcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICMjI1xuICAgICAgICBAb25Jbml0aWFsaXplID0geWVzXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGZvcm11bGEtZnVuY3Rpb24uXG4gICAgICAgICogQHByb3BlcnR5IGV4ZWNfXG4gICAgICAgICogQHR5cGUgRnVuY3Rpb25cbiAgICAgICAgIyMjXG4gICAgICAgIEBleGVjXyA9IGZcbiAgICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQW4gb3B0aW9uYWwgZGF0YS1vYmplY3Qgd2hpY2ggY2FuIGJlcyBhY2Nlc3NlZCBpbnNpZGUgdGhlIGZvcm11bGEtZnVuY3Rpb24uXG4gICAgICAgICogQHByb3BlcnR5IGRhdGFcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjICAgXG4gICAgICAgIEBkYXRhID0gZGF0YVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFuIG9wdGlvbmFsIGV2ZW50LW5hbWUgdG8gZGVmaW5lIHdoZW4gdGhlIGZvcm11bGEgc2hvdWxkIGJlIGV4ZWN1dGVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBldmVudFxuICAgICAgICAqIEB0eXBlIHN0cmluZ1xuICAgICAgICAjIyMgXG4gICAgICAgIEBldmVudCA9IGV2ZW50XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQW4gYXJyYXkgb2YgY3VzdG9tIG51bWJlci1kYXRhIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBkaWZmZXJlbnQgcHVycG9zZXMuIFRoZSBmaXJzdCBlbGVtZW50XG4gICAgICAgICogaXMgYWxzbyB1c2VkIGluIG9uQ2hhbmdlIG1ldGhvZCB0byBzdG9yZSB0aGUgb2xkIHZhbHVlIGFuZCBjaGVjayBhZ2FpbnN0IHRoZSBuZXcgb25lIHRvIGRldGVjdCBhIGNoYW5nZS5cbiAgICAgICAgKiBAcHJvcGVydHkgbnVtYmVyc1xuICAgICAgICAqIEB0eXBlIG51bWJlcltdXG4gICAgICAgICMjIyBcbiAgICAgICAgQG51bWJlcnMgPSBuZXcgQXJyYXkoMTApXG4gICAgICAgIEBudW1iZXJzW2ldID0gMCBmb3IgaSBpbiBbMC4uQG51bWJlcnMubGVuZ3RoXVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFuIGFycmF5IG9mIGN1c3RvbSBzdHJpbmctZGF0YSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgZGlmZmVyZW50IHB1cnBvc2VzLiBUaGUgZmlyc3QgZWxlbWVudFxuICAgICAgICAqIGlzIGFsc28gdXNlZCBpbiBvblRleHRDaGFuZ2UgbWV0aG9kIHRvIHN0b3JlIHRoZSBvbGQgdmFsdWUgYW5kIGNoZWNrIGFnYWluc3QgdGhlIG5ldyBvbmUgdG8gZGV0ZWN0IGEgY2hhbmdlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdHJpbmdzXG4gICAgICAgICogQHR5cGUgc3RyaW5nW11cbiAgICAgICAgIyMjXG4gICAgICAgIEBzdHJpbmdzID0gbmV3IEFycmF5KDEwKVxuICAgICAgICBAc3RyaW5nc1tpXSA9IFwiXCIgZm9yIGkgaW4gWzAuLkBzdHJpbmdzLmxlbmd0aF1cbiAgICAgICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogVGhlIGZvcm11bGEtZnVuY3Rpb24uIEl0cyBhIHdyYXBwZXItZnVuY3Rpb24gYmVmb3JlIHRoZSBmaXJzdC10aW1lIGNhbGwgd2FzIG1hZGUuXG4gICAgKiBAbWV0aG9kIGV4ZWNcbiAgICAjIyNcbiAgICBleGVjOiAtPlxuICAgICAgIEBleGVjID0gQGV4ZWNfXG4gICAgICAgciA9IEBleGVjXy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgQG9uSW5pdGlhbGl6ZSA9IG5vXG4gICAgICAgXG4gICAgICAgcmV0dXJuIHJcbiAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBudW1iZXItdmFsdWUgaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgY2hlY2suIEl0IHVzZXNcbiAgICAqIHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgbnVtYmVycy1hcnJheSB0byBzdG9yZSB0aGUgdmFsdWUgYW5kIGNoZWNrIGFnYWluc3QgdGhlIG5ldyBvbmUuXG4gICAgKlxuICAgICogQG1ldGhvZCBvbkNoYW5nZVxuICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlclZhbHVlIC0gTnVtYmVyIHZhbHVlIHRvIGNoZWNrLlxuICAgICMjIyAgICBcbiAgICBvbkNoYW5nZTogKG51bWJlclZhbHVlKSAtPlxuICAgICAgICByZXN1bHQgPSBAbnVtYmVyc1swXSAhPSBudW1iZXJWYWx1ZVxuICAgICAgICBAbnVtYmVyc1swXSA9IG51bWJlclZhbHVlXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgIFxuICAgICMjIypcbiAgICAqIENoZWNrcyBpZiB0aGUgc3BlY2lmaWVkIHRleHQtdmFsdWUgaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgY2hlY2suIEl0IHVzZXNcbiAgICAqIHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgc3RyaW5ncy1hcnJheSB0byBzdG9yZSB0aGUgdmFsdWUgYW5kIGNoZWNrIGFnYWluc3QgdGhlIG5ldyBvbmUuXG4gICAgKlxuICAgICogQG1ldGhvZCBvblRleHRDaGFuZ2VcbiAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0VmFsdWUgLSBUZXh0IHZhbHVlIHRvIGNoZWNrLlxuICAgICMjIyAgICAgXG4gICAgb25UZXh0Q2hhbmdlOiAodGV4dFZhbHVlKSAtPlxuICAgICAgICByZXN1bHQgPSBAc3RyaW5nc1swXSAhPSB0ZXh0VmFsdWVcbiAgICAgICAgQHN0cmluZ3NbMF0gPSB0ZXh0VmFsdWVcbiAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgXG51aS5Gb3JtdWxhID0gRm9ybXVsYVxuXG5jbGFzcyBTcGFjZVxuICAgICMjIypcbiAgICAqIERlc2NyaWJlcyBhIHNwYWNlIGluc2lkZSBvciBhcm91bmQgc29tZXRoaW5nIGxpa2UgYSBtYXJnaW4gb3IgcGFkZGluZy5cbiAgICAqXG4gICAgKiBAbW9kdWxlIHVpXG4gICAgKiBAY2xhc3MgU3BhY2VcbiAgICAqIEBtZW1iZXJvZiB1aVxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbGVmdCAtIFNwYWNlIGF0IHRoZSBsZWZ0IGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB0b3AgLSBTcGFjZSBhdCB0aGUgdG9wIGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByaWdodCAtIFNwYWNlIGF0IHRoZSByaWdodCBpbiBwaXhlbHMuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gYm90dG9tIC0gU3BhY2UgYXQgdGhlIGJvdHRvbSBpbiBwaXhlbHMuXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IChsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20pIC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgbGVmdCBpbiBwaXhlbHMuXG4gICAgICAgICogQHByb3BlcnR5IGxlZnRcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBsZWZ0ID0gbGVmdFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFNwYWNlIGF0IHRoZSB0b3AgaW4gcGl4ZWxzLlxuICAgICAgICAqIEBwcm9wZXJ0eSB0b3BcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEB0b3AgPSB0b3BcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgcmlnaHQgaW4gcGl4ZWxzLlxuICAgICAgICAqIEBwcm9wZXJ0eSByaWdodFxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQHJpZ2h0ID0gcmlnaHRcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgYm90dG9tIGluIHBpeGVscy5cbiAgICAgICAgKiBAcHJvcGVydHkgYm90dG9tXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAYm90dG9tID0gYm90dG9tXG4gICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgc3BhY2UgYnkgY29weWluZyB0aGVtIGZyb20gYSBzcGVjaWZpZWQgc3BhY2UuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXRGcm9tT2JqZWN0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gc3BhY2UgLSBBIHNwYWNlIHRvIGNvcHkuXG4gICAgIyMjICAgXG4gICAgc2V0RnJvbU9iamVjdDogKHNwYWNlKSAtPlxuICAgICAgICBAbGVmdCA9IHNwYWNlLmxlZnRcbiAgICAgICAgQHRvcCA9IHNwYWNlLnRvcFxuICAgICAgICBAcmlnaHQgPSBzcGFjZS5yaWdodFxuICAgICAgICBAYm90dG9tID0gc3BhY2UuYm90dG9tXG4gICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgc3BhY2UuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXRcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0IC0gU3BhY2UgYXQgdGhlIGxlZnQgaW4gcGl4ZWxzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHRvcCAtIFNwYWNlIGF0IHRoZSB0b3AgaW4gcGl4ZWxzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0IC0gU3BhY2UgYXQgdGhlIHJpZ2h0IGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBib3R0b20gLSBTcGFjZSBhdCB0aGUgYm90dG9tIGluIHBpeGVscy5cbiAgICAjIyMgICAgXG4gICAgc2V0OiAobGVmdCwgdG9wLCByaWdodCwgYm90dG9tKSAtPlxuICAgICAgICBAbGVmdCA9IGxlZnRcbiAgICAgICAgQHRvcCA9IHRvcFxuICAgICAgICBAcmlnaHQgPSByaWdodFxuICAgICAgICBAYm90dG9tID0gYm90dG9tXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIG5ldyBzcGFjZSBvYmplY3QgZnJvbSBhbiBhcnJheSBvZiBjb29yZGluYXRlcy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZyb21BcnJheVxuICAgICogQHN0YXRpY1xuICAgICogQHBhcmFtIHtudW1iZXJbXX0gYXJyYXkgLSBBbiBhcnJheSBvZiBjb29yZGluYXRlcyAobGVmdCwgdG9wIHJpZ2h0LCBib3R0b20pLlxuICAgICMjIyAgICBcbiAgICBAZnJvbUFycmF5OiAoYXJyYXkpIC0+IG5ldyB1aS5TcGFjZShhcnJheVswXSwgYXJyYXlbMV0sIGFycmF5WzJdLCBhcnJheVszXSlcbiAgICAgICAgXG51aS5TcGFjZSA9IFNwYWNlXG5cbmNsYXNzIFN0eWxlXG4gICAgIyMjKlxuICAgICogQSBVSSBzdHlsZSBjYW4gYXBwbGllZCB0byBhIFVJIG9iamVjdCB0byBtb2RpZnkgaXQgcHJvcGVydGllcyBsaWtlIGNvbG9yLCBpbWFnZSwgZXRjLiB0byBnaXZlIGEgY2VydGFpbiBcInN0eWxlXCIgdG8gaXQuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIFN0eWxlXG4gICAgKiBAbWVtYmVyb2YgdWlcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBBIHN0eWxlLWRlc2NyaXB0b3IgdG8gaW5pdGlhbGl6ZSB0aGUgc3R5bGUgZnJvbS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpZCAtIEEgdW5pcXVlIG51bWVyaWMgSUQgdG8gYWNjZXNzIHRoZSBzdHlsZSB0aHJvdWdoIFVJTWFuYWdlci5zdHlsZXNCeUlkIGNvbGxlY3Rpb24uXG4gICAgKiBAcGFyYW0ge251bWJlcn0gc2VsZWN0b3IgLSBBIHNlbGVjdG9yIElEIHdoaWNoIGNvbnRyb2xzIHVuZGVyIHdoaWNoIGNvbmRpdGlvbnMgdGhlIHN0eWxlcyB3aWxsIGJlIGFwcGxpZWQuXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IChkZXNjcmlwdG9yLCBpZCwgc2VsZWN0b3IpIC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBJRCBudW1iZXIgdG8gcXVpY2tseSBhY2Nlc3MgdGhpcyBzdHlsZSBhbmQgbGluayB0byB0aGlzIHN0eWxlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBpZFxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQGlkID0gaWRcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdHlsZS1JRCBvZiB0YXJnZXQgb2JqZWN0LiBUaGlzIHN0eWxlIHdpbGwgb25seSBiZSBhcHBsaWVkIG9uIFVJIG9iamVjdHMgd2l0aCB0aGF0IHN0eWxlIElEIHdoaWNoIGFyZVxuICAgICAgICAqIGNoaWxkcmVuIG9mIFVJIG9iamVjdHMgd2hlcmUgdGhpcyBzdHlsZSBpcyBhcHBsaWVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSB0YXJnZXRcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEB0YXJnZXQgPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFNlbGVjdG9yLUlEIHdoaWNoIGNvbnRyb2xzIHVuZGVyIHdoaWNoIGNvbmRpdGlvbnMgdGhlIHN0eWxlIGJlY29tZXMgYWN0aXZlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzZWxlY3RvclxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQHNlbGVjdG9yID0gc2VsZWN0b3JcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgZm9udCB1c2VkIGZvciB0aGUgdGV4dC1kaXNwbGF5LlxuICAgICAgICAqIEBkZWZhdWx0IG51bGxcbiAgICAgICAgKiBAcHJvcGVydHkgZm9udFxuICAgICAgICAqIEB0eXBlIGdzLkZvbnRcbiAgICAgICAgIyMjXG4gICAgICAgIEBmb250ID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBpbWFnZSB1c2VkIGZvciB2aXN1YWwgcHJlc2VudGF0aW9uLlxuICAgICAgICAqIEBwcm9wZXJ0eSBpbWFnZVxuICAgICAgICAqIEB0eXBlIHN0cmluZ1xuICAgICAgICAjIyNcbiAgICAgICAgQGltYWdlID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBhbmltYXRpb25zIHVzZWQgZm9yIHZpc3VhbCBwcmVzZW50YXRpb24uXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIEBwcm9wZXJ0eSBhbmltYXRpb25zXG4gICAgICAgICogQHR5cGUgT2JqZWN0W11cbiAgICAgICAgIyMjXG4gICAgICAgIEBhbmltYXRpb25zID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBjb2xvci5cbiAgICAgICAgKiBAcHJvcGVydHkgY29sb3JcbiAgICAgICAgKiBAdHlwZSBncy5Db2xvclxuICAgICAgICAjIyNcbiAgICAgICAgQGNvbG9yID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyB0b25lLlxuICAgICAgICAqIEBwcm9wZXJ0eSB0b25lXG4gICAgICAgICogQHR5cGUgZ3MuVG9uZVxuICAgICAgICAjIyNcbiAgICAgICAgQHRvbmUgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIGFuY2hvci1wb2ludC4gRm9yIGV4YW1wbGU6IEFuIGFuY2hvci1wb2ludCB3aXRoIDAsMCBwbGFjZXMgdGhlIG9iamVjdCB3aXRoIGl0cyB0b3AtbGVmdCBjb3JuZXJcbiAgICAgICAgKiBhdCBpdHMgcG9zaXRpb24gYnV0IHdpdGggYW4gMC41LCAwLjUgYW5jaG9yLXBvaW50IHRoZSBvYmplY3QgaXMgcGxhY2VkIHdpdGggaXRzIGNlbnRlci4gQW4gYW5jaG9yLXBvaW50IG9mIDEsMVxuICAgICAgICAqIHBsYWNlcyB0aGUgb2JqZWN0IHdpdGggaXRzIGxvd2VyLXJpZ2h0IGNvcm5lci5cbiAgICAgICAgKiBAcHJvcGVydHkgYW5jaG9yXG4gICAgICAgICogQHR5cGUgZ3MuUG9pbnRcbiAgICAgICAgIyMjXG4gICAgICAgIEBhbmNob3IgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIHpvb20tc2V0dGluZyBmb3IgeCBhbmQgeSBheGlzLlxuICAgICAgICAqIEBkZWZhdWx0IG5ldyBncy5Qb2ludCgxLjAsIDEuMClcbiAgICAgICAgKiBAcHJvcGVydHkgem9vbVxuICAgICAgICAqIEB0eXBlIGdzLlBvaW50XG4gICAgICAgICMjI1xuICAgICAgICBAem9vbSA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgbWFyZ2luLiBUaGUgbWFyZ2luIGRlZmluZXMgYW4gZXh0cmEgc3BhY2UgYXJvdW5kIHRoZSBVSSBvYmplY3QuIFxuICAgICAgICAqIFRoZSBkZWZhdWx0IGlzIHsgbGVmdDogMCwgdG9wOiAwLCByaWdodDogMCwgYm90dG9tOiAwIH0uXG4gICAgICAgICogQHByb3BlcnR5IG1hcmdpblxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQG1hcmdpbiA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgcGFkZGluZy4gVGhlIGRlZmF1bHQgaXMgeyBsZWZ0OiAwLCB0b3A6IDAsIHJpZ2h0OiAwLCBib3R0b206IDAgfS5cbiAgICAgICAgKiBAcHJvcGVydHkgcGFkZGluZ1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHBhZGRpbmcgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIG1hc2sgZm9yIG1hc2tpbmctZWZmZWN0cy5cbiAgICAgICAgKiBAcHJvcGVydHkgbWFza1xuICAgICAgICAqIEB0eXBlIGdzLk1hc2tcbiAgICAgICAgIyMjXG4gICAgICAgIEBtYXNrID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBhbGlnbm1lbnQuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudFxuICAgICAgICAqIEB0eXBlIHVpLkFsaWdubWVudFxuICAgICAgICAjIyNcbiAgICAgICAgQGFsaWdubWVudCA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIG9wYWNpdHkgdG8gY29udHJvbCB0cmFuc3BhcmVuY3kuIEZvciBleGFtcGxlOiAwID0gVHJhbnNwYXJlbnQsIDI1NSA9IE9wYXF1ZSwgMTI4ID0gU2VtaS1UcmFuc3BhcmVudC5cbiAgICAgICAgKiBAcHJvcGVydHkgb3BhY2l0eVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQG9wYWNpdHkgPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyBjbGlwLXJlY3QgZm9yIHZpc3VhbCBwcmVzZW50YXRpb24uXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIEBwcm9wZXJ0eSBjbGlwUmVjdFxuICAgICAgICAqIEB0eXBlIGdzLlJlY3RcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjI1xuICAgICAgICBAY2xpcFJlY3QgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGNvcm5lci1zaXplIG9mIHRoZSBmcmFtZS5cbiAgICAgICAgKiBAcHJvcGVydHkgZnJhbWVDb3JuZXJTaXplXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAZnJhbWVDb3JuZXJTaXplID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgdGhpY2tuZXNzIG9mIHRoZSBmcmFtZS5cbiAgICAgICAgKiBAcHJvcGVydHkgZnJhbWVUaGlja25lc3NcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBmcmFtZVRoaWNrbmVzcyA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGxvb3Bpbmcgb2YgdGhlIGltYWdlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBsb29waW5nXG4gICAgICAgICogQHR5cGUgdWkuT3JpZW50YXRpb25cbiAgICAgICAgIyMjXG4gICAgICAgIEBsb29waW5nID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyB6LWluZGV4IGNvbnRyb2xzIHJlbmRlcmluZy1vcmRlci9pbWFnZS1vdmVybGFwcGluZy4gQW4gb2JqZWN0IHdpdGggYSBzbWFsbGVyIHotaW5kZXggaXMgcmVuZGVyZWRcbiAgICAgICAgKiBiZWZvcmUgYW4gb2JqZWN0IHdpdGggYSBsYXJnZXIgaW5kZXguIEZvciBleGFtcGxlOiBUbyBtYWtlIHN1cmUgYSBnYW1lIG9iamVjdCBpcyBhbHdheXMgb24gdG9wIG9mIHRoZSBzY3JlZW4sIGl0XG4gICAgICAgICogc2hvdWxkIGhhdmUgdGhlIGxhcmdlc3Qgei1pbmRleCBvZiBhbGwgZ2FtZSBvYmplY3RzLlxuICAgICAgICAqIEBwcm9wZXJ0eSB6SW5kZXhcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEB6SW5kZXggPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyBhbGlnbm1lbnQgb24geC1heGlzLiBOZWVkcyB0byBiZSBzdXBwb3J0ZWQgYnkgbGF5b3V0LlxuICAgICAgICAqIEBwcm9wZXJ0eSBhbGlnbm1lbnRYXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAYWxpZ25tZW50WCA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIG9iamVjdCdzIGFsaWdubWVudCBvbiB5LWF4aXMuIE5lZWRzIHRvIGJlIHN1cHBvcnRlZCBieSBsYXlvdXQuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudFlcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBhbGlnbm1lbnRZID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgb2JqZWN0J3MgcmVzaXplIGJlaGF2aW9yLlxuICAgICAgICAqIEBwcm9wZXJ0eSByZXNpemFibGVcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICMjI1xuICAgICAgICBAcmVzaXphYmxlID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvcmlnaW5hbCBzdHlsZSBkZXNjcmlwdG9yLlxuICAgICAgICAqIEBwcm9wZXJ0eSBkZXNjcmlwdG9yXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3JcbiAgICAgICAgICAgIEBzZXRGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yKVxuXG4gICAgIyMjKlxuICAgICogSW5pdGlhbGl6ZXMgdGhlIHN0eWxlIGZyb20gYSBzdHlsZS1kZXNjcmlwdG9yLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0RnJvbURlc2NyaXB0b3JcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIHN0eWxlLWRlc2NyaXB0b3IuXG4gICAgIyMjIFxuICAgIHNldEZyb21EZXNjcmlwdG9yOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgQGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yXG4gICAgICAgIEBpbWFnZSA9IGRlc2NyaXB0b3IuaW1hZ2VcbiAgICAgICAgQGNvbG9yID0gZ3MuQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuY29sb3IpIGlmIGRlc2NyaXB0b3IuY29sb3JcbiAgICAgICAgQHRvbmUgPSBncy5Ub25lLmZyb21BcnJheShkZXNjcmlwdG9yLnRvbmUpIGlmIGRlc2NyaXB0b3IudG9uZVxuICAgICAgICBAYW5jaG9yID0gbmV3IGdzLlBvaW50KGRlc2NyaXB0b3IuYW5jaG9yWzBdLCBkZXNjcmlwdG9yLmFuY2hvclsxXSkgaWYgZGVzY3JpcHRvci5hbmNob3JcbiAgICAgICAgQHpvb20gPSBuZXcgZ3MuUG9pbnQoZGVzY3JpcHRvci56b29tWzBdLCBkZXNjcmlwdG9yLnpvb21bMV0pIGlmIGRlc2NyaXB0b3Iuem9vbVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb250XG4gICAgICAgICAgICBAc2V0dXBGb250KGRlc2NyaXB0b3IpXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jbGlwUmVjdFxuICAgICAgICAgICAgQGNsaXBSZWN0ID0gZ3MuUmVjdC5mcm9tQXJyYXkoZGVzY3JpcHRvci5jbGlwUmVjdClcbiAgICAgICAgICAgIFxuICAgICAgICBAb3BhY2l0eSA9IGRlc2NyaXB0b3Iub3BhY2l0eSBpZiBkZXNjcmlwdG9yLm9wYWNpdHkgPj0gMFxuICAgICAgICBAYWxpZ25tZW50ID0gZGVzY3JpcHRvci5hbGlnbm1lbnQgaWYgZGVzY3JpcHRvci5hbGlnbm1lbnQgPj0gMFxuICAgICAgICBAbWFyZ2luID0gdWkuU3BhY2UuZnJvbUFycmF5KGRlc2NyaXB0b3IubWFyZ2luKSBpZiBkZXNjcmlwdG9yLm1hcmdpblxuICAgICAgICBAcGFkZGluZyA9IHVpLlNwYWNlLmZyb21BcnJheShkZXNjcmlwdG9yLnBhZGRpbmcpIGlmIGRlc2NyaXB0b3IucGFkZGluZ1xuICAgICAgICBAYW5pbWF0aW9ucyA9IGRlc2NyaXB0b3IuYW5pbWF0aW9uc1xuICAgICAgICBAZnJhbWVDb3JuZXJTaXplID0gZGVzY3JpcHRvci5mcmFtZUNvcm5lclNpemUgaWYgZGVzY3JpcHRvci5mcmFtZUNvcm5lclNpemVcbiAgICAgICAgQGZyYW1lVGhpY2tuZXNzID0gZGVzY3JpcHRvci5mcmFtZVRoaWNrbmVzcyBpZiBkZXNjcmlwdG9yLmZyYW1lVGhpY2tuZXNzXG4gICAgICAgIEBmcmFtZSA9IGRlc2NyaXB0b3IuZnJhbWUgaWYgZGVzY3JpcHRvci5mcmFtZVxuICAgICAgICBAbG9vcGluZyA9IGRlc2NyaXB0b3IubG9vcGluZyBpZiBkZXNjcmlwdG9yLmxvb3BpbmdcbiAgICAgICAgQHJlc2l6YWJsZSA9IGRlc2NyaXB0b3IucmVzaXphYmxlIGlmIGRlc2NyaXB0b3IucmVzaXphYmxlP1xuICAgICAgICBAekluZGV4ID0gZGVzY3JpcHRvci56SW5kZXggaWYgZGVzY3JpcHRvci56SW5kZXhcbiAgICAgICAgQGFsaWdubWVudFggPSB1aS5VSU1hbmFnZXIuYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudFhdIGlmIGRlc2NyaXB0b3IuYWxpZ25tZW50WFxuICAgICAgICBAYWxpZ25tZW50WSA9IHVpLlVJTWFuYWdlci5hbGlnbm1lbnRzW2Rlc2NyaXB0b3IuYWxpZ25tZW50WV0gaWYgZGVzY3JpcHRvci5hbGlnbm1lbnRZXG4gICAgICAgIFxuICAgIHNldDogKHN0eWxlKSAtPlxuICAgICAgICBAaW1hZ2UgPSBzdHlsZS5pbWFnZVxuICAgICAgICBAY29sb3Iuc2V0RnJvbU9iamVjdChzdHlsZS5jb2xvcilcbiAgICAgICAgQHRvbmUuc2V0RnJvbU9iamVjdChzdHlsZS50b25lKVxuICAgICAgICBAYW5jaG9yLnNldChzdHlsZS5hbmNob3IueCwgc3R5bGUuYW5jaG9yLnkpXG4gICAgICAgIEB6b29tLnNldChzdHlsZS56b29tLngsIHN0eWxlLnpvb20ueSlcbiAgICAgICAgXG4gICAgICAgIGlmIHN0eWxlLmZvbnRcbiAgICAgICAgICAgIGlmICFAZm9udCB0aGVuIEBmb250ID0gbmV3IGdzLkZvbnQoc3R5bGUuZm9udC5uYW1lLCBzdHlsZS5mb250LnNpemUpXG4gICAgICAgICAgICBAZm9udC5zZXQoc3R5bGUuZm9udClcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBzdHlsZS5jbGlwUmVjdFxuICAgICAgICAgICAgaWYgIUBjbGlwUmVjdCB0aGVuIEBjbGlwUmVjdCA9IG5ldyBncy5SZWN0KClcbiAgICAgICAgICAgIEBjbGlwUmVjdC5zZXRGcm9tT2JqZWN0KHN0eWxlLmNsaXBSZWN0KVxuICAgICAgICAgICAgXG4gICAgICAgIEBvcGFjaXR5ID0gc3R5bGUub3BhY2l0elxuICAgICAgICBAYWxpZ25tZW50ID0gc3R5bGUuYWxpZ25tZW50XG4gICAgICAgIEBtYXJnaW4uc2V0RnJvbU9iamVjdChzdHlsZS5tYXJnaW4pXG4gICAgICAgIEBwYWRkaW5nLnNldEZyb21PYmplY3Qoc3R5bGUucGFkZGluZylcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogSW5pdGlhbGl6ZXMgZm9udC1kYXRhIGZyb20gYSBzdHlsZS1kZXNjcmlwdG9yLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0dXBGb250XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBzdHlsZS1kZXNjcmlwdG9yLlxuICAgICogQHByb3RlY3RlZFxuICAgICMjIyBcbiAgICBzZXR1cEZvbnQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnRcbiAgICAgICAgICAgIGlmICFAZm9udFxuICAgICAgICAgICAgICAgIEBmb250ID0gbmV3IEZvbnQoZGVzY3JpcHRvci5mb250Lm5hbWUsIGRlc2NyaXB0b3IuZm9udC5zaXplID8gMClcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBAZm9udC5uYW1lID0gZGVzY3JpcHRvci5mb250Lm5hbWVcbiAgICAgICAgICAgICAgICBAZm9udC5zaXplID0gZGVzY3JpcHRvci5mb250LnNpemUgPyAwXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAZm9udC5ib2xkID0gZGVzY3JpcHRvci5mb250LmJvbGQgPyBAZm9udC5ib2xkXG4gICAgICAgICAgICBAZm9udC5pdGFsaWMgPSBkZXNjcmlwdG9yLmZvbnQuaXRhbGljID8gQGZvbnQuaXRhbGljXG4gICAgICAgICAgICBAZm9udC5zbWFsbENhcHMgPSBkZXNjcmlwdG9yLmZvbnQuc21hbGxDYXBzID8gQGZvbnQuc21hbGxDYXBzXG4gICAgICAgICAgICBAZm9udC51bmRlcmxpbmUgPSBkZXNjcmlwdG9yLmZvbnQudW5kZXJsaW5lID8gQGZvbnQudW5kZXJsaW5lXG4gICAgICAgICAgICBAZm9udC5zdHJpa2VUaHJvdWdoID0gZGVzY3JpcHRvci5mb250LnN0cmlrZVRocm91Z2ggPyBAZm9udC5zdHJpa2VUaHJvdWdoXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5jb2xvcj9cbiAgICAgICAgICAgICAgICBAZm9udC5jb2xvci5zZXRGcm9tQXJyYXkoZGVzY3JpcHRvci5mb250LmNvbG9yKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyP1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlciA9IGRlc2NyaXB0b3IuZm9udC5ib3JkZXIgPyBub1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlclNpemUgPSBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyU2l6ZSA/IDRcbiAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJDb2xvci5zZXQoMCwgMCwgMCwgMjU1KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mb250Lm91dGxpbmU/XG4gICAgICAgICAgICAgICAgQGZvbnQuYm9yZGVyID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUgPyBub1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlclNpemUgPSBkZXNjcmlwdG9yLmZvbnQub3V0bGluZS5zaXplID8gNFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lLmNvbG9yP1xuICAgICAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJDb2xvci5zZXRGcm9tQXJyYXkoZGVzY3JpcHRvci5mb250Lm91dGxpbmUuY29sb3IpXG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJDb2xvci5zZXQoMCwgMCwgMCwgMjU1KVxuICAgIFxuICAgICMjIypcbiAgICAqIEFwcGxpZXMgdGhlIHN0eWxlIHRvIGEgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgYXBwbHlcbiAgICAqIEBwYXJhbSB7dWkuT2JqZWN0X1VJRWxlbWVudH0gb2JqZWN0IC0gVGhlIFVJIG9iamVjdCB3aGVyZSB0aGUgc3R5bGUgc2hvdWxkIGJlIGFwcGxpZWQgdG8uXG4gICAgIyMjICAgICAgICAgICAgICAgIFxuICAgIGFwcGx5OiAob2JqZWN0KSAtPlxuICAgICAgICBpZiBub3Qgb2JqZWN0LmFjdGl2ZVN0eWxlcy5jb250YWlucyh0aGlzKVxuICAgICAgICAgICAgb2JqZWN0LmFjdGl2ZVN0eWxlcy5wdXNoKHRoaXMpXG4gICAgICAgICAgICBpZiBAZm9udCB0aGVuIG9iamVjdC5mb250Py5zZXQoQGZvbnQpXG4gICAgICAgICAgICBpZiBAY29sb3IgdGhlbiBvYmplY3QuY29sb3Iuc2V0KEBjb2xvcilcbiAgICAgICAgICAgIGlmIEB0b25lIHRoZW4gb2JqZWN0LnRvbmU/LnNldChAdG9uZSlcbiAgICAgICAgICAgIGlmIEBpbWFnZSB0aGVuIG9iamVjdC5pbWFnZSA9IEBpbWFnZVxuICAgICAgICAgICAgaWYgQGFuY2hvciB0aGVuIG9iamVjdC5hbmNob3Iuc2V0KEBhbmNob3IueCwgQGFuY2hvci55KVxuICAgICAgICAgICAgaWYgQHpvb20gdGhlbiBvYmplY3Quem9vbS5zZXQoQHpvb20ueCwgQHpvb20ueSlcbiAgICAgICAgICAgIGlmIEBwYWRkaW5nIHRoZW4gb2JqZWN0LnBhZGRpbmcuc2V0RnJvbU9iamVjdChAcGFkZGluZylcbiAgICAgICAgICAgIGlmIEBtYXJnaW4gdGhlbiBvYmplY3QubWFyZ2luLnNldEZyb21PYmplY3QoQG1hcmdpbilcbiAgICAgICAgICAgIGlmIEBvcGFjaXR5ID49IDAgdGhlbiBvYmplY3Qub3BhY2l0eSA9IEBvcGFjaXR5XG4gICAgICAgICAgICBpZiBAYWxpZ25tZW50ID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50ID0gQGFsaWdubWVudFxuICAgICAgICAgICAgaWYgQGZyYW1lVGhpY2tuZXNzID49IDAgdGhlbiBvYmplY3QuZnJhbWVUaGlja25lc3MgPSBAZnJhbWVUaGlja25lc3NcbiAgICAgICAgICAgIGlmIEBmcmFtZUNvcm5lclNpemUgPj0gMCB0aGVuIG9iamVjdC5mcmFtZUNvcm5lclNpemUgPSBAZnJhbWVDb3JuZXJTaXplXG4gICAgICAgICAgICBpZiBAbWFzayB0aGVuIG9iamVjdC5tYXNrLnNldChAbWFzaylcbiAgICAgICAgICAgIGlmIEB6SW5kZXggPj0gMCB0aGVuIG9iamVjdC56SW5kZXggPSBAekluZGV4XG4gICAgICAgICAgICBpZiBAYWxpZ25tZW50WCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudFggPSBAYWxpZ25tZW50WFxuICAgICAgICAgICAgaWYgQGFsaWdubWVudFkgPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRZID0gQGFsaWdubWVudFlcbiAgICAgICAgICAgIGlmIEByZXNpemFibGU/IHRoZW4gb2JqZWN0LnJlc2l6YWJsZSA9IEByZXNpemFibGVcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGFwcGx5TG9vcGluZyhvYmplY3QpXG4gICAgICAgICAgICBAYXBwbHlBbmltYXRpb25zKG9iamVjdClcbiAgICAgXG4gICAgIyMjKlxuICAgICogQXBwbGllcyB0aGUgbG9vcGluZy1kYXRhIG9mIHRoZSBzdHlsZSB0byBhIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFwcGx5TG9vcGluZ1xuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBsb29waW5nLWRhdGEgc2hvdWxkIGJlIGFwcGxpZWQgdG8uXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICBcbiAgICBhcHBseUxvb3Bpbmc6IChvYmplY3QpIC0+XG4gICAgICAgIGlmIEBsb29waW5nXG4gICAgICAgICAgICBpZiAhb2JqZWN0LnZpc3VhbC5sb29waW5nXG4gICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICBvYmplY3QucmVtb3ZlQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbCA9IG5ldyBncy5Db21wb25lbnRfVGlsaW5nU3ByaXRlKClcbiAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIG9iamVjdC52aXN1YWwubG9vcGluZy52ZXJ0aWNhbCA9IEBsb29waW5nLnZlcnRpY2FsXG4gICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IEBsb29waW5nLmhvcml6b250YWxcbiAgICAgXG4gICAgIyMjKlxuICAgICogQXBwbGllcyB0aGUgYW5pbWF0aW9uLWRhdGEgb2YgdGhlIHN0eWxlIHRvIGEgVUkgb2JqZWN0LiBUaGlzIGF1dG9tYXRpY2FsbHkgYWRkcyBhbiBhbmltYXRpb24taGFuZGxlclxuICAgICogY29tcG9uZW50KHVpLkNvbXBvbmVudF9BbmltYXRpb25IYW5kbGVyKSB3aXRoIHRoZSBpZCBcImFuaW1hdGlvbkhhbmRsZXJcIiB0byB0aGUgVUkgb2JqZWN0IGlmIG5vdCBhbHJlYWR5IGV4aXN0cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFwcGx5QW5pbWF0aW9uc1xuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBhbmltYXRpb24tZGF0YSBzaG91bGQgYmUgYXBwbGllZCB0by5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgIFxuICAgIGFwcGx5QW5pbWF0aW9uczogKG9iamVjdCkgLT5cbiAgICAgICAgaWYgQGFuaW1hdGlvbnNcbiAgICAgICAgICAgIG9iamVjdC5hbmltYXRpb25zID0gT2JqZWN0LmRlZXBDb3B5KEBhbmltYXRpb25zKVxuICAgICAgICAgICAgaWYgIW9iamVjdC5maW5kQ29tcG9uZW50QnlJZChcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgICAgICAgICBvYmplY3QuYW5pbWF0aW9uRXhlY3V0b3IgPSBuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkV4ZWN1dG9yKClcbiAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQW5pbWF0aW9uSGFuZGxlcigpLCBcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG9iamVjdC5hbmltYXRpb25FeGVjdXRvciwgXCJhbmltYXRpb25FeGVjdXRvclwiKVxuICAgICAgICAgICAgICAgIFxuICAgICAgXG4gICAgIyMjKlxuICAgICogUmV2ZXJ0cyB0aGUgY2hhbmdlcyBmcm9tIGEgVUkgb2JqZWN0IG1hZGUgYnkgdGhpcyBzdHlsZS4gSG93ZXZlciwgdGhpcyByZXNldHMgYWxsIHN0eWxlYWJsZSBwcm9wZXJ0aWVzXG4gICAgKiB3ZXJlIHNldCBieSB0aGlzIHN0eWxlLiBTbyBpdCBpcyBuZWNlc3NhcnkgdG8gYXBwbHkgYWxsIG90aGVyIHN0eWxlcyBhZ2FpbiwgYnV0IHRoYXQgaXMgYWxyZWFkeSBoYW5kbGVzIGluXG4gICAgKiB1aS5Db21wb25lbnRfVUlCZWhhdmlvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJldmVydFxuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBzdHlsZSBzaG91bGQgYmUgcmV2ZXJ0ZWQuXG4gICAgIyMjICAgICAgICAgICAgIFxuICAgIHJldmVydDogKG9iamVjdCkgLT5cbiAgICAgICAgYWN0aXZlU3R5bGVzID0gb2JqZWN0LmFjdGl2ZVN0eWxlc1xuICAgICAgICBpZiBvYmplY3QuYWN0aXZlU3R5bGVzLmNvbnRhaW5zKHRoaXMpXG4gICAgICAgICAgICBvYmplY3QuYWN0aXZlU3R5bGVzLnJlbW92ZSh0aGlzKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBAZm9udCB0aGVuIG9iamVjdC5mb250LnNldChncy5Gb250cy5URVhUKTsgICAgICAgICAgICAgICAoaWYgcy5mb250IHRoZW4gb2JqZWN0LmZvbnQuc2V0KHMuZm9udCk7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBjb2xvciB0aGVuIG9iamVjdC5jb2xvci5zZXQoQ29sb3IuV0hJVEUpOyAgICAgICAgICAgICAgIChpZiBzLmNvbG9yIHRoZW4gb2JqZWN0LmNvbG9yLnNldChzLmNvbG9yKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQHRvbmUgdGhlbiBvYmplY3QudG9uZT8uc2V0KDAsIDAsIDAsIDApOyAgICAgICAgICAgICAgICAgKGlmIHMudG9uZSB0aGVuIG9iamVjdC50b25lPy5zZXQocy50b25lKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGltYWdlIHRoZW4gb2JqZWN0LmltYWdlID0gbnVsbDsgICAgICAgICAgICAgICAgICAgICAgICAgKGlmIHMuaW1hZ2UgdGhlbiBvYmplY3QuaW1hZ2UgPSBzLmltYWdlOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAYW5jaG9yIHRoZW4gb2JqZWN0LmFuY2hvci5zZXQoMCwgMCk7ICAgICAgICAgICAgICAgICAgICAoaWYgcy5hbmNob3IgdGhlbiBvYmplY3QuYW5jaG9yLnNldEZyb21PYmplY3Qocy5hbmNob3IpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAem9vbSB0aGVuIG9iamVjdC56b29tLnNldCgxLjAsIDEuMCk7ICAgICAgICAgICAgICAgICAgICAoaWYgcy56b29tIHRoZW4gb2JqZWN0Lnpvb20uc2V0RnJvbU9iamVjdChzLnpvb20pOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAcGFkZGluZyB0aGVuIG9iamVjdC5wYWRkaW5nLnNldCgwLCAwLCAwLCAwKTsgICAgICAgICAgICAoaWYgcy5wYWRkaW5nIHRoZW4gb2JqZWN0LnBhZGRpbmcuc2V0RnJvbU9iamVjdChzLnBhZGRpbmcpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAbWFyZ2luIHRoZW4gb2JqZWN0Lm1hcmdpbi5zZXQoMCwgMCwgMCwgMCk7ICAgICAgICAgICAgICAoaWYgcy5tYXJnaW4gdGhlbiBvYmplY3QubWFyZ2luLnNldEZyb21PYmplY3Qocy5tYXJnaW4pOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAb3BhY2l0eSA+PSAwIHRoZW4gb2JqZWN0Lm9wYWNpdHkgPSAyNTU7ICAgICAgICAgICAgICAgICAoaWYgcy5vcGFjaXR5ID49IDAgdGhlbiBvYmplY3Qub3BhY2l0eSA9IHMub3BhY2l0eTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGFsaWdubWVudCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudCA9IDA7ICAgICAgICAgICAgICAgKGlmIHMuYWxpZ25tZW50ID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50ID0gcy5hbGlnbm1lbnQ7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBmcmFtZUNvcm5lclNpemUgPj0gMCB0aGVuIG9iamVjdC5mcmFtZUNvcm5lclNpemUgPSAxNjsgIChpZiBzLmZyYW1lQ29ybmVyU2l6ZSA+PSAwIHRoZW4gb2JqZWN0LmZyYW1lQ29ybmVyU2l6ZSA9IHMuZnJhbWVDb3JuZXJTaXplOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAZnJhbWVUaGlja25lc3MgPj0gMCB0aGVuIG9iamVjdC5mcmFtZVRoaWNrbmVzcyA9IDE2OyAgICAoaWYgcy5mcmFtZVRoaWNrbmVzcyA+PSAwIHRoZW4gb2JqZWN0LmZyYW1lVGhpY2tuZXNzID0gcy5mcmFtZVRoaWNrbmVzczsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQG1hc2sgdGhlbiBvYmplY3QubWFzay5zZXQobnVsbCk7ICAgICAgICAgICAgICAgICAgICAgICAgKGlmIHMubWFzayB0aGVuIG9iamVjdC5tYXNrLnNldChzLmZvbnQpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAekluZGV4ID49IDAgdGhlbiBvYmplY3QuekluZGV4ID0gMDsgICAgICAgICAgICAgICAgICAgICAoaWYgcy56SW5kZXggPj0gMCB0aGVuIG9iamVjdC56SW5kZXggPSBzLnpJbmRleDsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGFsaWdubWVudFggPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRYID0gMDsgICAgICAgICAgICAgKGlmIHMuYWxpZ25tZW50WCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudFggPSBzLmFsaWdubWVudFg7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBhbGlnbm1lbnRZID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50WSA9IDA7ICAgICAgICAgICAgIChpZiBzLmFsaWdubWVudFkgPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRZID0gcy5hbGlnbm1lbnRZOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAcmVzaXphYmxlPyB0aGVuIG9iamVjdC5yZXNpemFibGUgPSBubzsgICAgICAgICAgICAgICAgICAoaWYgcy5yZXNpemFibGU/IHRoZW4gb2JqZWN0LnJlc2l6YWJsZSA9IHMucmVzaXphYmxlOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEByZXZlcnRBbmltYXRpb25zKG9iamVjdClcbiAgICAgICAgICAgIEByZXZlcnRMb29waW5nKG9iamVjdClcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogUmV2ZXJ0cyB0aGUgYW5pbWF0aW9uLWRhdGEgY2hhbmdlcyBhcHBsaWVkIHRvIGEgVUkgb2JqZWN0IGJ5IHRoaXMgc3R5bGUuXG4gICAgKlxuICAgICogQG1ldGhvZCByZXZlcnRBbmltYXRpb25zXG4gICAgKiBAcGFyYW0ge3VpLk9iamVjdF9VSUVsZW1lbnR9IG9iamVjdCAtIFRoZSBVSSBvYmplY3Qgd2hlcmUgdGhlIGFuaW1hdGlvbi1kYXRhIGNoYW5nZXMgc2hvdWxkIGJlIHJldmVydGVkLlxuICAgICMjIyAgICAgICAgICAgICAgICAgXG4gICAgcmV2ZXJ0QW5pbWF0aW9uczogKG9iamVjdCkgLT5cbiAgICAgICAgYWN0aXZlU3R5bGVzID0gb2JqZWN0LmFjdGl2ZVN0eWxlc1xuICAgICAgICBpZiBAYW5pbWF0aW9uc1xuICAgICAgICAgICAgb2JqZWN0LmFuaW1hdGlvbnMgPSBudWxsOyAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICAgICAgaWYgcy5hbmltYXRpb25zXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5hbmltYXRpb25zID0gT2JqZWN0LmRlZXBDb3B5KHMuYW5pbWF0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgaWYgIW9iamVjdC5maW5kQ29tcG9uZW50QnlJZChcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5hZGRDb21wb25lbnQobmV3IHVpLkNvbXBvbmVudF9BbmltYXRpb25IYW5kbGVyKCksIFwiYW5pbWF0aW9uSGFuZGxlclwiKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBSZXZlcnRzIHRoZSBsb29waW5nLWRhdGEgY2hhbmdlcyBhcHBsaWVkIHRvIGEgVUkgb2JqZWN0IGJ5IHRoaXMgc3R5bGUuXG4gICAgKlxuICAgICogQG1ldGhvZCByZXZlcnRMb29waW5nXG4gICAgKiBAcGFyYW0ge3VpLk9iamVjdF9VSUVsZW1lbnR9IG9iamVjdCAtIFRoZSBVSSBvYmplY3Qgd2hlcmUgdGhlIGxvb3BpbmctZGF0YSBjaGFuZ2VzIHNob3VsZCBiZSByZXZlcnRlZC5cbiAgICAjIyMgICAgICAgICAgICAgICAgIFxuICAgIHJldmVydExvb3Bpbmc6IChvYmplY3QpIC0+XG4gICAgICAgIGFjdGl2ZVN0eWxlcyA9IG9iamVjdC5hY3RpdmVTdHlsZXNcbiAgICAgICAgaWYgQGxvb3BpbmdcbiAgICAgICAgICAgIG9iamVjdC52aXN1YWwubG9vcGluZy52ZXJ0aWNhbCA9IG5vXG4gICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IG5vXG4gICAgICAgICAgICBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgICAgICBpZiBzLmxvb3BpbmdcbiAgICAgICAgICAgICAgICAgICAgaWYgIW9iamVjdC52aXN1YWwubG9vcGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5yZW1vdmVDb21wb25lbnQob2JqZWN0LnZpc3VhbClcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC52aXN1YWwgPSBuZXcgZ3MuQ29tcG9uZW50X1RpbGluZ1Nwcml0ZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBzLmxvb3BpbmcudmVydGljYWxcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5sb29waW5nLmhvcml6b250YWwgPSBzLmxvb3BpbmcuaG9yaXpvbnRhbFxuICAgICAgICAgICAgXG51aS5TdHlsZSA9IFN0eWxlXG5cbmNsYXNzIFVJTWFuYWdlclxuICAgICMjIypcbiAgICAqIEhhbmRsZXMgdGhlIGNyZWF0aW9uIG9mIEluIEdhbWUgVUkgZWxlbWVudHMuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0XG4gICAgKiBJbi1HYW1lIFVJIHNlZSBoZWxwIGZpbGUuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIFVJTWFuYWdlclxuICAgICogQG1lbWJlcm9mIHVpXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAjIyNcbiAgICBjb25zdHJ1Y3RvcjogLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBVSSBsYXlvdXRzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IGxheW91dHNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBsYXlvdXRzID0ge31cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIHJlZ2lzdGVyZWQgVUkgc3R5bGVzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IHN0eWxlc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHN0eWxlcyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCBVSSBzdHlsZXMgYnkgbnVtYmVyIGlkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdHlsZXNCeUlkXG4gICAgICAgICogQHR5cGUgdWkuU3R5bGVbXVxuICAgICAgICAjIyNcbiAgICAgICAgQHN0eWxlc0J5SWQgPSBuZXcgQXJyYXkoKVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgVUkgc3R5bGVzIGJ5IHN0eWxlLW5hbWUuXG4gICAgICAgICogQHByb3BlcnR5IHN0eWxlc0J5TmFtZVxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHN0eWxlc0J5TmFtZSA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCByZWdpc3RlcmVkIGN1c3RvbSBVSSB0eXBlcy90ZW1wbGF0ZXMgYnkgbmFtZS9pZC5cbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tVHlwZXNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBjdXN0b21UeXBlcyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCByZWdpc3RlcmVkIFVJIGNvbnRyb2xsZXJzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IGN1c3RvbVR5cGVzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAY29udHJvbGxlcnMgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBVSSBkYXRhIHNvdXJjZXMgYnkgbmFtZS9pZC5cbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tVHlwZXNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBkYXRhU291cmNlcyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogTWFwcGluZyB0byB0YWJsZSB0byBtYXAgYWxpZ25tZW50IG5hbWVzIHRvIG51bWJlciB2YWx1ZXMuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudHNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjI1xuICAgICAgICBAYWxpZ25tZW50cyA9IHsgXCJsZWZ0XCI6IDAsIFwidG9wXCI6IDAsIFwiY2VudGVyXCI6IDEsIFwiYm90dG9tXCI6IDIsIFwicmlnaHRcIjogMiwgXCIwXCI6IDAsIFwiMVwiOiAxLCBcIjJcIjogMiB9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogTWFwcGluZyB0byB0YWJsZSB0byBtYXAgYmxlbmQtbW9kZSBuYW1lcyB0byBudW1iZXIgdmFsdWVzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBibGVuZE1vZGVzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyNcbiAgICAgICAgQGJsZW5kTW9kZXMgPSB7IFwibm9ybWFsXCI6IDAsIFwiYWRkXCI6IDEsIFwic3ViXCI6IDIgfVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIE1hcHBpbmcgdG8gdGFibGUgdG8gbWFwIHNlbGVjdG9yIG5hbWVzIHRvIG51bWJlciB2YWx1ZXMuXG4gICAgICAgICogQHByb3BlcnR5IHNlbGVjdG9yc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHNlbGVjdG9ycyA9IHsgbm9ybWFsOiAwLCBob3ZlcjogMSwgc2VsZWN0ZWQ6IDIsIGVuYWJsZWQ6IDMsIGZvY3VzZWQ6IDQgfVxuICAgICAgICBAZGVmYXVsdFBsYWNlaG9sZGVyUGFyYW1zID0ge31cbiAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHVwIFVJIE1hbmFnZXIsIG9wdGltaXplcyBzdHlsZXMsIGV0Yy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldHVwXG4gICAgIyMjXG4gICAgc2V0dXA6IC0+XG4gICAgICAgIEBzZXR1cFN0eWxlcygpXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIFNldHMgdXAgdGhlIFVJIHN0eWxlcyBieSB3cmFwcGluZyB0aGVtIGludG8gdWkuU3R5bGUgb2JqZWN0cyBhbmQgb3B0aW1pemluZyB0aGUgYWNjZXNzLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0dXBTdHlsZXNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyNcbiAgICBzZXR1cFN0eWxlczogLT5cbiAgICAgICAgaWQgPSAwXG4gICAgICAgIHNlbGVjdG9yTWFwID0gQHNlbGVjdG9yc1xuICAgICAgICBmb3IgayBvZiBAc3R5bGVzXG4gICAgICAgICAgICBzdWJzID0gay5zcGxpdChcIiBcIilcbiAgICAgICAgICAgIHNlbGVjdG9yID0gc3Vic1swXS5zcGxpdChcIjpcIilcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgc2VsZWN0b3JNYXBbc2VsZWN0b3JbMV1dXG4gICAgICAgICAgICAgICAgQHN0eWxlc0J5SWRbaWRdID0gbmV3IHVpLlN0eWxlKEBzdHlsZXNba10sIGlkLCBzZWxlY3Rvck1hcFtzZWxlY3RvclsxXV0pXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgQHN0eWxlc0J5SWRbaWRdID0gbmV3IHVpLlN0eWxlKEBzdHlsZXNba10sIGlkLCAwKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAhQHN0eWxlc0J5TmFtZVtzZWxlY3RvclswXV1cbiAgICAgICAgICAgICAgICBAc3R5bGVzQnlOYW1lW3NlbGVjdG9yWzBdXSA9IFtdXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAc3R5bGVzQnlOYW1lW3NlbGVjdG9yWzBdXS5wdXNoKEBzdHlsZXNCeUlkW2lkXSlcbiAgICAgICAgICAgIEBzdHlsZXNba10gPSBAc3R5bGVzQnlJZFtpZF1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWQrK1xuICAgICAgICBcbiAgICAgICAgZm9yIGsgb2YgQHN0eWxlc1xuICAgICAgICAgICAgc3VicyA9IGsuc3BsaXQoXCIgXCIpXG4gICAgICAgICAgICBpZiBzdWJzLmxlbmd0aCA+IDFcbiAgICAgICAgICAgICAgICBAc3R5bGVzQnlOYW1lW3N1YnNbMV1dLnB1c2goQHN0eWxlc1trXSlcbiAgICAgICAgICAgICAgICBAc3R5bGVzW2tdLnRhcmdldCA9IEBzdHlsZXNbay5zcGxpdChcIjpcIilbMF1dPy5pZFxuICAgICAgICAgICAgICAgICNAc3R5bGVzW3N1YnNbMV1dLnRhcmdldCA9IEBzdHlsZXNba10uaWRcbiAgICAgICAgICAgICAgICAjQHN0eWxlc1trXS50YXJnZXQgPSBAc3R5bGVzW3N1YnNbMV1dLmlkXG4gICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRXhlY3V0ZXMgYWxsIHBsYWNlaG9sZGVyIGZvcm11bGFzIGluIHRoZSBzcGVjaWZpZWQgZGVzY3JpcHRvci4gVGhlIGRlc2NyaXB0b3Igd2lsbCBiZSBjaGFuZ2VkXG4gICAgKiBhbmQgcGxhY2Vob2xkZXIgZm9ybXVsYXMgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIgZXZhbHVhdGVkIHJlc3VsdCB2YWx1ZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGV4ZWN1dGVQbGFjZWhvbGRlckZvcm11bGFzXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBkZXNjcmlwdG9yLlxuICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIE9iamVjdCBjb250YWluaW5nIHRoZSBwbGFjZWhvbGRlciBwYXJhbXMuXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgIFxuICAgIGV4ZWN1dGVQbGFjZWhvbGRlckZvcm11bGFzOiAoZGVzY3JpcHRvciwgaWQsIHBhcmFtcykgLT5cbiAgICAgICAgcmV0dXJuIGlmIG5vdCBkZXNjcmlwdG9yP1xuICAgICAgICBrZXlzID0gT2JqZWN0LmtleXMoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIFxuICAgICAgICBmb3IgayBpbiBrZXlzXG4gICAgICAgICAgICB2ID0gZGVzY3JpcHRvcltrXVxuICAgICAgICAgICAgaWYgdj9cbiAgICAgICAgICAgICAgICBpZiB2IGluc3RhbmNlb2YgQXJyYXlcbiAgICAgICAgICAgICAgICAgICAgZm9yIGksIGMgaW4gdlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgaT9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0eXBlb2YgaSA9PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhcyhpLCBpZCwgcGFyYW1zKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYyAhPSBcImV4ZWNcIiBhbmQgdHlwZW9mIGkgPT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5wID0gcGFyYW1zIHx8ICBAZGVmYXVsdFBsYWNlaG9sZGVyUGFyYW1zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5kID0gZGVzY3JpcHRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2W2NdID0gaSgpXG4gICAgICAgICAgICAgICAgZWxzZSBpZiB0eXBlb2YgdiA9PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgIEBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhcyh2LCBpZCwgcGFyYW1zKVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgayAhPSBcImV4ZWNfXCIgYW5kIHR5cGVvZiB2ID09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cucCA9IHBhcmFtcyB8fCBAZGVmYXVsdFBsYWNlaG9sZGVyUGFyYW1zXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5kID0gZGVzY3JpcHRvclxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yW2tdID0gdigpXG4gICAgICAgIHJldHVybiBudWxsXG5cbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgY2FsY3VsYXRpb24gZm9yIGEgc3BlY2lmaWVkIGV4cHJlc3Npb24uXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVDYWxjRnVuY3Rpb25cbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBleHByZXNzaW9uIC0gVGhlIGV4cHJlc3Npb24gdG8gY3JlYXRlIGEgY2FsY3VsYXRpb24gZnVuY3Rpb24gZm9yLlxuICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjYWxjdWxhdGlvbiBmdW5jdGlvbi5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgICAgICAgICBcbiAgICBjcmVhdGVDYWxjRnVuY3Rpb246IChleHByZXNzaW9uKSAtPlxuICAgICAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5yZXBsYWNlKC8oWzAtOV0rKSUvZ20sIFwiKCQxIC8gMTAwICogdilcIilcbiAgICAgICAgcmV0dXJuIGV2YWwoXCIoZnVuY3Rpb24odil7IHJldHVybiBcIiArIGV4cHJlc3Npb24gKyBcIn0pXCIpXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBvYmplY3QgZnJvbSB0aGUgc3BlY2lmaWVkIG9iamVjdCB0eXBlLiBUaGUgdHlwZSBoYXMgdGhlIGZvcm1hdFxuICAgICogPG5hbWVzcGFjZT4uPHR5cGVuYW1lPiBsaWtlIHZuLkNvbXBvbmVudF9Ib3RzcG90LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlT2JqZWN0XG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG5hbWUuXG4gICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgICAgICAgXG4gICAgY3JlYXRlT2JqZWN0OiAodHlwZSkgLT5cbiAgICAgICAgc3VicyA9IHR5cGUuc3BsaXQoXCIuXCIpXG4gICAgICAgIHJldHVybiBuZXcgd2luZG93W3N1YnNbMF1dW3N1YnNbMV1dKClcbiAgICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gVUkgb2JqZWN0IGZyb20gYSBzcGVjaWZpZWQgVUkgZGVzY3JpcHRvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUZyb21EZXNjcmlwdG9yXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEBwYXJhbSB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gcGFyZW50IC0gVGhlIFVJIHBhcmVudCBvYmplY3QuIChBIGxheW91dCBmb3IgZXhhbXBsZSkuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBVSSBvYmplY3QuXG4gICAgIyMjICAgXG4gICAgY3JlYXRlRnJvbURlc2NyaXB0b3I6IChkZXNjcmlwdG9yLCBwYXJlbnQpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBudWxsXG4gICAgICAgIFxuICAgICAgICBmb3IgayBvZiBAY29udHJvbGxlcnNcbiAgICAgICAgICAgIGlmIEBjb250cm9sbGVyc1trXS50eXBlP1xuICAgICAgICAgICAgICAgIEBjb250cm9sbGVyc1trXSA9IEBjcmVhdGVPYmplY3QoQGNvbnRyb2xsZXJzW2tdLnR5cGUpXG4gICAgICAgICAgICBcbiAgICAgICAgQF9jcmVhdGVGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLCBwYXJlbnQpXG4gICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlSW1hZ2VCdXR0b25cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgIFxuICAgIGNyZWF0ZUltYWdlQnV0dG9uOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfSG90c3BvdChkZXNjcmlwdG9yLmltYWdlLCBkZXNjcmlwdG9yLmltYWdlSGFuZGxpbmcpIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmJlaGF2aW9yLnNvdW5kID0gZGVzY3JpcHRvci5zb3VuZFxuICAgICAgICBjb250cm9sLmJlaGF2aW9yLnNvdW5kcyA9IGRlc2NyaXB0b3Iuc291bmRzXG4gICAgICAgIGNvbnRyb2wuaW1hZ2UgPSBkZXNjcmlwdG9yLmltYWdlXG4gICAgICAgIGNvbnRyb2wuaW1hZ2VzID0gZGVzY3JpcHRvci5pbWFnZXNcbiAgICAgICAgaWYgZGVzY3JpcHRvci5pbWFnZUZvbGRlcj9cbiAgICAgICAgICAgIGNvbnRyb2wuaW1hZ2VGb2xkZXIgPSBkZXNjcmlwdG9yLmltYWdlRm9sZGVyXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5sb29waW5nP1xuICAgICAgICAgICAgY29udHJvbC52aXN1YWwuZGlzcG9zZSgpXG4gICAgICAgICAgICBjb250cm9sLnJlbW92ZUNvbXBvbmVudChjb250cm9sLnZpc3VhbClcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsID0gbmV3IGdzLkNvbXBvbmVudF9UaWxpbmdTcHJpdGUoKVxuICAgICAgICAgICAgY29udHJvbC5hZGRDb21wb25lbnQoY29udHJvbC52aXN1YWwpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBkZXNjcmlwdG9yLmxvb3BpbmcudmVydGljYWxcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IGRlc2NyaXB0b3IubG9vcGluZy5ob3Jpem9udGFsXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuY29sb3I/XG4gICAgICAgICAgICBjb250cm9sLmNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuY29sb3IpXG4gICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBpbWFnZSBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVJbWFnZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgXG4gICAgY3JlYXRlSW1hZ2U6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9JbWFnZShkZXNjcmlwdG9yLmltYWdlLCBkZXNjcmlwdG9yLmltYWdlSGFuZGxpbmcpIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmltYWdlRm9sZGVyP1xuICAgICAgICAgICAgY29udHJvbC5pbWFnZUZvbGRlciA9IGRlc2NyaXB0b3IuaW1hZ2VGb2xkZXJcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmxvb3Bpbmc/XG4gICAgICAgICAgICBjb250cm9sLnZpc3VhbC5kaXNwb3NlKClcbiAgICAgICAgICAgIGNvbnRyb2wucmVtb3ZlQ29tcG9uZW50KGNvbnRyb2wudmlzdWFsKVxuICAgICAgICAgICAgY29udHJvbC52aXN1YWwgPSBuZXcgZ3MuQ29tcG9uZW50X1RpbGluZ1Nwcml0ZSgpXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChjb250cm9sLnZpc3VhbClcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29udHJvbC52aXN1YWwubG9vcGluZy52ZXJ0aWNhbCA9IGRlc2NyaXB0b3IubG9vcGluZy52ZXJ0aWNhbFxuICAgICAgICAgICAgY29udHJvbC52aXN1YWwubG9vcGluZy5ob3Jpem9udGFsID0gZGVzY3JpcHRvci5sb29waW5nLmhvcml6b250YWxcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb2xvcj9cbiAgICAgICAgICAgIGNvbnRyb2wuY29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcilcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBpbWFnZSBtYXAgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlSW1hZ2VNYXBcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgICAgIFxuICAgIGNyZWF0ZUltYWdlTWFwOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfSW1hZ2VNYXAoKVxuICAgICAgICBjb250cm9sLmhvdHNwb3RzID0gKGRlc2NyaXB0b3IuaG90c3BvdHN8fFtdKS5zZWxlY3QgKGgpIC0+IFxuICAgICAgICAgICAgeyB4OiBoLnJlY3RbMF0sIHk6IGgucmVjdFsxXSwgc2l6ZTogeyB3aWR0aDogaC5yZWN0WzJdLCBoZWlnaHQ6IGgucmVjdFszXSB9LCBkYXRhOiB7IGFjdGlvbjogMywgYWN0aW9uczogaC5hY3Rpb25zIH0gfVxuICAgICAgICBjb250cm9sLmltYWdlcyA9IGRlc2NyaXB0b3IuaW1hZ2VzXG4gICAgICAgIGNvbnRyb2wuaW5zZXJ0Q29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQWN0aW9uSGFuZGxlcigpLCAxLCBcImFjdGlvbkhhbmRsZXJcIilcbiAgICAgICAgY29udHJvbC50YXJnZXQgPSBTY2VuZU1hbmFnZXIuc2NlbmUuYmVoYXZpb3JcbiAgICAgICAgY29udHJvbC52aXN1YWwudmFyaWFibGVDb250ZXh0ID0gbmV3IGdzLkludGVycHJldGVyQ29udGV4dChTY2VuZU1hbmFnZXIuc2NlbmUubGF5b3V0TmFtZSwgU2NlbmVNYW5hZ2VyLnNjZW5lKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgdmlkZW8gVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlVmlkZW9cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgXG4gICAgY3JlYXRlVmlkZW86IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9WaWRlbygpXG4gICAgICAgIGNvbnRyb2wudmlkZW8gPSBkZXNjcmlwdG9yLnZpZGVvXG4gICAgICAgIGNvbnRyb2wubG9vcCA9IGRlc2NyaXB0b3IubG9vcCA/IHllc1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgcGFuZWwgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlUGFuZWxcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgICAgXG4gICAgY3JlYXRlUGFuZWw6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9QYW5lbCgpXG4gICAgICAgIGNvbnRyb2wubW9kYWwgPSBkZXNjcmlwdG9yLm1vZGFsID8gbm9cbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb2xvcj9cbiAgICAgICAgICAgIGNvbnRyb2wuY29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcilcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBmcmFtZSBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVGcmFtZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgICAgICAgXG4gICAgY3JlYXRlRnJhbWU6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9GcmFtZShkZXNjcmlwdG9yLmZyYW1lU2tpbilcbiAgICAgICAgY29udHJvbC5mcmFtZVRoaWNrbmVzcyA9IGRlc2NyaXB0b3IuZnJhbWVUaGlja25lc3MgfHwgMTZcbiAgICAgICAgY29udHJvbC5mcmFtZUNvcm5lclNpemUgPSBkZXNjcmlwdG9yLmZyYW1lQ29ybmVyU2l6ZSB8fCAxNlxuICAgICAgICBjb250cm9sLmltYWdlID0gZGVzY3JpcHRvci5pbWFnZVxuICAgICAgICBjb250cm9sLmltYWdlcyA9IGRlc2NyaXB0b3IuaW1hZ2VzXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSB0aHJlZS1wYXJ0IGltYWdlIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZVRocmVlUGFydEltYWdlXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVUaHJlZVBhcnRJbWFnZTogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1RocmVlUGFydEltYWdlKGRlc2NyaXB0b3IuZnJhbWVTa2luKVxuICAgICAgICBjb250cm9sLmZpcnN0UGFydFNpemUgPSBkZXNjcmlwdG9yLmZpcnN0UGFydFNpemUgfHwgMTZcbiAgICAgICAgY29udHJvbC5taWRkbGVQYXJ0U2l6ZSA9IGRlc2NyaXB0b3IubWlkZGxlUGFydFNpemUgfHwgMVxuICAgICAgICBjb250cm9sLmxhc3RQYXJ0U2l6ZSA9IGRlc2NyaXB0b3IubGFzdFBhcnRTaXplIHx8IDE2XG4gICAgICAgIGNvbnRyb2wuaW1hZ2UgPSBkZXNjcmlwdG9yLmltYWdlXG4gICAgICAgIGNvbnRyb2wuaW1hZ2VzID0gZGVzY3JpcHRvci5pbWFnZXNcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSB0ZXh0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZVRleHRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgIFxuICAgIGNyZWF0ZVRleHQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9UZXh0KClcbiAgICAgICAgY29udHJvbC50ZXh0ID0gbGNzKGRlc2NyaXB0b3IudGV4dClcbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBjb250cm9sLmZvcm1hdHRpbmcgPSBkZXNjcmlwdG9yLmZvcm1hdHRpbmdcbiAgICAgICAgY29udHJvbC53b3JkV3JhcCA9IGRlc2NyaXB0b3Iud29yZFdyYXAgPyBub1xuICAgICAgICBjb250cm9sLmJlaGF2aW9yLmZvcm1hdCA9IGRlc2NyaXB0b3IuZm9ybWF0XG4gICAgICAgIGlmIGRlc2NyaXB0b3IudGV4dFBhZGRpbmdcbiAgICAgICAgICAgIGNvbnRyb2wuYmVoYXZpb3IucGFkZGluZyA9IHVpLlNwYWNlLmZyb21BcnJheShkZXNjcmlwdG9yLnRleHRQYWRkaW5nKVxuICAgICAgICBpZiBkZXNjcmlwdG9yLnJlc29sdmVQbGFjZWhvbGRlcnM/XG4gICAgICAgICAgICBjb250cm9sLnJlc29sdmVQbGFjZWhvbGRlcnMgPSBkZXNjcmlwdG9yLnJlc29sdmVQbGFjZWhvbGRlcnNcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb2xvcj9cbiAgICAgICAgICAgIGNvbnRyb2wuY29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcilcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBmcmVlLWxheW91dCBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVGcmVlTGF5b3V0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjIFxuICAgIGNyZWF0ZUZyZWVMYXlvdXQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lP1xuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfRnJlZUxheW91dChkZXNjcmlwdG9yLmZyYW1lWzBdIHx8IDAsIGRlc2NyaXB0b3IuZnJhbWVbMV0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsyXSB8fCAxLCBkZXNjcmlwdG9yLmZyYW1lWzNdIHx8IDEpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0ZyZWVMYXlvdXQoMCwgMCwgMSwgMSlcbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgc3RhY2stbGF5b3V0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZVN0YWNrTGF5b3V0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVTdGFja0xheW91dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9TdGFja0xheW91dChkZXNjcmlwdG9yLmZyYW1lWzBdIHx8IDAsIGRlc2NyaXB0b3IuZnJhbWVbMV0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsyXSB8fCAxLCBkZXNjcmlwdG9yLmZyYW1lWzNdIHx8IDEsIGRlc2NyaXB0b3Iub3JpZW50YXRpb24pXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1N0YWNrTGF5b3V0KDAsIDAsIDEsIDEsIGRlc2NyaXB0b3Iub3JpZW50YXRpb24pXG4gICAgICAgIGNvbnRyb2wuc2l6ZVRvRml0ID0gZGVzY3JpcHRvci5zaXplVG9GaXRcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIHNwcmVhZC1sYXlvdXQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlU3ByZWFkTGF5b3V0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVTcHJlYWRMYXlvdXQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lP1xuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfU3ByZWFkTGF5b3V0KGRlc2NyaXB0b3IuZnJhbWVbMF0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsxXSB8fCAwLCBkZXNjcmlwdG9yLmZyYW1lWzJdIHx8IDEsIGRlc2NyaXB0b3IuZnJhbWVbM10gfHwgMSwgZGVzY3JpcHRvci5vcmllbnRhdGlvbilcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfU3ByZWFkTGF5b3V0KDAsIDAsIDEsIDEsIGRlc2NyaXB0b3Iub3JpZW50YXRpb24pXG4gICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIGdyaWQtbGF5b3V0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUdyaWRMYXlvdXRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgXG4gICAgY3JlYXRlR3JpZExheW91dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9HcmlkTGF5b3V0KGRlc2NyaXB0b3IuZnJhbWVbMF0sIGRlc2NyaXB0b3IuZnJhbWVbMV0sIGRlc2NyaXB0b3IuZnJhbWVbMl0sIGRlc2NyaXB0b3IuZnJhbWVbM10sIGRlc2NyaXB0b3Iucm93cywgZGVzY3JpcHRvci5jb2x1bW5zLCBkZXNjcmlwdG9yLnRlbXBsYXRlKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9HcmlkTGF5b3V0KDAsIDAsIDEsIDEsIGRlc2NyaXB0b3Iucm93cywgZGVzY3JpcHRvci5jb2x1bW5zLCBkZXNjcmlwdG9yLnRlbXBsYXRlKVxuICAgICAgICBjb250cm9sLmNlbGxTcGFjaW5nID0gZGVzY3JpcHRvci5jZWxsU3BhY2luZyB8fCBbMCwgMCwgMCwgMF1cbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlTWVzc2FnZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgXG4gICAgY3JlYXRlTWVzc2FnZTogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X01lc3NhZ2UoKSBcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBkYXRhLWdyaWQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlRGF0YUdyaWRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgXG4gICAgY3JlYXRlRGF0YUdyaWQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9EYXRhR3JpZChkZXNjcmlwdG9yKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBVSSBvYmplY3QgZGVwZW5kaW5nIG9uIHRoZSBvYmplY3QtdHlwZSBvZiB0aGUgc3BlY2lmaWVkIFVJIGRlc2NyaXB0b3IuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVDb250cm9sXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIFVJIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgIFxuICAgIGNyZWF0ZUNvbnRyb2w6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgc3dpdGNoIGRlc2NyaXB0b3IudHlwZVxuICAgICAgICAgICAgd2hlbiBcInVpLkltYWdlQnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUltYWdlQnV0dG9uKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuSW1hZ2VcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlSW1hZ2UoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5JbWFnZU1hcFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVJbWFnZU1hcChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlZpZGVvXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVZpZGVvKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuUGFuZWxcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlUGFuZWwoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5GcmFtZVwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVGcmFtZShkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlRocmVlUGFydEltYWdlXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVRocmVlUGFydEltYWdlKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuVGV4dFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVUZXh0KGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVNZXNzYWdlKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuRGF0YUdyaWRcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlRGF0YUdyaWQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5GcmVlTGF5b3V0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUZyZWVMYXlvdXQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5TdGFja0xheW91dFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVTdGFja0xheW91dChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlNwcmVhZExheW91dFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVTcHJlYWRMYXlvdXQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5HcmlkTGF5b3V0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUdyaWRMYXlvdXQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICBcbiAgICBjcmVhdGVMYXlvdXRSZWN0OiAoZnJhbWUsIGNvbnRyb2wpIC0+XG4gICAgICAgIGlmICFjb250cm9sLmxheW91dFJlY3RcbiAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdCA9IG5ldyB1aS5MYXlvdXRSZWN0KClcbiAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnNldCgwLCAwLCAwLCAwKVxuICAgICAgICBcbiAgICAgICAgaWYgZnJhbWU/XG4gICAgICAgICAgICBpZiBmcmFtZVswXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC54ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihmcmFtZVswXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueCA9IDBcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueCA9IChkZXNjcmlwdG9yLmZyYW1lWzBdID8gY29udHJvbC5kc3RSZWN0LngpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBmcmFtZVsxXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC55ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihmcmFtZVsxXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IDBcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IChmcmFtZVsxXSA/IGNvbnRyb2wuZHN0UmVjdC55KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZnJhbWVbMl0/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3Qud2lkdGggPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGZyYW1lWzJdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC53aWR0aCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3Qud2lkdGggPSAoZnJhbWVbMl0gPyBjb250cm9sLmRzdFJlY3Qud2lkdGgpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBmcmFtZVszXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC5oZWlnaHQgPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGZyYW1lWzNdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQgPSAxXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LmhlaWdodCA9IChmcmFtZVszXSA/IGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQpXG4gICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIEFkZHMgdGhlIHN0eWxlcyBkZWZpbmVkIGluIGFuIGFycmF5IG9mIHN0eWxlLW5hbWVzIHRvIHRoZSBzcGVjaWZpZWQgY29udHJvbC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFkZENvbnRyb2xTdHlsZXNcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250cm9sIC0gVGhlIGNvbnRyb2wgdG8gYWRkIHRoZSBzdHlsZXMgdG8uXG4gICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBzdHlsZXMgLSBBcnJheSBvZiBzdHlsZS1uYW1lcyB0byBhZGQuXG4gICAgIyMjICAgICBcbiAgICBhZGRDb250cm9sU3R5bGVzOiAoY29udHJvbCwgc3R5bGVzKSAtPlxuICAgICAgICBmb3Igc3R5bGVOYW1lIGluIHN0eWxlc1xuICAgICAgICAgICAgaWYgQHN0eWxlc0J5TmFtZVtzdHlsZU5hbWVdP1xuICAgICAgICAgICAgICAgIGZvciBzdHlsZSBpbiBAc3R5bGVzQnlOYW1lW3N0eWxlTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5zdHlsZXMucHVzaChzdHlsZSlcbiAgICAgICAgICAgICAgICAgICAgaWYgc3R5bGUudGFyZ2V0ID09IC0xIGFuZCBzdHlsZS5zZWxlY3RvciA9PSAwXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5hcHBseShjb250cm9sKVxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gVUkgb2JqZWN0IGZyb20gYSBzcGVjaWZpZWQgVUkgZGVzY3JpcHRvci4gVGhpcyBtZXRob2QgaXMgY2FsbGVkXG4gICAgKiByZWN1cnNpdmVseSBmb3IgYWxsIGNoaWxkLWRlc2NyaXB0b3JzLlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlQ29udHJvbEZyb21EZXNjcmlwdG9yXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEBwYXJhbSB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gcGFyZW50IC0gVGhlIFVJIHBhcmVudCBvYmplY3QuIChBIGxheW91dCBmb3IgZXhhbXBsZSkuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBUaGUgaW5kZXguXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBVSSBvYmplY3QuXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICAgICBcbiAgICBjcmVhdGVDb250cm9sRnJvbURlc2NyaXB0b3I6IChkZXNjcmlwdG9yLCBwYXJlbnQsIGluZGV4KSAtPlxuICAgICAgICBjb250cm9sID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5zdHlsZT9cbiAgICAgICAgICAgIGRlc2NyaXB0b3Iuc3R5bGVzID0gW2Rlc2NyaXB0b3Iuc3R5bGVdXG4gICAgICAgICAgICBkZWxldGUgZGVzY3JpcHRvci5zdHlsZVxuICAgICAgICAgICAgXG4gICAgICAgIGRlc2NyaXB0b3IgPSBPYmplY3QuZGVlcENvcHkoZGVzY3JpcHRvcilcbiAgICAgICAgQGV4ZWN1dGVQbGFjZWhvbGRlckZvcm11bGFzKGRlc2NyaXB0b3IsIGRlc2NyaXB0b3IuaWQsIGRlc2NyaXB0b3IucGFyYW1zKVxuICAgICAgICAgICAgXG4gICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlQ29udHJvbChkZXNjcmlwdG9yKVxuICAgICAgICBcbiAgICAgICAgaWYgbm90IGNvbnRyb2w/XG4gICAgICAgICAgICB0eXBlID0gT2JqZWN0LmRlZXBDb3B5KEBjdXN0b21UeXBlc1tkZXNjcmlwdG9yLnR5cGVdKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBAZXhlY3V0ZVBsYWNlaG9sZGVyRm9ybXVsYXModHlwZSwgZGVzY3JpcHRvci5pZCwgZGVzY3JpcHRvci5wYXJhbXMpXG4gICAgICAgXG4gICAgICAgICAgICB0eXBlTmFtZSA9IHR5cGUudHlwZVxuICAgICAgICAgICAgY3VzdG9tRmllbGRzID0gdHlwZS5jdXN0b21GaWVsZHNcbiAgICAgICAgICAgIGJpbmRpbmdzID0gdHlwZS5iaW5kaW5nc1xuICAgICAgICAgICAgZm9ybXVsYXMgPSB0eXBlLmZvcm11bGFzXG4gICAgICAgICAgICBhY3Rpb25zID0gdHlwZS5hY3Rpb25zXG4gICAgICAgICAgICBpZiB0eXBlLnN0eWxlP1xuICAgICAgICAgICAgICAgIHR5cGUuc3R5bGVzID0gW3R5cGUuc3R5bGVdXG4gICAgICAgICAgICAgICAgdHlwZS5zdHlsZSA9IG51bGxcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIE9iamVjdC5taXhpbih0eXBlLCBkZXNjcmlwdG9yKVxuICAgICAgICAgICAgaWYgY3VzdG9tRmllbGRzPyB0aGVuIE9iamVjdC5taXhpbih0eXBlLmN1c3RvbUZpZWxkcywgY3VzdG9tRmllbGRzKVxuICAgICAgICAgICAgaWYgYmluZGluZ3M/IGFuZCBiaW5kaW5ncyAhPSB0eXBlLmJpbmRpbmdzIHRoZW4gdHlwZS5iaW5kaW5ncyA9IHR5cGUuYmluZGluZ3MuY29uY2F0KGJpbmRpbmdzKVxuICAgICAgICAgICAgaWYgZm9ybXVsYXM/IGFuZCBmb3JtdWxhcyAhPSB0eXBlLmZvcm11bGFzIHRoZW4gdHlwZS5mb3JtdWxhcyA9IHR5cGUuZm9ybXVsYXMuY29uY2F0KGZvcm11bGFzKVxuICAgICAgICAgICAgaWYgYWN0aW9ucz8gYW5kIGFjdGlvbnMgIT0gdHlwZS5hY3Rpb25zIHRoZW4gdHlwZS5hY3Rpb25zID0gYWN0aW9ucy5jb25jYXQodHlwZS5hY3Rpb25zKVxuICAgICAgICAgICAgdHlwZS50eXBlID0gdHlwZU5hbWVcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcmV0dXJuIEBjcmVhdGVDb250cm9sRnJvbURlc2NyaXB0b3IodHlwZSwgcGFyZW50KVxuICAgICAgICBlbHNlIGlmIHBhcmVudD9cbiAgICAgICAgICAgIHBhcmVudC5hZGRPYmplY3QoY29udHJvbClcbiAgICAgICAgICAgIGNvbnRyb2wuaW5kZXggPSBpbmRleFxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQuYWRkT2JqZWN0KGNvbnRyb2wpXG4gICAgICAgICBcbiAgICAgICAgY29udHJvbC51aSA9IG5ldyB1aS5Db21wb25lbnRfVUlCZWhhdmlvcigpXG4gICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbnRyb2wudWkpXG4gICAgICAgIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgY29udHJvbC5wYXJhbXMgPSBkZXNjcmlwdG9yLnBhcmFtc1xuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci51cGRhdGVCZWhhdmlvciA9PSBcImNvbnRpbnVvdXNcIlxuICAgICAgICAgICAgY29udHJvbC51cGRhdGVCZWhhdmlvciA9IHVpLlVwZGF0ZUJlaGF2aW9yLkNPTlRJTlVPVVNcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmluaGVyaXRQcm9wZXJ0aWVzXG4gICAgICAgICAgICBjb250cm9sLmluaGVyaXRQcm9wZXJ0aWVzID0geWVzXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb250P1xuICAgICAgICAgICAgY29udHJvbC5mb250ID0gbmV3IEZvbnQoZGVzY3JpcHRvci5mb250Lm5hbWUsIGRlc2NyaXB0b3IuZm9udC5zaXplKVxuICAgICAgICAgICAgY29udHJvbC5mb250LmJvbGQgPSBkZXNjcmlwdG9yLmZvbnQuYm9sZCA/IGNvbnRyb2wuZm9udC5ib2xkXG4gICAgICAgICAgICBjb250cm9sLmZvbnQuaXRhbGljID0gZGVzY3JpcHRvci5mb250Lml0YWxpYyA/IGNvbnRyb2wuZm9udC5pdGFsaWNcbiAgICAgICAgICAgIGNvbnRyb2wuZm9udC5zbWFsbENhcHMgPSBkZXNjcmlwdG9yLmZvbnQuc21hbGxDYXBzID8gY29udHJvbC5mb250LnNtYWxsQ2Fwc1xuICAgICAgICAgICAgY29udHJvbC5mb250LnVuZGVybGluZSA9IGRlc2NyaXB0b3IuZm9udC51bmRlcmxpbmUgPyBjb250cm9sLmZvbnQudW5kZXJsaW5lXG4gICAgICAgICAgICBjb250cm9sLmZvbnQuc3RyaWtlVGhyb3VnaCA9IGRlc2NyaXB0b3IuZm9udC5zdHJpa2VUaHJvdWdoID8gY29udHJvbC5mb250LnN0cmlrZVRocm91Z2hcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mb250LmNvbG9yP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5jb2xvciA9IENvbG9yLmZyb21BcnJheShkZXNjcmlwdG9yLmZvbnQuY29sb3IpXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5ib3JkZXIgPSBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyID8gbm9cbiAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyU2l6ZSA9IGRlc2NyaXB0b3IuZm9udC5ib3JkZXJTaXplID8gNFxuICAgICAgICAgICAgICAjaWYgZGVzY3JpcHRvci5mb250LmJvcmRlci5jb2xvclxuICAgICAgICAgICAgIyAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5ib3JkZXIuY29sb3IpXG4gICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gbmV3IENvbG9yKDAsIDAsIDApXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQub3V0bGluZT9cbiAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUgPyBub1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5ib3JkZXJTaXplID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUuc2l6ZSA/IDRcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQub3V0bGluZS5jb2xvcj9cbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lLmNvbG9yKVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gbmV3IENvbG9yKDAsIDAsIDApXG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb21wb25lbnRzP1xuICAgICAgICAgICAgZm9yIGMgaW4gZGVzY3JpcHRvci5jb21wb25lbnRzXG4gICAgICAgICAgICAgICAgbSA9IGMubW9kdWxlIHx8IFwiZ3NcIlxuICAgICAgICAgICAgICAgIGNvbXBvbmVudCA9IG5ldyB3aW5kb3dbbV1bYy50eXBlXShjLnBhcmFtcylcbiAgICAgICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChjb21wb25lbnQsIGMuaWQpXG4gICAgICAgICAgICAgICAgY29udHJvbFtjLmlkXSA9IGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICNjb21wb25lbnQuc2V0dXA/KClcbiAgICAgICAgIFxuICAgICAgICBjb250cm9sLmZvY3VzYWJsZSA9IGRlc2NyaXB0b3IuZm9jdXNhYmxlID8gY29udHJvbC5mb2N1c2FibGUgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IubmV4dEtleU9iamVjdFxuICAgICAgICAgICAgY29udHJvbC51aS5uZXh0S2V5T2JqZWN0SWQgPSBkZXNjcmlwdG9yLm5leHRLZXlPYmplY3RcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuaW5pdGlhbEZvY3VzXG4gICAgICAgICAgICBjb250cm9sLnVpLmZvY3VzKClcbiAgICAgICAgICAgIFxuICAgICAgICBhY3Rpb25zID0gT2JqZWN0LmRlZXBDb3B5KGlmIGRlc2NyaXB0b3IuYWN0aW9uPyB0aGVuIFtkZXNjcmlwdG9yLmFjdGlvbl0gZWxzZSBkZXNjcmlwdG9yLmFjdGlvbnMpIFxuICAgICAgICBpZiBhY3Rpb25zP1xuICAgICAgICAgICAgZm9yIGFjdGlvbiBpbiBhY3Rpb25zXG4gICAgICAgICAgICAgICAgaWYgYWN0aW9uP1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb24uZXZlbnQgPSBhY3Rpb24uZXZlbnQgPyBcIm9uQWNjZXB0XCJcbiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGFjdGlvbi50YXJnZXQ/XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBpZiBAY29udHJvbGxlcnM/IHRoZW4gQGNvbnRyb2xsZXJzW2Rlc2NyaXB0b3IudGFyZ2V0XSBlbHNlIGNvbnRyb2xsZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbi50YXJnZXQgPSB0YXJnZXQgfHwgU2NlbmVNYW5hZ2VyLnNjZW5lLmJlaGF2aW9yXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnRyb2wuYWN0aW9ucyA9IGFjdGlvbnNcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYoIWNvbnRyb2wuZmluZENvbXBvbmVudEJ5SWQoXCJhY3Rpb25IYW5kbGVyXCIpKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuaW5zZXJ0Q29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQWN0aW9uSGFuZGxlcigpLCAxLCBcImFjdGlvbkhhbmRsZXJcIilcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuaWQ/XG4gICAgICAgICAgICBjb250cm9sLmlkID0gZGVzY3JpcHRvci5pZFxuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQoY29udHJvbCwgY29udHJvbC5pZClcbiAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yXG4gICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdCA9IG5ldyBSZWN0KClcbiAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnNldCgwLCAwLCAwLCAwKVxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lP1xuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mcmFtZVswXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC54ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzBdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC54ID0gMFxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC54ID0gKGRlc2NyaXB0b3IuZnJhbWVbMF0gPyBjb250cm9sLmRzdFJlY3QueClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWVbMV0/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3QueSA9IEBjcmVhdGVDYWxjRnVuY3Rpb24oZGVzY3JpcHRvci5mcmFtZVsxXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IDBcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IChkZXNjcmlwdG9yLmZyYW1lWzFdID8gY29udHJvbC5kc3RSZWN0LnkpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lWzJdPy5sZW5ndGg/XG4gICAgICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LndpZHRoID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzJdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC53aWR0aCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3Qud2lkdGggPSAoZGVzY3JpcHRvci5mcmFtZVsyXSA/IGNvbnRyb2wuZHN0UmVjdC53aWR0aClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWVbM10/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3QuaGVpZ2h0ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzNdKSAjcGFyc2VJbnQoZGVzY3JpcHRvci5mcmFtZVszXS5zcGxpdChcIiVcIilbMF0pXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LmhlaWdodCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QuaGVpZ2h0ID0gKGRlc2NyaXB0b3IuZnJhbWVbM10gPyBjb250cm9sLmRzdFJlY3QuaGVpZ2h0KVxuICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5zaXplVG9QYXJlbnQ/XG4gICAgICAgICAgICBjb250cm9sLnNpemVUb1BhcmVudCA9IGRlc2NyaXB0b3Iuc2l6ZVRvUGFyZW50XG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5ibGVuZE1vZGU/XG4gICAgICAgICAgICBjb250cm9sLmJsZW5kTW9kZSA9IEBibGVuZE1vZGVzW2Rlc2NyaXB0b3IuYmxlbmRNb2RlXVxuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuYW5jaG9yP1xuICAgICAgICAgICAgY29udHJvbC5hbmNob3Iuc2V0KGRlc2NyaXB0b3IuYW5jaG9yWzBdLCBkZXNjcmlwdG9yLmFuY2hvclsxXSlcbiAgICAgICAgXG5cbiAgICAgICAgY29udHJvbC5vcGFjaXR5ID0gZGVzY3JpcHRvci5vcGFjaXR5ID8gMjU1ICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLm1pbmltdW1TaXplP1xuICAgICAgICAgICAgY29udHJvbC5taW5pbXVtU2l6ZSA9IHsgd2lkdGg6IGRlc2NyaXB0b3IubWluaW11bVNpemVbMF0sIGhlaWdodDogZGVzY3JpcHRvci5taW5pbXVtU2l6ZVsxXSB9XG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5yZXNpemFibGU/IHRoZW4gY29udHJvbC5yZXNpemFibGUgPSBkZXNjcmlwdG9yLnJlc2l6YWJsZVxuICAgICAgICBpZiBkZXNjcmlwdG9yLnNjcm9sbGFibGU/IHRoZW4gY29udHJvbC5zY3JvbGxhYmxlID0gZGVzY3JpcHRvci5zY3JvbGxhYmxlIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZpeGVkU2l6ZT8gdGhlbiBjb250cm9sLmZpeGVkU2l6ZSA9IGRlc2NyaXB0b3IuZml4ZWRTaXplXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZHJhZ2dhYmxlP1xuICAgICAgICAgICAgY29udHJvbC5kcmFnZ2FibGUgPSBkZXNjcmlwdG9yLmRyYWdnYWJsZVxuICAgICAgICAgICAgY29udHJvbC5kcmFnZ2FibGUuc3RlcCA9IDBcbiAgICAgICAgICAgIGlmIGNvbnRyb2wuZHJhZ2dhYmxlLnJlY3Q/XG4gICAgICAgICAgICAgICAgY29udHJvbC5kcmFnZ2FibGUucmVjdCA9IFJlY3QuZnJvbUFycmF5KGNvbnRyb2wuZHJhZ2dhYmxlLnJlY3QpXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0RyYWdnYWJsZSgpKVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5iaW5kaW5ncz9cbiAgICAgICAgICAgIGNvbnRyb2wuYmluZGluZ3MgPSBkZXNjcmlwdG9yLmJpbmRpbmdzXG4gICAgICAgICAgICBjb250cm9sLmluc2VydENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0JpbmRpbmdIYW5kbGVyKCksIDApXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb3JtdWxhcz9cbiAgICAgICAgICAgIGNvbnRyb2wuZm9ybXVsYXMgPSBkZXNjcmlwdG9yLmZvcm11bGFzXG4gICAgICAgICAgICBjb250cm9sLmluc2VydENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0Zvcm11bGFIYW5kbGVyKCksIDApXG4gICAgICAgICAgICBcbiAgICAgICAgY29udHJvbC5kYXRhRmllbGQgPSBkZXNjcmlwdG9yLmRhdGFGaWVsZFxuICAgICAgICBjb250cm9sLmVuYWJsZWQgPSBkZXNjcmlwdG9yLmVuYWJsZWQgPyB5ZXNcbiAgICAgICAgaWYgZGVzY3JpcHRvci5zZWxlY3RhYmxlPyB0aGVuIGNvbnRyb2wuc2VsZWN0YWJsZSA9IGRlc2NyaXB0b3Iuc2VsZWN0YWJsZVxuICAgICAgICBpZiBkZXNjcmlwdG9yLmdyb3VwPyBcbiAgICAgICAgICAgIGNvbnRyb2wuZ3JvdXAgPSBkZXNjcmlwdG9yLmdyb3VwXG4gICAgICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQuYWRkVG9Hcm91cChjb250cm9sLCBjb250cm9sLmdyb3VwKVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jdXN0b21GaWVsZHM/XG4gICAgICAgICAgICBjb250cm9sLmN1c3RvbUZpZWxkcyA9IE9iamVjdC5kZWVwQ29weShkZXNjcmlwdG9yLmN1c3RvbUZpZWxkcylcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLm1hcmdpbj9cbiAgICAgICAgICAgIGNvbnRyb2wubWFyZ2luLmxlZnQgPSBkZXNjcmlwdG9yLm1hcmdpblswXVxuICAgICAgICAgICAgY29udHJvbC5tYXJnaW4udG9wID0gZGVzY3JpcHRvci5tYXJnaW5bMV1cbiAgICAgICAgICAgIGNvbnRyb2wubWFyZ2luLnJpZ2h0ID0gZGVzY3JpcHRvci5tYXJnaW5bMl1cbiAgICAgICAgICAgIGNvbnRyb2wubWFyZ2luLmJvdHRvbSA9IGRlc2NyaXB0b3IubWFyZ2luWzNdXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5wYWRkaW5nP1xuICAgICAgICAgICAgY29udHJvbC5wYWRkaW5nLmxlZnQgPSBkZXNjcmlwdG9yLnBhZGRpbmdbMF1cbiAgICAgICAgICAgIGNvbnRyb2wucGFkZGluZy50b3AgPSBkZXNjcmlwdG9yLnBhZGRpbmdbMV1cbiAgICAgICAgICAgIGNvbnRyb2wucGFkZGluZy5yaWdodCA9IGRlc2NyaXB0b3IucGFkZGluZ1syXVxuICAgICAgICAgICAgY29udHJvbC5wYWRkaW5nLmJvdHRvbSA9IGRlc2NyaXB0b3IucGFkZGluZ1szXVxuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuYWxpZ25tZW50P1xuICAgICAgICAgICAgY29udHJvbC5hbGlnbm1lbnQgPSBAYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudF1cbiAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmFsaWdubWVudFkgPSBAYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudFkgfHwgMF1cbiAgICAgICAgY29udHJvbC5hbGlnbm1lbnRYID0gQGFsaWdubWVudHNbZGVzY3JpcHRvci5hbGlnbm1lbnRYIHx8IDBdXG4gICAgICAgIGNvbnRyb2wuekluZGV4ID0gZGVzY3JpcHRvci56SW5kZXggfHwgMFxuICAgICAgICBjb250cm9sLm9yZGVyID0gZGVzY3JpcHRvci5vcmRlciB8fCAwXG4gICAgICAgIGNvbnRyb2wuY2hhaW5PcmRlciA9IChkZXNjcmlwdG9yLmNoYWluT3JkZXIgPyBkZXNjcmlwdG9yLnpPcmRlcikgKyAocGFyZW50Py5jaGFpbk9yZGVyIHx8IDApXG4gICAgICAgIGlmIGRlc2NyaXB0b3Iuem9vbT9cbiAgICAgICAgICAgIGNvbnRyb2wuem9vbSA9IHg6IGRlc2NyaXB0b3Iuem9vbVswXSAvIDEwMCwgeTogZGVzY3JpcHRvci56b29tWzFdIC8gMTAwXG4gICAgICAgICNjb250cm9sLmRhdGFGaWVsZHMgPSBkYXRhRmllbGRzXG4gICAgICAgICNjb250cm9sLmNvbnRyb2xsZXJzID0gQGNvbnRyb2xsZXJzXG4gICAgICAgICNjb250cm9sLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnZpc2libGU/XG4gICAgICAgICAgICBjb250cm9sLnZpc2libGUgPSBkZXNjcmlwdG9yLnZpc2libGVcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jbGlwUmVjdFxuICAgICAgICAgICAgY29udHJvbC5jbGlwUmVjdCA9IG5ldyBSZWN0KGNvbnRyb2wuZHN0UmVjdC54LCBjb250cm9sLmRzdFJlY3QueSwgY29udHJvbC5kc3RSZWN0LndpZHRoLCBjb250cm9sLmRzdFJlY3QuaGVpZ2h0KVxuXG4gICAgICAgIGlmIGRlc2NyaXB0b3Iuc3R5bGVzP1xuICAgICAgICAgICAgQGFkZENvbnRyb2xTdHlsZXMoY29udHJvbCwgZGVzY3JpcHRvci5zdHlsZXMpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IudGVtcGxhdGU/XG4gICAgICAgICAgICBjb250cm9sLmJlaGF2aW9yLm1hbmFnZW1lbnRNb2RlID0gdWkuTGF5b3V0TWFuYWdlbWVudE1vZGUuZnJvbVN0cmluZyhkZXNjcmlwdG9yLm1hbmFnZW1lbnRNb2RlKVxuICAgICAgICAgICAgZGF0YSA9IHVpLkNvbXBvbmVudF9Gb3JtdWxhSGFuZGxlci5maWVsZFZhbHVlKGNvbnRyb2wsIGNvbnRyb2wuZGF0YUZpZWxkKSAjY29udHJvbC5kYXRhRmllbGRzW2NvbnRyb2wuZGF0YUZpZWxkXVxuICAgICAgICAgICAgaXNOdW1iZXIgPSB0eXBlb2YgZGF0YSA9PSBcIm51bWJlclwiXG4gICAgICAgICAgICBpZiBkYXRhP1xuICAgICAgICAgICAgICAgIGZvciBpIGluIFswLi4uKGRhdGEubGVuZ3RoID8gZGF0YSldXG4gICAgICAgICAgICAgICAgICAgIGlmIGRhdGFbaV0/IG9yIGlzTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IHllc1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5kYXRhRmlsdGVyPyBhbmQgbm90IGlzTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSB1aS5Db21wb25lbnRfSGFuZGxlci5jaGVja0NvbmRpdGlvbihkYXRhW2ldLCBkZXNjcmlwdG9yLmRhdGFGaWx0ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiB2YWxpZCBvciBpc051bWJlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gQGNyZWF0ZUNvbnRyb2xGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLnRlbXBsYXRlLCBjb250cm9sLCBpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICNjaGlsZC5kYXRhRmllbGRzID0gY29udHJvbC5kYXRhRmllbGRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGF0YVtpXT8uZHN0UmVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5kc3RSZWN0ID0gdWkuVUlFbGVtZW50UmVjdGFuZ2xlLmZyb21SZWN0KGNoaWxkLCBkYXRhW2ldLmRzdFJlY3QpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vdCBjaGlsZC5jbGlwUmVjdD8pIGFuZCBjb250cm9sLmNsaXBSZWN0P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5jbGlwUmVjdCA9IGNvbnRyb2wuY2xpcFJlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY2hpbGQucGFyZW50ID0gY29udHJvbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuYWRkT2JqZWN0KGNoaWxkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmluZGV4ID0gaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLm9yZGVyID0gKGRhdGEubGVuZ3RoID8gZGF0YSkgLSBpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5jb250cm9scy5wdXNoKGNoaWxkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb250cm9scyBhbmQgZGVzY3JpcHRvci5jb250cm9scy5leGVjXG4gICAgICAgICAgICBjb250cm9scyA9IHVpLkNvbXBvbmVudF9Gb3JtdWxhSGFuZGxlci5maWVsZFZhbHVlKGRlc2NyaXB0b3IsIGRlc2NyaXB0b3IuY29udHJvbHMpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2xzID0gZGVzY3JpcHRvci5jb250cm9sc1xuICAgICAgICAgICAgXG4gICAgICAgIGlmIGNvbnRyb2xzP1xuICAgICAgICAgICAgZm9yIGl0ZW0sIGkgaW4gY29udHJvbHNcbiAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wgPSBAX2NyZWF0ZUZyb21EZXNjcmlwdG9yKGl0ZW0sIGNvbnRyb2wsIGkpXG4gICAgICAgICAgICAgICAgaWYgKG5vdCBjaGlsZENvbnRyb2wuY2xpcFJlY3Q/KSBhbmQgY29udHJvbC5jbGlwUmVjdD9cbiAgICAgICAgICAgICAgICAgICAgY2hpbGRDb250cm9sLmNsaXBSZWN0ID0gY29udHJvbC5jbGlwUmVjdFxuICAgICAgICAgICAgICAgIGNoaWxkQ29udHJvbC5pbmRleCA9IGlcbiAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wub3JpZ2luLnggPSBjb250cm9sLm9yaWdpbi54ICsgY29udHJvbC5kc3RSZWN0LnhcbiAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wub3JpZ2luLnkgPSBjb250cm9sLm9yaWdpbi55ICsgY29udHJvbC5kc3RSZWN0LnlcbiAgICAgICAgICAgICAgICAjY2hpbGRDb250cm9sLnBhcmVudCA9IGNvbnRyb2xcbiAgICAgICAgICAgICAgICBjb250cm9sLmFkZE9iamVjdChjaGlsZENvbnRyb2wpXG4gICAgICAgICAgICAgICAgY29udHJvbC5jb250cm9scy5wdXNoKGNoaWxkQ29udHJvbClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgY29udHJvbC5zdHlsZXMgYW5kIGNvbnRyb2wucGFyZW50c0J5U3R5bGVcbiAgICAgICAgICAgICNmb3Igc3R5bGUgaW4gY29udHJvbC5zdHlsZXNcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50ID0gY29udHJvbC5wYXJlbnRcbiAgICAgICAgICAgIHdoaWxlIHBhcmVudFxuICAgICAgICAgICAgICAgIGlmIHBhcmVudC5zdHlsZXNcbiAgICAgICAgICAgICAgICAgICAgZm9yIHN0eWxlIGluIHBhcmVudC5zdHlsZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICFjb250cm9sLnBhcmVudHNCeVN0eWxlW3N0eWxlLmlkXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdID0gW11cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdLnB1c2gocGFyZW50KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICN3aGlsZSBwYXJlbnRcbiAgICAgICAgICAgICAgICAgICAgI2lmIHBhcmVudC5jb250cm9sc0J5U3R5bGVcbiAgICAgICAgICAgICAgICAgICAgIyAgICBpZighcGFyZW50LmNvbnRyb2xzQnlTdHlsZVtzdHlsZS5pZF0pXG4gICAgICAgICAgICAgICAgICAgICMgICAgICAgIHBhcmVudC5jb250cm9sc0J5U3R5bGVbc3R5bGUuaWRdID0gW11cbiAgICAgICAgICAgICAgICAgICAgIyAgICBwYXJlbnQuY29udHJvbHNCeVN0eWxlW3N0eWxlLmlkXS5wdXNoKGNvbnRyb2wpXG4gICAgICAgICAgICAgICAgICAjICBpZiBjb250cm9sLnBhcmVudHNCeVN0eWxlXG4gICAgICAgICAgICAgICAgICAjICAgICAgaWYgIWNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdXG4gICAgICAgICAgICAgICAgICAjICAgICAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdID0gW11cbiAgICAgICAgICAgICAgICAgICMgICAgICBjb250cm9sLnBhcmVudHNCeVN0eWxlW3N0eWxlLmlkXS5wdXNoKHBhcmVudClcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5hbmltYXRpb25zP1xuICAgICAgICAgICAgY29udHJvbC5hbmltYXRpb25zID0gT2JqZWN0LmRlZXBDb3B5KGRlc2NyaXB0b3IuYW5pbWF0aW9ucylcbiAgICAgICAgICAgIGNvbnRyb2wuYW5pbWF0aW9uRXhlY3V0b3IgPSBuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkV4ZWN1dG9yKClcbiAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbnRyb2wuYW5pbWF0aW9uRXhlY3V0b3IpXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkhhbmRsZXIoKSlcbiAgICAgICAgIFxuICAgICAgICBjb250cm9sLnVpLnVwZGF0ZVN0eWxlKClcbiAgICAgICAgY29udHJvbC5zZXR1cCgpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGFuIFVJIG9iamVjdCBmcm9tIGEgc3BlY2lmaWVkIFVJIGRlc2NyaXB0b3IuXG4gICAgKlxuICAgICogQG1ldGhvZCBfY3JlYXRlRnJvbURlc2NyaXB0b3JcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHBhcmFtIHtncy5PYmplY3RfVUlFbGVtZW50fSBwYXJlbnQgLSBUaGUgVUkgcGFyZW50IG9iamVjdC4gKEEgbGF5b3V0IGZvciBleGFtcGxlKS5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIFVJIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWQgXG4gICAgIyMjICAgXG4gICAgX2NyZWF0ZUZyb21EZXNjcmlwdG9yOiAoZGVzY3JpcHRvciwgcGFyZW50LCBpbmRleCkgLT4gICAgIFxuICAgICAgICBjb250cm9sID0gQGNyZWF0ZUNvbnRyb2xGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLCBwYXJlbnQsIGluZGV4KVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb250cm9sbGVyP1xuICAgICAgICAgICAgY29udHJvbGxlciA9IEBjb250cm9sbGVyc1tkZXNjcmlwdG9yLmNvbnRyb2xsZXJdXG4gICAgICAgICAgICBjb250cm9sLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChjb250cm9sbGVyKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICAgICBcbiAgICBjcmVhdGVMYXlvdXRGcm9tRGVzY3JpcHRvcjogKGRlc2NyaXB0b3IsIHBhcmVudCwgaW5kZXgpIC0+XG4gICAgICAgIEBfY3JlYXRlRnJvbURlc2NyaXB0b3IoZGVzY3JpcHRvciwgcGFyZW50LCBpbmRleClcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIFxuR3JhcGhpY3Mud2lkdGggPSAkUEFSQU1TLnJlc29sdXRpb24ud2lkdGhcbkdyYXBoaWNzLmhlaWdodCA9ICRQQVJBTVMucmVzb2x1dGlvbi5oZWlnaHRcbnVpLlVpRmFjdG9yeSA9IG5ldyBVSU1hbmFnZXIoKVxudWkuVUlNYW5hZ2VyID0gdWkuVWlGYWN0b3J5Il19\n//# sourceURL=UIManager_103.js"
13 13 },
14 14 "summary": [
15 15 "name",