uicore-ts 1.1.146 → 1.1.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiledScripts/UICore.js +1 -0
- package/compiledScripts/UICore.js.map +2 -2
- package/compiledScripts/UIRectangle.js.map +1 -1
- package/compiledScripts/UITextField.d.ts +14 -0
- package/compiledScripts/UITextField.js +52 -0
- package/compiledScripts/UITextField.js.map +2 -2
- package/compiledScripts/UIView.d.ts +1 -0
- package/compiledScripts/UIView.js +17 -4
- package/compiledScripts/UIView.js.map +2 -2
- package/package.json +1 -1
- package/scripts/UICore.ts +1 -1
- package/scripts/UIRectangle.ts +1 -1
- package/scripts/UITextField.ts +84 -0
- package/scripts/UIView.ts +24 -5
|
@@ -65,6 +65,7 @@ const _UICore = class extends import_UIObject.UIObject {
|
|
|
65
65
|
this.rootViewController._triggerLayoutViewSubviews();
|
|
66
66
|
import_UIView.UIView.layoutViewsIfNeeded();
|
|
67
67
|
this.rootViewController._triggerLayoutViewSubviews();
|
|
68
|
+
import_UIView.UIView.layoutViewsIfNeeded();
|
|
68
69
|
this.rootViewController.view.broadcastEventInSubtree({
|
|
69
70
|
name: _UICore.broadcastEventName.WindowDidResize,
|
|
70
71
|
parameters: import_UIObject.nil
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UICore.ts"],
|
|
4
|
-
"sourcesContent": ["import \"./UICoreExtensions\"\nimport { UILanguageService } from \"./UIInterfaces\"\nimport { nil, NO, UIObject } from \"./UIObject\"\nimport { UIRoute } from \"./UIRoute\"\nimport { UIView } from \"./UIView\"\nimport { UIViewController } from \"./UIViewController\"\n\n\nexport class UICore extends UIObject {\n \n rootViewController: UIViewController\n \n \n \n static RootViewControllerClass: typeof UIViewController\n static main: UICore\n \n static languageService: UILanguageService = nil\n \n static readonly broadcastEventName = {\n \n \"RouteDidChange\": \"RouteDidChange\",\n \"WindowDidResize\": \"WindowDidResize\"\n \n }\n \n constructor(rootDivElementID: string, rootViewControllerClass: typeof UIViewController, public paddingLength = 20) {\n \n super()\n \n UICore.RootViewControllerClass = rootViewControllerClass\n UICore.main = UICore.main || this\n \n const rootViewElement = document.getElementById(rootDivElementID)\n const rootView = new UIView(rootDivElementID, rootViewElement)\n rootView.pausesPointerEvents = NO //YES;\n rootView.core = this\n \n if (UICore.RootViewControllerClass) {\n \n if (!(UICore.RootViewControllerClass.prototype instanceof UIViewController) ||\n (UICore.RootViewControllerClass as any) === UIViewController) {\n \n console.log(\n \"Error, UICore.RootViewControllerClass must be UIViewController or a subclass of UIViewController, \" +\n \"falling back to UIViewController.\"\n )\n \n UICore.RootViewControllerClass = UIViewController\n \n }\n \n this.rootViewController = new UICore.RootViewControllerClass(rootView)\n \n }\n else {\n \n this.rootViewController = new UIViewController(rootView)\n \n }\n \n this.rootViewController.viewWillAppear().then(() =>\n this.rootViewController.viewDidAppear()\n )\n \n \n this.rootViewController.view.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n () => {\n \n (document.activeElement as HTMLElement)?.blur?.()\n \n }\n )\n \n \n const windowDidResize = () => {\n \n this.rootViewController.view.forEachViewInSubtree((view) => {\n \n view._frameCache = undefined\n \n })\n // Doing layout two times to prevent page scrollbars from confusing the layout\n this.rootViewController.view.setNeedsLayout()\n this.rootViewController._triggerLayoutViewSubviews()\n UIView.layoutViewsIfNeeded()\n \n this.rootViewController._triggerLayoutViewSubviews()\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAAO;AAEP,sBAAkC;AAClC,qBAAwB;AACxB,oBAAuB;AACvB,8BAAiC;AAG1B,MAAM,UAAN,cAAqB,yBAAS;AAAA,EAkBjC,YAAY,kBAA0B,yBAAyD,gBAAgB,IAAI;AAE/G,UAAM;AAFqF;AAI3F,YAAO,0BAA0B;AACjC,YAAO,OAAO,QAAO,QAAQ;AAE7B,UAAM,kBAAkB,SAAS,eAAe,gBAAgB;AAChE,UAAM,WAAW,IAAI,qBAAO,kBAAkB,eAAe;AAC7D,aAAS,sBAAsB;AAC/B,aAAS,OAAO;AAEhB,QAAI,QAAO,yBAAyB;AAEhC,UAAI,EAAE,QAAO,wBAAwB,qBAAqB,6CACrD,QAAO,4BAAoC,0CAAkB;AAE9D,gBAAQ;AAAA,UACJ;AAAA,QAEJ;AAEA,gBAAO,0BAA0B;AAAA,MAErC;AAEA,WAAK,qBAAqB,IAAI,QAAO,wBAAwB,QAAQ;AAAA,IAEzE,OACK;AAED,WAAK,qBAAqB,IAAI,yCAAiB,QAAQ;AAAA,IAE3D;AAEA,SAAK,mBAAmB,eAAe,EAAE;AAAA,MAAK,MAC1C,KAAK,mBAAmB,cAAc;AAAA,IAC1C;AAGA,SAAK,mBAAmB,KAAK;AAAA,MACzB,qBAAO,aAAa;AAAA,MACpB,MAAM;AApElB;AAsEgB,SAAC,oBAAS,kBAAT,mBAAwC,SAAxC;AAAA,MAEL;AAAA,IACJ;AAGA,UAAM,kBAAkB,MAAM;AAE1B,WAAK,mBAAmB,KAAK,qBAAqB,CAAC,SAAS;AAExD,aAAK,cAAc;AAAA,MAEvB,CAAC;AAED,WAAK,mBAAmB,KAAK,eAAe;AAC5C,WAAK,mBAAmB,2BAA2B;AACnD,2BAAO,oBAAoB;AAE3B,WAAK,mBAAmB,2BAA2B;
|
|
4
|
+
"sourcesContent": ["import \"./UICoreExtensions\"\nimport { UILanguageService } from \"./UIInterfaces\"\nimport { nil, NO, UIObject } from \"./UIObject\"\nimport { UIRoute } from \"./UIRoute\"\nimport { UIView } from \"./UIView\"\nimport { UIViewController } from \"./UIViewController\"\n\n\nexport class UICore extends UIObject {\n \n rootViewController: UIViewController\n \n \n \n static RootViewControllerClass: typeof UIViewController\n static main: UICore\n \n static languageService: UILanguageService = nil\n \n static readonly broadcastEventName = {\n \n \"RouteDidChange\": \"RouteDidChange\",\n \"WindowDidResize\": \"WindowDidResize\"\n \n }\n \n constructor(rootDivElementID: string, rootViewControllerClass: typeof UIViewController, public paddingLength = 20) {\n \n super()\n \n UICore.RootViewControllerClass = rootViewControllerClass\n UICore.main = UICore.main || this\n \n const rootViewElement = document.getElementById(rootDivElementID)\n const rootView = new UIView(rootDivElementID, rootViewElement)\n rootView.pausesPointerEvents = NO //YES;\n rootView.core = this\n \n if (UICore.RootViewControllerClass) {\n \n if (!(UICore.RootViewControllerClass.prototype instanceof UIViewController) ||\n (UICore.RootViewControllerClass as any) === UIViewController) {\n \n console.log(\n \"Error, UICore.RootViewControllerClass must be UIViewController or a subclass of UIViewController, \" +\n \"falling back to UIViewController.\"\n )\n \n UICore.RootViewControllerClass = UIViewController\n \n }\n \n this.rootViewController = new UICore.RootViewControllerClass(rootView)\n \n }\n else {\n \n this.rootViewController = new UIViewController(rootView)\n \n }\n \n this.rootViewController.viewWillAppear().then(() =>\n this.rootViewController.viewDidAppear()\n )\n \n \n this.rootViewController.view.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n () => {\n \n (document.activeElement as HTMLElement)?.blur?.()\n \n }\n )\n \n \n const windowDidResize = () => {\n \n this.rootViewController.view.forEachViewInSubtree((view) => {\n \n view._frameCache = undefined\n \n })\n // Doing layout two times to prevent page scrollbars from confusing the layout\n this.rootViewController.view.setNeedsLayout()\n this.rootViewController._triggerLayoutViewSubviews()\n UIView.layoutViewsIfNeeded()\n \n this.rootViewController._triggerLayoutViewSubviews()\n UIView.layoutViewsIfNeeded()\n \n this.rootViewController.view.broadcastEventInSubtree({\n \n name: UICore.broadcastEventName.WindowDidResize,\n parameters: nil\n \n })\n \n }\n \n window.addEventListener(\"resize\", windowDidResize)\n \n const didScroll = () => {\n \n //code\n \n this.rootViewController.view.broadcastEventInSubtree({\n \n name: UIView.broadcastEventName.PageDidScroll,\n parameters: nil\n \n })\n \n \n }\n \n window.addEventListener(\"scroll\", didScroll, false)\n \n const hashDidChange = () => {\n \n //code\n \n this.rootViewController.handleRouteRecursively(UIRoute.currentRoute)\n \n this.rootViewController.view.broadcastEventInSubtree({\n \n name: UICore.broadcastEventName.RouteDidChange,\n parameters: nil\n \n })\n \n \n }\n \n window.addEventListener(\"hashchange\", hashDidChange, false)\n \n hashDidChange()\n \n \n }\n \n \n}\n\n\nArray.prototype.indexOf || (Array.prototype.indexOf = function (d, e) {\n let a\n if (null == this) {\n throw new TypeError(\"\\\"this\\\" is null or not defined\")\n }\n const c = Object(this),\n b = c.length >>> 0\n if (0 === b) {\n return -1\n }\n // @ts-ignore\n a = +e || 0\n Infinity === Math.abs(a) && (a = 0)\n if (a >= b) {\n return -1\n }\n for (a = Math.max(0 <= a ? a : b - Math.abs(a), 0); a < b;) {\n if (a in c && c[a] === d) {\n return a\n }\n a++\n }\n return -1\n})\n\n\n\n\n\n\n\n\n\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UIRectangle.ts"],
|
|
4
|
-
"sourcesContent": ["import { FIRST_OR_NIL, IS, IS_DEFINED, IS_NIL, IS_NOT_LIKE_NULL, IS_NOT_NIL, nil, NO, UIObject, YES } from \"./UIObject\"\nimport { UIPoint } from \"./UIPoint\"\nimport { UIView } from \"./UIView\"\n\n\nexport type SizeNumberOrFunctionOrView = number | ((constrainingOrthogonalSize: number) => number) | UIView\n\nexport class UIRectangle extends UIObject {\n \n _isBeingUpdated: boolean\n rectanglePointDidChange?: (b: any) => void\n \n // COW: Internal data structure that can be shared\n private _data: {\n min: UIPoint\n max: UIPoint\n minHeight?: number\n maxHeight?: number\n minWidth?: number\n maxWidth?: number\n refCount: number\n }\n \n // COW: Flag to indicate this is a lazy copy\n private _isLazyCopy: boolean\n \n \n constructor(x: number = 0, y: number = 0, height: number = 0, width: number = 0) {\n \n super()\n \n this._isLazyCopy = NO\n this._isBeingUpdated = NO\n \n // COW: Create the shared data structure\n this._data = {\n min: new UIPoint(x, y),\n max: new UIPoint(x + width, y + height),\n refCount: 1\n }\n \n this._setupPointCallbacks()\n \n if (IS_NIL(height)) {\n this._data.max.y = height\n }\n \n if (IS_NIL(width)) {\n this._data.max.x = width\n }\n \n }\n \n // COW: Setup callbacks for point changes\n private _setupPointCallbacks() {\n this._data.min.didChange = (point) => {\n this.rectanglePointDidChange?.(point)\n this._rectanglePointDidChange()\n }\n this._data.max.didChange = (point) => {\n this.rectanglePointDidChange?.(point)\n this._rectanglePointDidChange()\n }\n }\n \n // COW: Materialize a lazy copy before mutation\n materialize() {\n if (this._isLazyCopy || this._data.refCount > 1) {\n this._data.refCount--\n \n const oldData = this._data\n this._data = {\n min: oldData.min.copy(),\n max: oldData.max.copy(),\n minHeight: oldData.minHeight,\n maxHeight: oldData.maxHeight,\n minWidth: oldData.minWidth,\n maxWidth: oldData.maxWidth,\n refCount: 1\n }\n \n this._setupPointCallbacks()\n this._isLazyCopy = NO\n }\n }\n \n // Copy on write: Lazy copy that shares data\n // Tested to reduce CPU time from 1.5% to 1% during heavy resizing\n lazyCopy(): UIRectangle {\n const result = Object.create(UIRectangle.prototype)\n result._data = this._data\n result._data.refCount++\n result._isLazyCopy = YES\n result._isBeingUpdated = NO\n result.rectanglePointDidChange = this.rectanglePointDidChange\n return result\n }\n \n // COW: Getters and setters that materialize on write\n get min(): UIPoint {\n return this._data.min\n }\n \n set min(value: UIPoint) {\n this.materialize()\n this._data.min = value\n this._setupPointCallbacks()\n }\n \n get max(): UIPoint {\n return this._data.max\n }\n \n set max(value: UIPoint) {\n this.materialize()\n this._data.max = value\n this._setupPointCallbacks()\n }\n \n get minHeight(): number | undefined {\n return this._data.minHeight\n }\n \n set minHeight(value: number | undefined) {\n this.materialize()\n this._data.minHeight = value\n }\n \n get maxHeight(): number | undefined {\n return this._data.maxHeight\n }\n \n set maxHeight(value: number | undefined) {\n this.materialize()\n this._data.maxHeight = value\n }\n \n get minWidth(): number | undefined {\n return this._data.minWidth\n }\n \n set minWidth(value: number | undefined) {\n this.materialize()\n this._data.minWidth = value\n }\n \n get maxWidth(): number | undefined {\n return this._data.maxWidth\n }\n \n set maxWidth(value: number | undefined) {\n this.materialize()\n this._data.maxWidth = value\n }\n \n \n copy() {\n \n const result = new UIRectangle(this.x, this.y, this.height, this.width)\n \n result.minHeight = this.minHeight\n result.minWidth = this.minWidth\n result.maxHeight = this.maxHeight\n result.maxWidth = this.maxWidth\n \n return result\n \n }\n \n isEqualTo(rectangle: UIRectangle | null | undefined) {\n return (IS(rectangle) && this.min.isEqualTo(rectangle.min) && this.max.isEqualTo(rectangle.max))\n }\n \n static zero() {\n return new UIRectangle(0, 0, 0, 0)\n }\n \n containsPoint(point: UIPoint) {\n return this.min.x <= point.x && this.min.y <= point.y &&\n point.x <= this.max.x && point.y <= this.max.y\n }\n \n updateByAddingPoint(point: UIPoint) {\n \n this.materialize() // COW: Materialize before mutation\n \n if (!point) {\n point = new UIPoint(0, 0)\n }\n \n this.beginUpdates()\n \n const min = this.min.copy()\n if (min.x === nil) {\n min.x = this.max.x\n }\n if (min.y === nil) {\n min.y = this.max.y\n }\n \n const max = this.max.copy()\n if (max.x === nil) {\n max.x = this.min.x\n }\n if (max.y === nil) {\n max.y = this.min.y\n }\n \n this.min.x = Math.min(min.x, point.x)\n this.min.y = Math.min(min.y, point.y)\n this.max.x = Math.max(max.x, point.x)\n this.max.y = Math.max(max.y, point.y)\n \n this.finishUpdates()\n \n }\n \n scale(scale: number) {\n this.materialize() // COW: Materialize before mutation\n if (IS_NOT_NIL(this.max.y)) {\n this.height = this.height * scale\n }\n if (IS_NOT_NIL(this.max.x)) {\n this.width = this.width * scale\n }\n }\n \n get height() {\n if (this.max.y === nil) {\n return nil\n }\n return this.max.y - this.min.y\n }\n \n set height(height: number) {\n this.materialize() // COW: Materialize before mutation\n this._data.max.y = this.min.y + height\n }\n \n \n get width() {\n if (this.max.x === nil) {\n return nil\n }\n return this.max.x - this.min.x\n }\n \n set width(width: number) {\n this.materialize() // COW: Materialize before mutation\n this._data.max.x = this.min.x + width\n }\n \n \n get x() {\n return this.min.x\n }\n \n set x(x: number) {\n \n this.materialize() // COW: Materialize before mutation\n this.beginUpdates()\n \n const width = this.width\n this._data.min.x = x\n this._data.max.x = this.min.x + width\n \n this.finishUpdates()\n \n }\n \n \n get y() {\n return this.min.y\n }\n \n \n set y(y: number) {\n \n this.materialize() // COW: Materialize before mutation\n this.beginUpdates()\n \n const height = this.height\n this._data.min.y = y\n this._data.max.y = this.min.y + height\n \n this.finishUpdates()\n \n }\n \n \n get topLeft() {\n return this.min.copy()\n }\n \n get topRight() {\n return new UIPoint(this.max.x, this.y)\n }\n \n get bottomLeft() {\n return new UIPoint(this.x, this.max.y)\n }\n \n get bottomRight() {\n return this.max.copy()\n }\n \n \n get center() {\n return this.min.copy().add(this.min.to(this.max).scale(0.5))\n }\n \n set center(center: UIPoint) {\n this.materialize() // COW: Materialize before mutation\n const offset = this.center.to(center)\n this.offsetByPoint(offset)\n }\n \n offsetByPoint(offset: UIPoint) {\n this.materialize() // COW: Materialize before mutation\n this.min.add(offset)\n this.max.add(offset)\n \n return this\n }\n \n \n concatenateWithRectangle(rectangle: UIRectangle) {\n this.updateByAddingPoint(rectangle.bottomRight)\n this.updateByAddingPoint(rectangle.topLeft)\n return this\n }\n \n rectangleByConcatenatingWithRectangle(rectangle: UIRectangle) {\n return this.lazyCopy().concatenateWithRectangle(rectangle) // COW: Use lazyCopy\n }\n \n \n intersectionRectangleWithRectangle(rectangle: UIRectangle): UIRectangle {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.materialize() // COW: We're going to modify it\n \n result.beginUpdates()\n \n const min = result.min\n if (min.x === nil) {\n min.x = rectangle.max.x - Math.min(result.width, rectangle.width)\n }\n if (min.y === nil) {\n min.y = rectangle.max.y - Math.min(result.height, rectangle.height)\n }\n \n const max = result.max\n if (max.x === nil) {\n max.x = rectangle.min.x + Math.min(result.width, rectangle.width)\n }\n if (max.y === nil) {\n max.y = rectangle.min.y + Math.min(result.height, rectangle.height)\n }\n \n result.min.x = Math.max(result.min.x, rectangle.min.x)\n result.min.y = Math.max(result.min.y, rectangle.min.y)\n result.max.x = Math.min(result.max.x, rectangle.max.x)\n result.max.y = Math.min(result.max.y, rectangle.max.y)\n \n \n if (result.height < 0) {\n \n const averageY = (this.center.y + rectangle.center.y) * 0.5\n result.min.y = averageY\n result.max.y = averageY\n \n }\n \n if (result.width < 0) {\n \n const averageX = (this.center.x + rectangle.center.x) * 0.5\n result.min.x = averageX\n result.max.x = averageX\n \n }\n \n result.finishUpdates()\n \n return result\n \n }\n \n \n get area() {\n return this.height * this.width\n }\n \n \n intersectsWithRectangle(rectangle: UIRectangle) {\n return (this.intersectionRectangleWithRectangle(rectangle).area != 0)\n }\n \n \n // add some space around the rectangle\n rectangleWithInsets(left: number, right: number, bottom: number, top: number) {\n const result = this.lazyCopy() // COW: Use lazyCopy\n result.materialize() // COW: We're modifying multiple properties\n result.min.x = this.min.x + left\n result.max.x = this.max.x - right\n result.min.y = this.min.y + top\n result.max.y = this.max.y - bottom\n return result\n }\n \n rectangleWithInset(inset: number) {\n return this.rectangleWithInsets(inset, inset, inset, inset)\n }\n \n rectangleWithHeight(height: SizeNumberOrFunctionOrView, centeredOnPosition: number = nil) {\n \n height = this._heightNumberFromSizeNumberOrFunctionOrView(height)\n \n if (isNaN(centeredOnPosition)) {\n centeredOnPosition = nil\n }\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.height = height\n \n if (centeredOnPosition != nil) {\n const change = height - this.height\n result.offsetByPoint(new UIPoint(0, change * centeredOnPosition).scale(-1))\n }\n \n return result\n \n }\n \n rectangleWithWidth(width: SizeNumberOrFunctionOrView, centeredOnPosition: number = nil) {\n \n width = this._widthNumberFromSizeNumberOrFunctionOrView(width)\n \n if (isNaN(centeredOnPosition)) {\n centeredOnPosition = nil\n }\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.width = width\n \n if (centeredOnPosition != nil) {\n const change = width - this.width\n result.offsetByPoint(new UIPoint(change * centeredOnPosition, 0).scale(-1))\n }\n \n return result\n \n }\n \n rectangleWithHeightRelativeToWidth(heightRatio: number = 1, centeredOnPosition: number = nil) {\n return this.rectangleWithHeight(this.width * heightRatio, centeredOnPosition)\n }\n \n rectangleWithWidthRelativeToHeight(widthRatio: number = 1, centeredOnPosition: number = nil) {\n return this.rectangleWithWidth(this.height * widthRatio, centeredOnPosition)\n }\n \n rectangleWithX(x: number, centeredOnPosition: number = 0) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.x = x - result.width * centeredOnPosition\n \n return result\n \n }\n \n rectangleWithY(y: number, centeredOnPosition: number = 0) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.y = y - result.height * centeredOnPosition\n \n return result\n \n }\n \n \n rectangleByAddingX(x: number) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.x = this.x + x\n \n return result\n \n }\n \n rectangleByAddingY(y: number) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.y = this.y + y\n \n return result\n \n }\n \n rectangleByAddingWidth(widthToAdd: number, centeredOnPosition = 0) {\n \n const result = this.rectangleWithWidth(this.width + widthToAdd, centeredOnPosition)\n \n return result\n \n }\n \n rectangleByAddingHeight(heightToAdd: number, centeredOnPosition = 0) {\n \n const result = this.rectangleWithHeight(this.height + heightToAdd, centeredOnPosition)\n \n return result\n \n }\n \n \n rectangleWithRelativeValues(\n relativeXPosition: number,\n widthMultiplier: number,\n relativeYPosition: number,\n heightMultiplier: number\n ) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.materialize() // COW: We're modifying multiple properties\n \n const width = result.width\n const height = result.height\n \n result.width = widthMultiplier * width\n result.height = heightMultiplier * height\n \n result.center = new UIPoint(\n relativeXPosition * width,\n relativeYPosition * height\n )\n \n return result\n \n }\n \n \n /**\n * Returns a rectangle with a maximum width constraint\n * If current width exceeds max, centers the constrained width\n */\n rectangleWithMaxWidth(maxWidth: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.width <= maxWidth) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithWidth(maxWidth, centeredOnPosition)\n }\n \n /**\n * Returns a rectangle with a maximum height constraint\n */\n rectangleWithMaxHeight(maxHeight: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.height <= maxHeight) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithHeight(maxHeight, centeredOnPosition)\n }\n \n /**\n * Returns a rectangle with minimum width constraint\n */\n rectangleWithMinWidth(minWidth: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.width >= minWidth) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithWidth(minWidth, centeredOnPosition)\n }\n \n /**\n * Returns a rectangle with minimum height constraint\n */\n rectangleWithMinHeight(minHeight: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.height >= minHeight) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithHeight(minHeight, centeredOnPosition)\n }\n \n // Returns a new rectangle that is positioned relative to the reference rectangle\n // By default, it makes a copy of this rectangle taht is centered in the target rectangle\n rectangleByCenteringInRectangle(referenceRectangle: UIRectangle, xPosition = 0.5, yPosition = 0.5) {\n const result = this.lazyCopy() // COW: Use lazyCopy\n result.center = referenceRectangle.topLeft\n .pointByAddingX(xPosition * referenceRectangle.width)\n .pointByAddingY(yPosition * referenceRectangle.height)\n return result\n }\n \n \n rectanglesBySplittingWidth(\n weights: SizeNumberOrFunctionOrView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteWidths: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n \n if (IS_NIL(paddings)) {\n paddings = 1\n }\n if (!((paddings as any) instanceof Array)) {\n paddings = [paddings].arrayByRepeating(weights.length - 1)\n }\n paddings = (paddings as any[]).arrayByTrimmingToLengthIfLonger(weights.length - 1)\n paddings = paddings.map(padding => this._widthNumberFromSizeNumberOrFunctionOrView(padding))\n if (!(absoluteWidths instanceof Array) && IS_NOT_NIL(absoluteWidths)) {\n absoluteWidths = [absoluteWidths].arrayByRepeating(weights.length)\n }\n absoluteWidths = absoluteWidths.map(\n width => this._widthNumberFromSizeNumberOrFunctionOrView(width)\n )\n \n weights = weights.map(weight => this._widthNumberFromSizeNumberOrFunctionOrView(weight))\n const result: UIRectangle[] = []\n const sumOfWeights = (weights as number[]).reduce(\n (a, b, index) => {\n if (IS_NOT_NIL((absoluteWidths as number[])[index])) {\n b = 0\n }\n return a + b\n },\n 0\n )\n const sumOfPaddings = paddings.summedValue as number\n const sumOfAbsoluteWidths = (absoluteWidths as number[]).summedValue\n const totalRelativeWidth = this.width - sumOfPaddings - sumOfAbsoluteWidths\n let previousCellMaxX = this.x\n \n for (let i = 0; i < weights.length; i++) {\n \n let resultWidth: number\n if (IS_NOT_NIL(absoluteWidths[i])) {\n resultWidth = (absoluteWidths[i] || 0) as number\n }\n else {\n resultWidth = totalRelativeWidth * (weights[i] as number / sumOfWeights)\n }\n \n const rectangle = this.rectangleWithWidth(resultWidth)\n \n let padding = 0\n if (paddings.length > i && paddings[i]) {\n padding = paddings[i] as number\n }\n \n rectangle.x = previousCellMaxX\n previousCellMaxX = rectangle.max.x + padding\n result.push(rectangle)\n \n }\n \n return result\n \n }\n \n rectanglesBySplittingHeight(\n weights: SizeNumberOrFunctionOrView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteHeights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n \n if (IS_NIL(paddings)) {\n paddings = 1\n }\n if (!((paddings as any) instanceof Array)) {\n paddings = [paddings].arrayByRepeating(weights.length - 1)\n }\n paddings = (paddings as number[]).arrayByTrimmingToLengthIfLonger(weights.length - 1)\n paddings = paddings.map(padding => this._heightNumberFromSizeNumberOrFunctionOrView(padding))\n if (!(absoluteHeights instanceof Array) && IS_NOT_NIL(absoluteHeights)) {\n absoluteHeights = [absoluteHeights].arrayByRepeating(weights.length)\n }\n absoluteHeights = absoluteHeights.map(\n height => this._heightNumberFromSizeNumberOrFunctionOrView(height)\n )\n \n weights = weights.map(weight => this._heightNumberFromSizeNumberOrFunctionOrView(weight))\n const result: UIRectangle[] = []\n const sumOfWeights = (weights as number[]).reduce(\n (a, b, index) => {\n if (IS_NOT_NIL((absoluteHeights as number[])[index])) {\n b = 0\n }\n return a + b\n },\n 0\n )\n const sumOfPaddings = paddings.summedValue as number\n const sumOfAbsoluteHeights = (absoluteHeights as number[]).summedValue\n const totalRelativeHeight = this.height - sumOfPaddings - sumOfAbsoluteHeights\n let previousCellMaxY = this.y\n \n for (let i = 0; i < weights.length; i++) {\n let resultHeight: number\n if (IS_NOT_NIL(absoluteHeights[i])) {\n \n resultHeight = (absoluteHeights[i] || 0) as number\n \n }\n else {\n \n resultHeight = totalRelativeHeight * (weights[i] as number / sumOfWeights)\n \n }\n \n const rectangle = this.rectangleWithHeight(resultHeight)\n \n let padding = 0\n if (paddings.length > i && paddings[i]) {\n padding = paddings[i] as number\n }\n \n rectangle.y = previousCellMaxY\n previousCellMaxY = rectangle.max.y + padding\n //rectangle = rectangle.rectangleWithInsets(0, 0, padding, 0);\n result.push(rectangle)\n }\n \n return result\n \n }\n \n \n rectanglesByEquallySplittingWidth(numberOfFrames: number, padding: number = 0) {\n const result: UIRectangle[] = []\n const totalPadding = padding * (numberOfFrames - 1)\n const resultWidth = (this.width - totalPadding) / numberOfFrames\n for (var i = 0; i < numberOfFrames; i++) {\n const rectangle = this.rectangleWithWidth(resultWidth, i / (numberOfFrames - 1))\n result.push(rectangle)\n }\n return result\n }\n \n rectanglesByEquallySplittingHeight(numberOfFrames: number, padding: number = 0) {\n const result: UIRectangle[] = []\n const totalPadding = padding * (numberOfFrames - 1)\n const resultHeight = (this.height - totalPadding) / numberOfFrames\n for (var i = 0; i < numberOfFrames; i++) {\n const rectangle = this.rectangleWithHeight(resultHeight, i / (numberOfFrames - 1))\n result.push(rectangle)\n }\n return result\n }\n \n \n distributeViewsAlongWidth(\n views: UIView[],\n weights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 1,\n paddings?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[],\n absoluteWidths?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[]\n ) {\n if (!(weights instanceof Array)) {\n weights = [weights].arrayByRepeating(views.length)\n }\n const frames = this.rectanglesBySplittingWidth(weights, paddings, absoluteWidths)\n frames.forEach((frame, index) => FIRST_OR_NIL(views[index]).frame = frame)\n return this\n }\n \n distributeViewsAlongHeight(\n views: UIView[],\n weights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 1,\n paddings?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[],\n absoluteHeights?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[]\n ) {\n if (!(weights instanceof Array)) {\n weights = [weights].arrayByRepeating(views.length)\n }\n const frames = this.rectanglesBySplittingHeight(weights, paddings, absoluteHeights)\n frames.forEach((frame, index) => FIRST_OR_NIL(views[index]).frame = frame)\n return this\n }\n \n \n distributeViewsEquallyAlongWidth(views: UIView[], padding: number) {\n const frames = this.rectanglesByEquallySplittingWidth(views.length, padding)\n frames.forEach((frame, index) => views[index].frame = frame)\n return this\n }\n \n distributeViewsEquallyAlongHeight(views: UIView[], padding: number) {\n const frames = this.rectanglesByEquallySplittingHeight(views.length, padding)\n frames.forEach((frame, index) => views[index].frame = frame)\n return this\n }\n \n \n _heightNumberFromSizeNumberOrFunctionOrView(height: SizeNumberOrFunctionOrView) {\n if (height instanceof Function) {\n return height(this.width)\n }\n if (height instanceof UIView) {\n return height.intrinsicContentHeight(this.width)\n }\n return height\n }\n \n _widthNumberFromSizeNumberOrFunctionOrView(width: SizeNumberOrFunctionOrView) {\n if (width instanceof Function) {\n return width(this.height)\n }\n if (width instanceof UIView) {\n return width.intrinsicContentWidth(this.height)\n }\n return width\n }\n \n rectangleForNextRow(padding: number = 0, height: SizeNumberOrFunctionOrView = this.height) {\n const heightNumber = this._heightNumberFromSizeNumberOrFunctionOrView(height)\n const result = this.rectangleWithY(this.max.y + padding)\n if (heightNumber != this.height) {\n result.height = heightNumber\n }\n return result\n }\n \n rectangleForNextColumn(padding: number = 0, width: SizeNumberOrFunctionOrView = this.width) {\n const widthNumber = this._widthNumberFromSizeNumberOrFunctionOrView(width)\n const result = this.rectangleWithX(this.max.x + padding)\n if (widthNumber != this.width) {\n result.width = widthNumber\n }\n return result\n }\n \n rectangleForPreviousRow(padding: number = 0, height: SizeNumberOrFunctionOrView = this.height) {\n const heightNumber = this._heightNumberFromSizeNumberOrFunctionOrView(height)\n const result = this.rectangleWithY(this.min.y - heightNumber - padding)\n if (heightNumber != this.height) {\n result.height = heightNumber\n }\n return result\n }\n \n rectangleForPreviousColumn(padding: number = 0, width: SizeNumberOrFunctionOrView = this.width) {\n const widthNumber = this._widthNumberFromSizeNumberOrFunctionOrView(width)\n const result = this.rectangleWithX(this.min.x - widthNumber - padding)\n if (widthNumber != this.width) {\n result.width = widthNumber\n }\n return result\n \n }\n \n /**\n * Distributes views vertically as a column, assigning frames and returning them.\n * Each view is positioned below the previous one with optional padding between them.\n * @param views - Array of views to distribute\n * @param paddings - Padding between views (single value or array of values)\n * @param absoluteHeights - Optional fixed heights for views (overrides intrinsic height)\n * @returns Array of rectangles representing the frame for each view\n */\n framesByDistributingViewsAsColumn(\n views: UIView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteHeights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n const frames: UIRectangle[] = []\n let currentRectangle = this.lazyCopy() // COW: Use lazyCopy\n \n if (!(paddings instanceof Array)) {\n paddings = [paddings].arrayByRepeating(views.length - 1)\n }\n paddings = paddings.map(padding => this._heightNumberFromSizeNumberOrFunctionOrView(padding))\n \n if (!(absoluteHeights instanceof Array) && IS_NOT_NIL(absoluteHeights)) {\n absoluteHeights = [absoluteHeights].arrayByRepeating(views.length)\n }\n absoluteHeights = absoluteHeights.map(\n height => this._heightNumberFromSizeNumberOrFunctionOrView(height)\n )\n \n for (let i = 0; i < views.length; i++) {\n const frame = currentRectangle.rectangleWithHeight(views[i])\n \n if (IS_NOT_NIL(absoluteHeights[i])) {\n frame.height = absoluteHeights[i] as number\n }\n \n views[i].frame = frame\n frames.push(frame)\n \n const padding = (paddings[i] || 0) as number\n currentRectangle = frame.rectangleForNextRow(padding)\n }\n \n return frames\n }\n \n /**\n * Distributes views horizontally as a row, assigning frames and returning them.\n * Each view is positioned to the right of the previous one with optional padding between them.\n * @param views - Array of views to distribute\n * @param paddings - Padding between views (single value or array of values)\n * @param absoluteWidths - Optional fixed widths for views (overrides intrinsic width)\n * @returns Array of rectangles representing the frame for each view\n */\n framesByDistributingViewsAsRow(\n views: UIView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteWidths: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n const frames: UIRectangle[] = []\n let currentRectangle = this.lazyCopy() // COW: Use lazyCopy\n \n if (!(paddings instanceof Array)) {\n paddings = [paddings].arrayByRepeating(views.length - 1)\n }\n paddings = paddings.map(padding => this._widthNumberFromSizeNumberOrFunctionOrView(padding))\n \n if (!(absoluteWidths instanceof Array) && IS_NOT_NIL(absoluteWidths)) {\n absoluteWidths = [absoluteWidths].arrayByRepeating(views.length)\n }\n absoluteWidths = absoluteWidths.map(\n width => this._widthNumberFromSizeNumberOrFunctionOrView(width)\n )\n \n for (let i = 0; i < views.length; i++) {\n const frame = currentRectangle.rectangleWithWidth(views[i])\n \n if (IS_NOT_NIL(absoluteWidths[i])) {\n frame.width = absoluteWidths[i] as number\n }\n \n views[i].frame = frame\n frames.push(frame)\n \n const padding = (paddings[i] || 0) as number\n currentRectangle = frame.rectangleForNextColumn(padding)\n }\n \n return frames\n }\n \n /**\n * Distributes views as a grid (2D array), assigning frames and returning them.\n * The first index represents rows (vertical), the second index represents columns (horizontal).\n * Example: views[0] is the first row, views[0][0] is the first column in the first row.\n * Each row is laid out horizontally, and rows are stacked vertically.\n * @param views - 2D array where views[row][column] represents the grid structure\n * @param paddings - Vertical padding between rows (single value or array of values)\n * @param absoluteHeights - Optional fixed heights for each row (overrides intrinsic height)\n * @returns 2D array of rectangles where frames[row][column] matches views[row][column]\n */\n framesByDistributingViewsAsGrid(\n views: UIView[][],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteHeights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n const frames: UIRectangle[][] = []\n let currentRowRectangle = this.lazyCopy() // COW: Use lazyCopy\n \n if (!(paddings instanceof Array)) {\n paddings = [paddings].arrayByRepeating(views.length - 1)\n }\n paddings = paddings.map(padding => this._heightNumberFromSizeNumberOrFunctionOrView(padding))\n \n if (!(absoluteHeights instanceof Array) && IS_NOT_NIL(absoluteHeights)) {\n absoluteHeights = [absoluteHeights].arrayByRepeating(views.length)\n }\n absoluteHeights = absoluteHeights.map(\n height => this._heightNumberFromSizeNumberOrFunctionOrView(height)\n )\n \n for (let i = 0; i < views.length; i++) {\n const rowViews = views[i]\n const rowFrames = currentRowRectangle.framesByDistributingViewsAsRow(rowViews)\n \n if (IS_NOT_NIL(absoluteHeights[i])) {\n const heightNumber = absoluteHeights[i] as number\n rowFrames.forEach((frame, j) => {\n frame.height = heightNumber\n rowViews[j].frame = frame\n })\n }\n \n frames.push(rowFrames)\n \n const padding = (paddings[i] || 0) as number\n const maxHeight = Math.max(...rowFrames.map(f => f.height))\n currentRowRectangle = currentRowRectangle.rectangleForNextRow(padding, maxHeight)\n }\n \n return frames\n }\n \n rectangleWithIntrinsicContentSizeForView(view: UIView, centeredOnXPosition = 0, centeredOnYPosition = 0) {\n const intrinsicContentSize = view.intrinsicContentSize()\n return this.rectangleWithHeight(intrinsicContentSize.height, centeredOnYPosition)\n .rectangleWithWidth(intrinsicContentSize.width, centeredOnXPosition)\n }\n \n settingMinHeight(minHeight?: number) {\n this.minHeight = minHeight\n return this\n }\n \n settingMinWidth(minWidth?: number) {\n this.minWidth = minWidth\n return this\n }\n \n settingMaxHeight(maxHeight?: number) {\n this.maxHeight = maxHeight\n return this\n }\n \n settingMaxWidth(maxWidth?: number) {\n this.maxWidth = maxWidth\n return this\n }\n \n rectangleByEnforcingMinAndMaxSizes(centeredOnXPosition = 0, centeredOnYPosition = 0) {\n return this.rectangleWithHeight(\n [\n [this.height, this.maxHeight].filter(value => IS_NOT_LIKE_NULL(value)).min(),\n this.minHeight\n ].filter(value => IS_NOT_LIKE_NULL(value)).max(),\n centeredOnYPosition\n ).rectangleWithWidth(\n [\n [this.width, this.maxWidth].filter(value => IS_NOT_LIKE_NULL(value)).min(),\n this.minWidth\n ].filter(value => IS_NOT_LIKE_NULL(value)).max(),\n centeredOnXPosition\n )\n }\n \n \n assignedAsFrameOfView(view: UIView, isWeakFrame = view.hasWeakFrame) {\n view.frame = this\n view.hasWeakFrame = isWeakFrame\n return this\n }\n \n \n override toString() {\n \n const result = \"[\" + this.class.name + \"] { x: \" + this.x + \", y: \" + this.y + \", \" +\n \"height: \" + this.height.toFixed(2) + \", width: \" + this.height.toFixed(2) + \" }\"\n \n return result\n \n }\n \n get [Symbol.toStringTag]() {\n return this.toString()\n }\n \n \n IF(condition: boolean): UIRectangleConditionalChain<UIRectangle> {\n const conditionalBlock = new UIRectangleConditionalBlock(this, condition)\n // @ts-ignore\n return conditionalBlock.getProxy()\n }\n \n // These will be intercepted by the proxy, but we define them for TypeScript\n ELSE_IF(condition: boolean): UIRectangle {\n return this\n }\n \n ELSE(): UIRectangle {\n return this\n }\n \n ENDIF(): this\n ENDIF<T, R>(performFunction: (result: T) => R): R\n ENDIF<T, R>(performFunction?: (result: T) => R): R | this {\n if (performFunction) {\n return performFunction(this as any)\n }\n return this\n }\n \n \n // Bounding box\n static boundingBoxForPoints(points: UIPoint[]) {\n const result = new UIRectangle()\n for (let i = 0; i < points.length; i++) {\n result.updateByAddingPoint(points[i])\n }\n return result\n }\n \n static boundingBoxForRectanglesAndPoints(rectanglesAndPoints: (UIPoint | UIRectangle)[]) {\n const result = new UIRectangle()\n for (let i = 0; i < rectanglesAndPoints.length; i++) {\n const rectangleOrPoint = rectanglesAndPoints[i]\n if (rectangleOrPoint instanceof UIRectangle) {\n result.updateByAddingPoint(rectangleOrPoint.min)\n result.updateByAddingPoint(rectangleOrPoint.max)\n }\n else {\n result.updateByAddingPoint(rectangleOrPoint)\n }\n }\n return result\n }\n \n \n beginUpdates() {\n this._isBeingUpdated = YES\n }\n \n finishUpdates() {\n this._isBeingUpdated = NO\n this.didChange()\n }\n \n \n didChange() {\n \n // Callback to be set by delegate\n \n }\n \n _rectanglePointDidChange() {\n if (!this._isBeingUpdated) {\n this.didChange()\n }\n }\n \n \n}\n\n\n// 1. Methods available when holding a UIRectangle\ntype RectangleChainMethods<TResult> = {\n [K in keyof UIRectangle as (\n K extends 'IF' | 'ELSE' | 'ELSE_IF' | 'ENDIF' ? never : K\n )]:\n UIRectangle[K] extends (...args: infer Args) => infer R\n ? R extends UIRectangle | UIRectangle[]\n // CHANGE: We do NOT add 'R' to 'TResult' here. We only update the current state (R).\n ? (...args: Args) => UIRectangleConditionalChain<R, TResult>\n : never\n : never\n};\n\n// 2. Methods available when holding a UIRectangle[]\ntype ArrayChainMethods<TResult> = {\n [K in keyof UIRectangle[]]:\n UIRectangle[][K] extends UIRectangle\n ? UIRectangleConditionalChain<UIRectangle, TResult> // No accumulation for properties\n : UIRectangle[][K] extends (...args: infer Args) => infer R\n ? R extends UIRectangle | UIRectangle[]\n // CHANGE: We do NOT add 'R' to 'TResult' here either.\n ? (...args: Args) => UIRectangleConditionalChain<R, TResult>\n : never\n : never\n};\n\n// 3. Methods available in both states (Control Flow + Transform)\ntype SharedChainMethods<TCurrent, TResult> = {\n // TRANSFORM acts as a standard method, it should not leak intermediate types into TResult\n TRANSFORM<R extends UIRectangle>(fn: (current: TCurrent) => R): UIRectangleConditionalChain<R, TResult>;\n \n // ELSE_IF marks the end of a branch. We MUST capture the current state (TCurrent) and add it to TResult.\n // The new chain starts with the original UIRectangle state for the next branch.\n ELSE_IF(condition: boolean): UIRectangleConditionalChain<UIRectangle, TResult | TCurrent>;\n \n // ELSE marks the end of a branch. Same logic as ELSE_IF.\n ELSE(): UIRectangleConditionalChain<UIRectangle, TResult | TCurrent>;\n \n // ENDIF marks the end of the block. Same logic: capture TCurrent into TResult.\n ENDIF(): TResult | TCurrent;\n ENDIF<R>(performFunction: (result: TResult | TCurrent) => R): R;\n};\n\n// 4. The Main Type (No changes needed here, just re-stating for context)\ntype UIRectangleConditionalChain<TCurrent, TResult = TCurrent> =\n (TCurrent extends UIRectangle ? RectangleChainMethods<TResult> : {}) &\n (TCurrent extends UIRectangle[] ? ArrayChainMethods<TResult> : {}) &\n SharedChainMethods<TCurrent, TResult>;\n\n\nclass UIRectangleConditionalBlock {\n // The value we are currently chaining on (can be UIRectangle or UIRectangle[])\n private currentResult: any\n // The value where the IF block started (needed to reset for ELSE branches)\n private originalResult: any\n private conditionMet: boolean\n \n constructor(initialResult: UIRectangle, condition: boolean) {\n this.originalResult = initialResult\n this.currentResult = initialResult\n this.conditionMet = condition\n }\n \n private createProxy(): UIRectangleConditionalChain<any, any> {\n const self = this\n \n // The target is irrelevant; we delegate everything to self.currentResult\n return new Proxy({}, {\n get(_, prop) {\n \n // 1. Control Flow Methods\n \n if (prop === 'TRANSFORM') {\n return <R extends UIRectangle>(fn: (current: any) => R) => {\n if (self.conditionMet) {\n const result = fn(self.currentResult)\n self.currentResult = result\n }\n return self.createProxy()\n }\n }\n \n if (prop === 'ELSE_IF') {\n return <U>(condition: boolean) => {\n // Only enter this branch if no previous branch has run\n if (!self.conditionMet) {\n self.conditionMet = condition\n // Reset the state to the original starting point for this new branch\n self.currentResult = self.originalResult\n }\n return self.createProxy()\n }\n }\n \n if (prop === 'ELSE') {\n return <U>() => {\n if (!self.conditionMet) {\n self.conditionMet = true\n // Reset the state to the original starting point\n self.currentResult = self.originalResult\n }\n return self.createProxy()\n }\n }\n \n if (prop === 'ENDIF') {\n function endif(): any\n function endif<R>(performFunction: (result: any) => R): R\n function endif<R>(performFunction?: (result: any) => R): R | any {\n return performFunction ? performFunction(self.currentResult) : self.currentResult\n }\n return endif\n }\n \n // 2. Forwarding to currentResult (Rectangle or Array)\n \n const value = self.currentResult[prop]\n \n // Case A: It's a function (method call)\n if (typeof value === 'function') {\n return (...args: any[]) => {\n if (self.conditionMet) {\n // Call the method on the CURRENT object, and update the state\n const result = value.apply(self.currentResult, args)\n self.currentResult = result\n }\n return self.createProxy()\n }\n }\n \n // Case B: It's a property (getter)\n // Accessing a property acts as a transition (e.g. accessing .lastElement)\n if (self.conditionMet) {\n self.currentResult = value\n }\n \n return self.createProxy()\n }\n }) as any\n }\n \n getProxy(): UIRectangleConditionalChain<any, any> {\n return this.createProxy()\n }\n \n}\n\n"],
|
|
4
|
+
"sourcesContent": ["import { FIRST_OR_NIL, IS, IS_DEFINED, IS_NIL, IS_NOT_LIKE_NULL, IS_NOT_NIL, nil, NO, UIObject, YES } from \"./UIObject\"\nimport { UIPoint } from \"./UIPoint\"\nimport { UIView } from \"./UIView\"\n\n\nexport type SizeNumberOrFunctionOrView = number | ((constrainingOrthogonalSize: number) => number) | UIView\n\nexport class UIRectangle extends UIObject {\n \n _isBeingUpdated: boolean\n rectanglePointDidChange?: (b: any) => void\n \n // COW: Internal data structure that can be shared\n private _data: {\n min: UIPoint\n max: UIPoint\n minHeight?: number\n maxHeight?: number\n minWidth?: number\n maxWidth?: number\n refCount: number\n }\n \n // COW: Flag to indicate this is a lazy copy\n private _isLazyCopy: boolean\n \n \n constructor(x: number = 0, y: number = 0, height: number = 0, width: number = 0) {\n \n super()\n \n this._isLazyCopy = NO\n this._isBeingUpdated = NO\n \n // COW: Create the shared data structure\n this._data = {\n min: new UIPoint(x, y),\n max: new UIPoint(x + width, y + height),\n refCount: 1\n }\n \n this._setupPointCallbacks()\n \n if (IS_NIL(height)) {\n this._data.max.y = height\n }\n \n if (IS_NIL(width)) {\n this._data.max.x = width\n }\n \n }\n \n // COW: Setup callbacks for point changes\n private _setupPointCallbacks() {\n this._data.min.didChange = (point) => {\n this.rectanglePointDidChange?.(point)\n this._rectanglePointDidChange()\n }\n this._data.max.didChange = (point) => {\n this.rectanglePointDidChange?.(point)\n this._rectanglePointDidChange()\n }\n }\n \n // COW: Materialize a lazy copy before mutation\n materialize() {\n if (this._isLazyCopy || this._data.refCount > 1) {\n this._data.refCount--\n \n const oldData = this._data\n this._data = {\n min: oldData.min.copy(),\n max: oldData.max.copy(),\n minHeight: oldData.minHeight,\n maxHeight: oldData.maxHeight,\n minWidth: oldData.minWidth,\n maxWidth: oldData.maxWidth,\n refCount: 1\n }\n \n this._setupPointCallbacks()\n this._isLazyCopy = NO\n }\n }\n \n // Copy on write: Lazy copy that shares data\n // Tested to reduce CPU time from 2.2% to 1% during heavy resizing\n lazyCopy(): UIRectangle {\n const result = Object.create(UIRectangle.prototype)\n result._data = this._data\n result._data.refCount++\n result._isLazyCopy = YES\n result._isBeingUpdated = NO\n result.rectanglePointDidChange = this.rectanglePointDidChange\n return result\n }\n \n // COW: Getters and setters that materialize on write\n get min(): UIPoint {\n return this._data.min\n }\n \n set min(value: UIPoint) {\n this.materialize()\n this._data.min = value\n this._setupPointCallbacks()\n }\n \n get max(): UIPoint {\n return this._data.max\n }\n \n set max(value: UIPoint) {\n this.materialize()\n this._data.max = value\n this._setupPointCallbacks()\n }\n \n get minHeight(): number | undefined {\n return this._data.minHeight\n }\n \n set minHeight(value: number | undefined) {\n this.materialize()\n this._data.minHeight = value\n }\n \n get maxHeight(): number | undefined {\n return this._data.maxHeight\n }\n \n set maxHeight(value: number | undefined) {\n this.materialize()\n this._data.maxHeight = value\n }\n \n get minWidth(): number | undefined {\n return this._data.minWidth\n }\n \n set minWidth(value: number | undefined) {\n this.materialize()\n this._data.minWidth = value\n }\n \n get maxWidth(): number | undefined {\n return this._data.maxWidth\n }\n \n set maxWidth(value: number | undefined) {\n this.materialize()\n this._data.maxWidth = value\n }\n \n \n copy() {\n \n const result = new UIRectangle(this.x, this.y, this.height, this.width)\n \n result.minHeight = this.minHeight\n result.minWidth = this.minWidth\n result.maxHeight = this.maxHeight\n result.maxWidth = this.maxWidth\n \n return result\n \n }\n \n isEqualTo(rectangle: UIRectangle | null | undefined) {\n return (IS(rectangle) && this.min.isEqualTo(rectangle.min) && this.max.isEqualTo(rectangle.max))\n }\n \n static zero() {\n return new UIRectangle(0, 0, 0, 0)\n }\n \n containsPoint(point: UIPoint) {\n return this.min.x <= point.x && this.min.y <= point.y &&\n point.x <= this.max.x && point.y <= this.max.y\n }\n \n updateByAddingPoint(point: UIPoint) {\n \n this.materialize() // COW: Materialize before mutation\n \n if (!point) {\n point = new UIPoint(0, 0)\n }\n \n this.beginUpdates()\n \n const min = this.min.copy()\n if (min.x === nil) {\n min.x = this.max.x\n }\n if (min.y === nil) {\n min.y = this.max.y\n }\n \n const max = this.max.copy()\n if (max.x === nil) {\n max.x = this.min.x\n }\n if (max.y === nil) {\n max.y = this.min.y\n }\n \n this.min.x = Math.min(min.x, point.x)\n this.min.y = Math.min(min.y, point.y)\n this.max.x = Math.max(max.x, point.x)\n this.max.y = Math.max(max.y, point.y)\n \n this.finishUpdates()\n \n }\n \n scale(scale: number) {\n this.materialize() // COW: Materialize before mutation\n if (IS_NOT_NIL(this.max.y)) {\n this.height = this.height * scale\n }\n if (IS_NOT_NIL(this.max.x)) {\n this.width = this.width * scale\n }\n }\n \n get height() {\n if (this.max.y === nil) {\n return nil\n }\n return this.max.y - this.min.y\n }\n \n set height(height: number) {\n this.materialize() // COW: Materialize before mutation\n this._data.max.y = this.min.y + height\n }\n \n \n get width() {\n if (this.max.x === nil) {\n return nil\n }\n return this.max.x - this.min.x\n }\n \n set width(width: number) {\n this.materialize() // COW: Materialize before mutation\n this._data.max.x = this.min.x + width\n }\n \n \n get x() {\n return this.min.x\n }\n \n set x(x: number) {\n \n this.materialize() // COW: Materialize before mutation\n this.beginUpdates()\n \n const width = this.width\n this._data.min.x = x\n this._data.max.x = this.min.x + width\n \n this.finishUpdates()\n \n }\n \n \n get y() {\n return this.min.y\n }\n \n \n set y(y: number) {\n \n this.materialize() // COW: Materialize before mutation\n this.beginUpdates()\n \n const height = this.height\n this._data.min.y = y\n this._data.max.y = this.min.y + height\n \n this.finishUpdates()\n \n }\n \n \n get topLeft() {\n return this.min.copy()\n }\n \n get topRight() {\n return new UIPoint(this.max.x, this.y)\n }\n \n get bottomLeft() {\n return new UIPoint(this.x, this.max.y)\n }\n \n get bottomRight() {\n return this.max.copy()\n }\n \n \n get center() {\n return this.min.copy().add(this.min.to(this.max).scale(0.5))\n }\n \n set center(center: UIPoint) {\n this.materialize() // COW: Materialize before mutation\n const offset = this.center.to(center)\n this.offsetByPoint(offset)\n }\n \n offsetByPoint(offset: UIPoint) {\n this.materialize() // COW: Materialize before mutation\n this.min.add(offset)\n this.max.add(offset)\n \n return this\n }\n \n \n concatenateWithRectangle(rectangle: UIRectangle) {\n this.updateByAddingPoint(rectangle.bottomRight)\n this.updateByAddingPoint(rectangle.topLeft)\n return this\n }\n \n rectangleByConcatenatingWithRectangle(rectangle: UIRectangle) {\n return this.lazyCopy().concatenateWithRectangle(rectangle) // COW: Use lazyCopy\n }\n \n \n intersectionRectangleWithRectangle(rectangle: UIRectangle): UIRectangle {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.materialize() // COW: We're going to modify it\n \n result.beginUpdates()\n \n const min = result.min\n if (min.x === nil) {\n min.x = rectangle.max.x - Math.min(result.width, rectangle.width)\n }\n if (min.y === nil) {\n min.y = rectangle.max.y - Math.min(result.height, rectangle.height)\n }\n \n const max = result.max\n if (max.x === nil) {\n max.x = rectangle.min.x + Math.min(result.width, rectangle.width)\n }\n if (max.y === nil) {\n max.y = rectangle.min.y + Math.min(result.height, rectangle.height)\n }\n \n result.min.x = Math.max(result.min.x, rectangle.min.x)\n result.min.y = Math.max(result.min.y, rectangle.min.y)\n result.max.x = Math.min(result.max.x, rectangle.max.x)\n result.max.y = Math.min(result.max.y, rectangle.max.y)\n \n \n if (result.height < 0) {\n \n const averageY = (this.center.y + rectangle.center.y) * 0.5\n result.min.y = averageY\n result.max.y = averageY\n \n }\n \n if (result.width < 0) {\n \n const averageX = (this.center.x + rectangle.center.x) * 0.5\n result.min.x = averageX\n result.max.x = averageX\n \n }\n \n result.finishUpdates()\n \n return result\n \n }\n \n \n get area() {\n return this.height * this.width\n }\n \n \n intersectsWithRectangle(rectangle: UIRectangle) {\n return (this.intersectionRectangleWithRectangle(rectangle).area != 0)\n }\n \n \n // add some space around the rectangle\n rectangleWithInsets(left: number, right: number, bottom: number, top: number) {\n const result = this.lazyCopy() // COW: Use lazyCopy\n result.materialize() // COW: We're modifying multiple properties\n result.min.x = this.min.x + left\n result.max.x = this.max.x - right\n result.min.y = this.min.y + top\n result.max.y = this.max.y - bottom\n return result\n }\n \n rectangleWithInset(inset: number) {\n return this.rectangleWithInsets(inset, inset, inset, inset)\n }\n \n rectangleWithHeight(height: SizeNumberOrFunctionOrView, centeredOnPosition: number = nil) {\n \n height = this._heightNumberFromSizeNumberOrFunctionOrView(height)\n \n if (isNaN(centeredOnPosition)) {\n centeredOnPosition = nil\n }\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.height = height\n \n if (centeredOnPosition != nil) {\n const change = height - this.height\n result.offsetByPoint(new UIPoint(0, change * centeredOnPosition).scale(-1))\n }\n \n return result\n \n }\n \n rectangleWithWidth(width: SizeNumberOrFunctionOrView, centeredOnPosition: number = nil) {\n \n width = this._widthNumberFromSizeNumberOrFunctionOrView(width)\n \n if (isNaN(centeredOnPosition)) {\n centeredOnPosition = nil\n }\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.width = width\n \n if (centeredOnPosition != nil) {\n const change = width - this.width\n result.offsetByPoint(new UIPoint(change * centeredOnPosition, 0).scale(-1))\n }\n \n return result\n \n }\n \n rectangleWithHeightRelativeToWidth(heightRatio: number = 1, centeredOnPosition: number = nil) {\n return this.rectangleWithHeight(this.width * heightRatio, centeredOnPosition)\n }\n \n rectangleWithWidthRelativeToHeight(widthRatio: number = 1, centeredOnPosition: number = nil) {\n return this.rectangleWithWidth(this.height * widthRatio, centeredOnPosition)\n }\n \n rectangleWithX(x: number, centeredOnPosition: number = 0) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.x = x - result.width * centeredOnPosition\n \n return result\n \n }\n \n rectangleWithY(y: number, centeredOnPosition: number = 0) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.y = y - result.height * centeredOnPosition\n \n return result\n \n }\n \n \n rectangleByAddingX(x: number) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.x = this.x + x\n \n return result\n \n }\n \n rectangleByAddingY(y: number) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.y = this.y + y\n \n return result\n \n }\n \n rectangleByAddingWidth(widthToAdd: number, centeredOnPosition = 0) {\n \n const result = this.rectangleWithWidth(this.width + widthToAdd, centeredOnPosition)\n \n return result\n \n }\n \n rectangleByAddingHeight(heightToAdd: number, centeredOnPosition = 0) {\n \n const result = this.rectangleWithHeight(this.height + heightToAdd, centeredOnPosition)\n \n return result\n \n }\n \n \n rectangleWithRelativeValues(\n relativeXPosition: number,\n widthMultiplier: number,\n relativeYPosition: number,\n heightMultiplier: number\n ) {\n \n const result = this.lazyCopy() // COW: Use lazyCopy\n result.materialize() // COW: We're modifying multiple properties\n \n const width = result.width\n const height = result.height\n \n result.width = widthMultiplier * width\n result.height = heightMultiplier * height\n \n result.center = new UIPoint(\n relativeXPosition * width,\n relativeYPosition * height\n )\n \n return result\n \n }\n \n \n /**\n * Returns a rectangle with a maximum width constraint\n * If current width exceeds max, centers the constrained width\n */\n rectangleWithMaxWidth(maxWidth: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.width <= maxWidth) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithWidth(maxWidth, centeredOnPosition)\n }\n \n /**\n * Returns a rectangle with a maximum height constraint\n */\n rectangleWithMaxHeight(maxHeight: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.height <= maxHeight) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithHeight(maxHeight, centeredOnPosition)\n }\n \n /**\n * Returns a rectangle with minimum width constraint\n */\n rectangleWithMinWidth(minWidth: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.width >= minWidth) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithWidth(minWidth, centeredOnPosition)\n }\n \n /**\n * Returns a rectangle with minimum height constraint\n */\n rectangleWithMinHeight(minHeight: number, centeredOnPosition: number = 0): UIRectangle {\n if (this.height >= minHeight) {\n return this.lazyCopy() // COW: Use lazyCopy\n }\n return this.rectangleWithHeight(minHeight, centeredOnPosition)\n }\n \n // Returns a new rectangle that is positioned relative to the reference rectangle\n // By default, it makes a copy of this rectangle taht is centered in the target rectangle\n rectangleByCenteringInRectangle(referenceRectangle: UIRectangle, xPosition = 0.5, yPosition = 0.5) {\n const result = this.lazyCopy() // COW: Use lazyCopy\n result.center = referenceRectangle.topLeft\n .pointByAddingX(xPosition * referenceRectangle.width)\n .pointByAddingY(yPosition * referenceRectangle.height)\n return result\n }\n \n \n rectanglesBySplittingWidth(\n weights: SizeNumberOrFunctionOrView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteWidths: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n \n if (IS_NIL(paddings)) {\n paddings = 1\n }\n if (!((paddings as any) instanceof Array)) {\n paddings = [paddings].arrayByRepeating(weights.length - 1)\n }\n paddings = (paddings as any[]).arrayByTrimmingToLengthIfLonger(weights.length - 1)\n paddings = paddings.map(padding => this._widthNumberFromSizeNumberOrFunctionOrView(padding))\n if (!(absoluteWidths instanceof Array) && IS_NOT_NIL(absoluteWidths)) {\n absoluteWidths = [absoluteWidths].arrayByRepeating(weights.length)\n }\n absoluteWidths = absoluteWidths.map(\n width => this._widthNumberFromSizeNumberOrFunctionOrView(width)\n )\n \n weights = weights.map(weight => this._widthNumberFromSizeNumberOrFunctionOrView(weight))\n const result: UIRectangle[] = []\n const sumOfWeights = (weights as number[]).reduce(\n (a, b, index) => {\n if (IS_NOT_NIL((absoluteWidths as number[])[index])) {\n b = 0\n }\n return a + b\n },\n 0\n )\n const sumOfPaddings = paddings.summedValue as number\n const sumOfAbsoluteWidths = (absoluteWidths as number[]).summedValue\n const totalRelativeWidth = this.width - sumOfPaddings - sumOfAbsoluteWidths\n let previousCellMaxX = this.x\n \n for (let i = 0; i < weights.length; i++) {\n \n let resultWidth: number\n if (IS_NOT_NIL(absoluteWidths[i])) {\n resultWidth = (absoluteWidths[i] || 0) as number\n }\n else {\n resultWidth = totalRelativeWidth * (weights[i] as number / sumOfWeights)\n }\n \n const rectangle = this.rectangleWithWidth(resultWidth)\n \n let padding = 0\n if (paddings.length > i && paddings[i]) {\n padding = paddings[i] as number\n }\n \n rectangle.x = previousCellMaxX\n previousCellMaxX = rectangle.max.x + padding\n result.push(rectangle)\n \n }\n \n return result\n \n }\n \n rectanglesBySplittingHeight(\n weights: SizeNumberOrFunctionOrView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteHeights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n \n if (IS_NIL(paddings)) {\n paddings = 1\n }\n if (!((paddings as any) instanceof Array)) {\n paddings = [paddings].arrayByRepeating(weights.length - 1)\n }\n paddings = (paddings as number[]).arrayByTrimmingToLengthIfLonger(weights.length - 1)\n paddings = paddings.map(padding => this._heightNumberFromSizeNumberOrFunctionOrView(padding))\n if (!(absoluteHeights instanceof Array) && IS_NOT_NIL(absoluteHeights)) {\n absoluteHeights = [absoluteHeights].arrayByRepeating(weights.length)\n }\n absoluteHeights = absoluteHeights.map(\n height => this._heightNumberFromSizeNumberOrFunctionOrView(height)\n )\n \n weights = weights.map(weight => this._heightNumberFromSizeNumberOrFunctionOrView(weight))\n const result: UIRectangle[] = []\n const sumOfWeights = (weights as number[]).reduce(\n (a, b, index) => {\n if (IS_NOT_NIL((absoluteHeights as number[])[index])) {\n b = 0\n }\n return a + b\n },\n 0\n )\n const sumOfPaddings = paddings.summedValue as number\n const sumOfAbsoluteHeights = (absoluteHeights as number[]).summedValue\n const totalRelativeHeight = this.height - sumOfPaddings - sumOfAbsoluteHeights\n let previousCellMaxY = this.y\n \n for (let i = 0; i < weights.length; i++) {\n let resultHeight: number\n if (IS_NOT_NIL(absoluteHeights[i])) {\n \n resultHeight = (absoluteHeights[i] || 0) as number\n \n }\n else {\n \n resultHeight = totalRelativeHeight * (weights[i] as number / sumOfWeights)\n \n }\n \n const rectangle = this.rectangleWithHeight(resultHeight)\n \n let padding = 0\n if (paddings.length > i && paddings[i]) {\n padding = paddings[i] as number\n }\n \n rectangle.y = previousCellMaxY\n previousCellMaxY = rectangle.max.y + padding\n //rectangle = rectangle.rectangleWithInsets(0, 0, padding, 0);\n result.push(rectangle)\n }\n \n return result\n \n }\n \n \n rectanglesByEquallySplittingWidth(numberOfFrames: number, padding: number = 0) {\n const result: UIRectangle[] = []\n const totalPadding = padding * (numberOfFrames - 1)\n const resultWidth = (this.width - totalPadding) / numberOfFrames\n for (var i = 0; i < numberOfFrames; i++) {\n const rectangle = this.rectangleWithWidth(resultWidth, i / (numberOfFrames - 1))\n result.push(rectangle)\n }\n return result\n }\n \n rectanglesByEquallySplittingHeight(numberOfFrames: number, padding: number = 0) {\n const result: UIRectangle[] = []\n const totalPadding = padding * (numberOfFrames - 1)\n const resultHeight = (this.height - totalPadding) / numberOfFrames\n for (var i = 0; i < numberOfFrames; i++) {\n const rectangle = this.rectangleWithHeight(resultHeight, i / (numberOfFrames - 1))\n result.push(rectangle)\n }\n return result\n }\n \n \n distributeViewsAlongWidth(\n views: UIView[],\n weights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 1,\n paddings?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[],\n absoluteWidths?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[]\n ) {\n if (!(weights instanceof Array)) {\n weights = [weights].arrayByRepeating(views.length)\n }\n const frames = this.rectanglesBySplittingWidth(weights, paddings, absoluteWidths)\n frames.forEach((frame, index) => FIRST_OR_NIL(views[index]).frame = frame)\n return this\n }\n \n distributeViewsAlongHeight(\n views: UIView[],\n weights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 1,\n paddings?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[],\n absoluteHeights?: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[]\n ) {\n if (!(weights instanceof Array)) {\n weights = [weights].arrayByRepeating(views.length)\n }\n const frames = this.rectanglesBySplittingHeight(weights, paddings, absoluteHeights)\n frames.forEach((frame, index) => FIRST_OR_NIL(views[index]).frame = frame)\n return this\n }\n \n \n distributeViewsEquallyAlongWidth(views: UIView[], padding: number) {\n const frames = this.rectanglesByEquallySplittingWidth(views.length, padding)\n frames.forEach((frame, index) => views[index].frame = frame)\n return this\n }\n \n distributeViewsEquallyAlongHeight(views: UIView[], padding: number) {\n const frames = this.rectanglesByEquallySplittingHeight(views.length, padding)\n frames.forEach((frame, index) => views[index].frame = frame)\n return this\n }\n \n \n _heightNumberFromSizeNumberOrFunctionOrView(height: SizeNumberOrFunctionOrView) {\n if (height instanceof Function) {\n return height(this.width)\n }\n if (height instanceof UIView) {\n return height.intrinsicContentHeight(this.width)\n }\n return height\n }\n \n _widthNumberFromSizeNumberOrFunctionOrView(width: SizeNumberOrFunctionOrView) {\n if (width instanceof Function) {\n return width(this.height)\n }\n if (width instanceof UIView) {\n return width.intrinsicContentWidth(this.height)\n }\n return width\n }\n \n rectangleForNextRow(padding: number = 0, height: SizeNumberOrFunctionOrView = this.height) {\n const heightNumber = this._heightNumberFromSizeNumberOrFunctionOrView(height)\n const result = this.rectangleWithY(this.max.y + padding)\n if (heightNumber != this.height) {\n result.height = heightNumber\n }\n return result\n }\n \n rectangleForNextColumn(padding: number = 0, width: SizeNumberOrFunctionOrView = this.width) {\n const widthNumber = this._widthNumberFromSizeNumberOrFunctionOrView(width)\n const result = this.rectangleWithX(this.max.x + padding)\n if (widthNumber != this.width) {\n result.width = widthNumber\n }\n return result\n }\n \n rectangleForPreviousRow(padding: number = 0, height: SizeNumberOrFunctionOrView = this.height) {\n const heightNumber = this._heightNumberFromSizeNumberOrFunctionOrView(height)\n const result = this.rectangleWithY(this.min.y - heightNumber - padding)\n if (heightNumber != this.height) {\n result.height = heightNumber\n }\n return result\n }\n \n rectangleForPreviousColumn(padding: number = 0, width: SizeNumberOrFunctionOrView = this.width) {\n const widthNumber = this._widthNumberFromSizeNumberOrFunctionOrView(width)\n const result = this.rectangleWithX(this.min.x - widthNumber - padding)\n if (widthNumber != this.width) {\n result.width = widthNumber\n }\n return result\n \n }\n \n /**\n * Distributes views vertically as a column, assigning frames and returning them.\n * Each view is positioned below the previous one with optional padding between them.\n * @param views - Array of views to distribute\n * @param paddings - Padding between views (single value or array of values)\n * @param absoluteHeights - Optional fixed heights for views (overrides intrinsic height)\n * @returns Array of rectangles representing the frame for each view\n */\n framesByDistributingViewsAsColumn(\n views: UIView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteHeights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n const frames: UIRectangle[] = []\n let currentRectangle = this.lazyCopy() // COW: Use lazyCopy\n \n if (!(paddings instanceof Array)) {\n paddings = [paddings].arrayByRepeating(views.length - 1)\n }\n paddings = paddings.map(padding => this._heightNumberFromSizeNumberOrFunctionOrView(padding))\n \n if (!(absoluteHeights instanceof Array) && IS_NOT_NIL(absoluteHeights)) {\n absoluteHeights = [absoluteHeights].arrayByRepeating(views.length)\n }\n absoluteHeights = absoluteHeights.map(\n height => this._heightNumberFromSizeNumberOrFunctionOrView(height)\n )\n \n for (let i = 0; i < views.length; i++) {\n const frame = currentRectangle.rectangleWithHeight(views[i])\n \n if (IS_NOT_NIL(absoluteHeights[i])) {\n frame.height = absoluteHeights[i] as number\n }\n \n views[i].frame = frame\n frames.push(frame)\n \n const padding = (paddings[i] || 0) as number\n currentRectangle = frame.rectangleForNextRow(padding)\n }\n \n return frames\n }\n \n /**\n * Distributes views horizontally as a row, assigning frames and returning them.\n * Each view is positioned to the right of the previous one with optional padding between them.\n * @param views - Array of views to distribute\n * @param paddings - Padding between views (single value or array of values)\n * @param absoluteWidths - Optional fixed widths for views (overrides intrinsic width)\n * @returns Array of rectangles representing the frame for each view\n */\n framesByDistributingViewsAsRow(\n views: UIView[],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteWidths: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n const frames: UIRectangle[] = []\n let currentRectangle = this.lazyCopy() // COW: Use lazyCopy\n \n if (!(paddings instanceof Array)) {\n paddings = [paddings].arrayByRepeating(views.length - 1)\n }\n paddings = paddings.map(padding => this._widthNumberFromSizeNumberOrFunctionOrView(padding))\n \n if (!(absoluteWidths instanceof Array) && IS_NOT_NIL(absoluteWidths)) {\n absoluteWidths = [absoluteWidths].arrayByRepeating(views.length)\n }\n absoluteWidths = absoluteWidths.map(\n width => this._widthNumberFromSizeNumberOrFunctionOrView(width)\n )\n \n for (let i = 0; i < views.length; i++) {\n const frame = currentRectangle.rectangleWithWidth(views[i])\n \n if (IS_NOT_NIL(absoluteWidths[i])) {\n frame.width = absoluteWidths[i] as number\n }\n \n views[i].frame = frame\n frames.push(frame)\n \n const padding = (paddings[i] || 0) as number\n currentRectangle = frame.rectangleForNextColumn(padding)\n }\n \n return frames\n }\n \n /**\n * Distributes views as a grid (2D array), assigning frames and returning them.\n * The first index represents rows (vertical), the second index represents columns (horizontal).\n * Example: views[0] is the first row, views[0][0] is the first column in the first row.\n * Each row is laid out horizontally, and rows are stacked vertically.\n * @param views - 2D array where views[row][column] represents the grid structure\n * @param paddings - Vertical padding between rows (single value or array of values)\n * @param absoluteHeights - Optional fixed heights for each row (overrides intrinsic height)\n * @returns 2D array of rectangles where frames[row][column] matches views[row][column]\n */\n framesByDistributingViewsAsGrid(\n views: UIView[][],\n paddings: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = 0,\n absoluteHeights: SizeNumberOrFunctionOrView | SizeNumberOrFunctionOrView[] = nil\n ) {\n const frames: UIRectangle[][] = []\n let currentRowRectangle = this.lazyCopy() // COW: Use lazyCopy\n \n if (!(paddings instanceof Array)) {\n paddings = [paddings].arrayByRepeating(views.length - 1)\n }\n paddings = paddings.map(padding => this._heightNumberFromSizeNumberOrFunctionOrView(padding))\n \n if (!(absoluteHeights instanceof Array) && IS_NOT_NIL(absoluteHeights)) {\n absoluteHeights = [absoluteHeights].arrayByRepeating(views.length)\n }\n absoluteHeights = absoluteHeights.map(\n height => this._heightNumberFromSizeNumberOrFunctionOrView(height)\n )\n \n for (let i = 0; i < views.length; i++) {\n const rowViews = views[i]\n const rowFrames = currentRowRectangle.framesByDistributingViewsAsRow(rowViews)\n \n if (IS_NOT_NIL(absoluteHeights[i])) {\n const heightNumber = absoluteHeights[i] as number\n rowFrames.forEach((frame, j) => {\n frame.height = heightNumber\n rowViews[j].frame = frame\n })\n }\n \n frames.push(rowFrames)\n \n const padding = (paddings[i] || 0) as number\n const maxHeight = Math.max(...rowFrames.map(f => f.height))\n currentRowRectangle = currentRowRectangle.rectangleForNextRow(padding, maxHeight)\n }\n \n return frames\n }\n \n rectangleWithIntrinsicContentSizeForView(view: UIView, centeredOnXPosition = 0, centeredOnYPosition = 0) {\n const intrinsicContentSize = view.intrinsicContentSize()\n return this.rectangleWithHeight(intrinsicContentSize.height, centeredOnYPosition)\n .rectangleWithWidth(intrinsicContentSize.width, centeredOnXPosition)\n }\n \n settingMinHeight(minHeight?: number) {\n this.minHeight = minHeight\n return this\n }\n \n settingMinWidth(minWidth?: number) {\n this.minWidth = minWidth\n return this\n }\n \n settingMaxHeight(maxHeight?: number) {\n this.maxHeight = maxHeight\n return this\n }\n \n settingMaxWidth(maxWidth?: number) {\n this.maxWidth = maxWidth\n return this\n }\n \n rectangleByEnforcingMinAndMaxSizes(centeredOnXPosition = 0, centeredOnYPosition = 0) {\n return this.rectangleWithHeight(\n [\n [this.height, this.maxHeight].filter(value => IS_NOT_LIKE_NULL(value)).min(),\n this.minHeight\n ].filter(value => IS_NOT_LIKE_NULL(value)).max(),\n centeredOnYPosition\n ).rectangleWithWidth(\n [\n [this.width, this.maxWidth].filter(value => IS_NOT_LIKE_NULL(value)).min(),\n this.minWidth\n ].filter(value => IS_NOT_LIKE_NULL(value)).max(),\n centeredOnXPosition\n )\n }\n \n \n assignedAsFrameOfView(view: UIView, isWeakFrame = view.hasWeakFrame) {\n view.frame = this\n view.hasWeakFrame = isWeakFrame\n return this\n }\n \n \n override toString() {\n \n const result = \"[\" + this.class.name + \"] { x: \" + this.x + \", y: \" + this.y + \", \" +\n \"height: \" + this.height.toFixed(2) + \", width: \" + this.height.toFixed(2) + \" }\"\n \n return result\n \n }\n \n get [Symbol.toStringTag]() {\n return this.toString()\n }\n \n \n IF(condition: boolean): UIRectangleConditionalChain<UIRectangle> {\n const conditionalBlock = new UIRectangleConditionalBlock(this, condition)\n // @ts-ignore\n return conditionalBlock.getProxy()\n }\n \n // These will be intercepted by the proxy, but we define them for TypeScript\n ELSE_IF(condition: boolean): UIRectangle {\n return this\n }\n \n ELSE(): UIRectangle {\n return this\n }\n \n ENDIF(): this\n ENDIF<T, R>(performFunction: (result: T) => R): R\n ENDIF<T, R>(performFunction?: (result: T) => R): R | this {\n if (performFunction) {\n return performFunction(this as any)\n }\n return this\n }\n \n \n // Bounding box\n static boundingBoxForPoints(points: UIPoint[]) {\n const result = new UIRectangle()\n for (let i = 0; i < points.length; i++) {\n result.updateByAddingPoint(points[i])\n }\n return result\n }\n \n static boundingBoxForRectanglesAndPoints(rectanglesAndPoints: (UIPoint | UIRectangle)[]) {\n const result = new UIRectangle()\n for (let i = 0; i < rectanglesAndPoints.length; i++) {\n const rectangleOrPoint = rectanglesAndPoints[i]\n if (rectangleOrPoint instanceof UIRectangle) {\n result.updateByAddingPoint(rectangleOrPoint.min)\n result.updateByAddingPoint(rectangleOrPoint.max)\n }\n else {\n result.updateByAddingPoint(rectangleOrPoint)\n }\n }\n return result\n }\n \n \n beginUpdates() {\n this._isBeingUpdated = YES\n }\n \n finishUpdates() {\n this._isBeingUpdated = NO\n this.didChange()\n }\n \n \n didChange() {\n \n // Callback to be set by delegate\n \n }\n \n _rectanglePointDidChange() {\n if (!this._isBeingUpdated) {\n this.didChange()\n }\n }\n \n \n}\n\n\n// 1. Methods available when holding a UIRectangle\ntype RectangleChainMethods<TResult> = {\n [K in keyof UIRectangle as (\n K extends 'IF' | 'ELSE' | 'ELSE_IF' | 'ENDIF' ? never : K\n )]:\n UIRectangle[K] extends (...args: infer Args) => infer R\n ? R extends UIRectangle | UIRectangle[]\n // CHANGE: We do NOT add 'R' to 'TResult' here. We only update the current state (R).\n ? (...args: Args) => UIRectangleConditionalChain<R, TResult>\n : never\n : never\n};\n\n// 2. Methods available when holding a UIRectangle[]\ntype ArrayChainMethods<TResult> = {\n [K in keyof UIRectangle[]]:\n UIRectangle[][K] extends UIRectangle\n ? UIRectangleConditionalChain<UIRectangle, TResult> // No accumulation for properties\n : UIRectangle[][K] extends (...args: infer Args) => infer R\n ? R extends UIRectangle | UIRectangle[]\n // CHANGE: We do NOT add 'R' to 'TResult' here either.\n ? (...args: Args) => UIRectangleConditionalChain<R, TResult>\n : never\n : never\n};\n\n// 3. Methods available in both states (Control Flow + Transform)\ntype SharedChainMethods<TCurrent, TResult> = {\n // TRANSFORM acts as a standard method, it should not leak intermediate types into TResult\n TRANSFORM<R extends UIRectangle>(fn: (current: TCurrent) => R): UIRectangleConditionalChain<R, TResult>;\n \n // ELSE_IF marks the end of a branch. We MUST capture the current state (TCurrent) and add it to TResult.\n // The new chain starts with the original UIRectangle state for the next branch.\n ELSE_IF(condition: boolean): UIRectangleConditionalChain<UIRectangle, TResult | TCurrent>;\n \n // ELSE marks the end of a branch. Same logic as ELSE_IF.\n ELSE(): UIRectangleConditionalChain<UIRectangle, TResult | TCurrent>;\n \n // ENDIF marks the end of the block. Same logic: capture TCurrent into TResult.\n ENDIF(): TResult | TCurrent;\n ENDIF<R>(performFunction: (result: TResult | TCurrent) => R): R;\n};\n\n// 4. The Main Type (No changes needed here, just re-stating for context)\ntype UIRectangleConditionalChain<TCurrent, TResult = TCurrent> =\n (TCurrent extends UIRectangle ? RectangleChainMethods<TResult> : {}) &\n (TCurrent extends UIRectangle[] ? ArrayChainMethods<TResult> : {}) &\n SharedChainMethods<TCurrent, TResult>;\n\n\nclass UIRectangleConditionalBlock {\n // The value we are currently chaining on (can be UIRectangle or UIRectangle[])\n private currentResult: any\n // The value where the IF block started (needed to reset for ELSE branches)\n private originalResult: any\n private conditionMet: boolean\n \n constructor(initialResult: UIRectangle, condition: boolean) {\n this.originalResult = initialResult\n this.currentResult = initialResult\n this.conditionMet = condition\n }\n \n private createProxy(): UIRectangleConditionalChain<any, any> {\n const self = this\n \n // The target is irrelevant; we delegate everything to self.currentResult\n return new Proxy({}, {\n get(_, prop) {\n \n // 1. Control Flow Methods\n \n if (prop === 'TRANSFORM') {\n return <R extends UIRectangle>(fn: (current: any) => R) => {\n if (self.conditionMet) {\n const result = fn(self.currentResult)\n self.currentResult = result\n }\n return self.createProxy()\n }\n }\n \n if (prop === 'ELSE_IF') {\n return <U>(condition: boolean) => {\n // Only enter this branch if no previous branch has run\n if (!self.conditionMet) {\n self.conditionMet = condition\n // Reset the state to the original starting point for this new branch\n self.currentResult = self.originalResult\n }\n return self.createProxy()\n }\n }\n \n if (prop === 'ELSE') {\n return <U>() => {\n if (!self.conditionMet) {\n self.conditionMet = true\n // Reset the state to the original starting point\n self.currentResult = self.originalResult\n }\n return self.createProxy()\n }\n }\n \n if (prop === 'ENDIF') {\n function endif(): any\n function endif<R>(performFunction: (result: any) => R): R\n function endif<R>(performFunction?: (result: any) => R): R | any {\n return performFunction ? performFunction(self.currentResult) : self.currentResult\n }\n return endif\n }\n \n // 2. Forwarding to currentResult (Rectangle or Array)\n \n const value = self.currentResult[prop]\n \n // Case A: It's a function (method call)\n if (typeof value === 'function') {\n return (...args: any[]) => {\n if (self.conditionMet) {\n // Call the method on the CURRENT object, and update the state\n const result = value.apply(self.currentResult, args)\n self.currentResult = result\n }\n return self.createProxy()\n }\n }\n \n // Case B: It's a property (getter)\n // Accessing a property acts as a transition (e.g. accessing .lastElement)\n if (self.conditionMet) {\n self.currentResult = value\n }\n \n return self.createProxy()\n }\n }) as any\n }\n \n getProxy(): UIRectangleConditionalChain<any, any> {\n return this.createProxy()\n }\n \n}\n\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA2G;AAC3G,qBAAwB;AACxB,oBAAuB;AAKhB,MAAM,oBAAoB,yBAAS;AAAA,EAoBtC,YAAY,IAAY,GAAG,IAAY,GAAG,SAAiB,GAAG,QAAgB,GAAG;AAE7E,UAAM;AAEN,SAAK,cAAc;AACnB,SAAK,kBAAkB;AAGvB,SAAK,QAAQ;AAAA,MACT,KAAK,IAAI,uBAAQ,GAAG,CAAC;AAAA,MACrB,KAAK,IAAI,uBAAQ,IAAI,OAAO,IAAI,MAAM;AAAA,MACtC,UAAU;AAAA,IACd;AAEA,SAAK,qBAAqB;AAE1B,YAAI,wBAAO,MAAM,GAAG;AAChB,WAAK,MAAM,IAAI,IAAI;AAAA,IACvB;AAEA,YAAI,wBAAO,KAAK,GAAG;AACf,WAAK,MAAM,IAAI,IAAI;AAAA,IACvB;AAAA,EAEJ;AAAA,EAGQ,uBAAuB;AAC3B,SAAK,MAAM,IAAI,YAAY,CAAC,UAAU;AAvD9C;AAwDY,iBAAK,4BAAL,8BAA+B;AAC/B,WAAK,yBAAyB;AAAA,IAClC;AACA,SAAK,MAAM,IAAI,YAAY,CAAC,UAAU;AA3D9C;AA4DY,iBAAK,4BAAL,8BAA+B;AAC/B,WAAK,yBAAyB;AAAA,IAClC;AAAA,EACJ;AAAA,EAGA,cAAc;AACV,QAAI,KAAK,eAAe,KAAK,MAAM,WAAW,GAAG;AAC7C,WAAK,MAAM;AAEX,YAAM,UAAU,KAAK;AACrB,WAAK,QAAQ;AAAA,QACT,KAAK,QAAQ,IAAI,KAAK;AAAA,QACtB,KAAK,QAAQ,IAAI,KAAK;AAAA,QACtB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,UAAU;AAAA,MACd;AAEA,WAAK,qBAAqB;AAC1B,WAAK,cAAc;AAAA,IACvB;AAAA,EACJ;AAAA,EAIA,WAAwB;AACpB,UAAM,SAAS,OAAO,OAAO,YAAY,SAAS;AAClD,WAAO,QAAQ,KAAK;AACpB,WAAO,MAAM;AACb,WAAO,cAAc;AACrB,WAAO,kBAAkB;AACzB,WAAO,0BAA0B,KAAK;AACtC,WAAO;AAAA,EACX;AAAA,EAGA,IAAI,MAAe;AACf,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,IAAI,IAAI,OAAgB;AACpB,SAAK,YAAY;AACjB,SAAK,MAAM,MAAM;AACjB,SAAK,qBAAqB;AAAA,EAC9B;AAAA,EAEA,IAAI,MAAe;AACf,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,IAAI,IAAI,OAAgB;AACpB,SAAK,YAAY;AACjB,SAAK,MAAM,MAAM;AACjB,SAAK,qBAAqB;AAAA,EAC9B;AAAA,EAEA,IAAI,YAAgC;AAChC,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,IAAI,UAAU,OAA2B;AACrC,SAAK,YAAY;AACjB,SAAK,MAAM,YAAY;AAAA,EAC3B;AAAA,EAEA,IAAI,YAAgC;AAChC,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,IAAI,UAAU,OAA2B;AACrC,SAAK,YAAY;AACjB,SAAK,MAAM,YAAY;AAAA,EAC3B;AAAA,EAEA,IAAI,WAA+B;AAC/B,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,IAAI,SAAS,OAA2B;AACpC,SAAK,YAAY;AACjB,SAAK,MAAM,WAAW;AAAA,EAC1B;AAAA,EAEA,IAAI,WAA+B;AAC/B,WAAO,KAAK,MAAM;AAAA,EACtB;AAAA,EAEA,IAAI,SAAS,OAA2B;AACpC,SAAK,YAAY;AACjB,SAAK,MAAM,WAAW;AAAA,EAC1B;AAAA,EAGA,OAAO;AAEH,UAAM,SAAS,IAAI,YAAY,KAAK,GAAG,KAAK,GAAG,KAAK,QAAQ,KAAK,KAAK;AAEtE,WAAO,YAAY,KAAK;AACxB,WAAO,WAAW,KAAK;AACvB,WAAO,YAAY,KAAK;AACxB,WAAO,WAAW,KAAK;AAEvB,WAAO;AAAA,EAEX;AAAA,EAEA,UAAU,WAA2C;AACjD,eAAQ,oBAAG,SAAS,KAAK,KAAK,IAAI,UAAU,UAAU,GAAG,KAAK,KAAK,IAAI,UAAU,UAAU,GAAG;AAAA,EAClG;AAAA,EAEA,OAAO,OAAO;AACV,WAAO,IAAI,YAAY,GAAG,GAAG,GAAG,CAAC;AAAA,EACrC;AAAA,EAEA,cAAc,OAAgB;AAC1B,WAAO,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK,MAAM,KAChD,MAAM,KAAK,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI;AAAA,EACrD;AAAA,EAEA,oBAAoB,OAAgB;AAEhC,SAAK,YAAY;AAEjB,QAAI,CAAC,OAAO;AACR,cAAQ,IAAI,uBAAQ,GAAG,CAAC;AAAA,IAC5B;AAEA,SAAK,aAAa;AAElB,UAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,KAAK,IAAI;AAAA,IACrB;AACA,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,KAAK,IAAI;AAAA,IACrB;AAEA,UAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,KAAK,IAAI;AAAA,IACrB;AACA,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,KAAK,IAAI;AAAA,IACrB;AAEA,SAAK,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC;AACpC,SAAK,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC;AACpC,SAAK,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC;AACpC,SAAK,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC;AAEpC,SAAK,cAAc;AAAA,EAEvB;AAAA,EAEA,MAAM,OAAe;AACjB,SAAK,YAAY;AACjB,YAAI,4BAAW,KAAK,IAAI,CAAC,GAAG;AACxB,WAAK,SAAS,KAAK,SAAS;AAAA,IAChC;AACA,YAAI,4BAAW,KAAK,IAAI,CAAC,GAAG;AACxB,WAAK,QAAQ,KAAK,QAAQ;AAAA,IAC9B;AAAA,EACJ;AAAA,EAEA,IAAI,SAAS;AACT,QAAI,KAAK,IAAI,MAAM,qBAAK;AACpB,aAAO;AAAA,IACX;AACA,WAAO,KAAK,IAAI,IAAI,KAAK,IAAI;AAAA,EACjC;AAAA,EAEA,IAAI,OAAO,QAAgB;AACvB,SAAK,YAAY;AACjB,SAAK,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI;AAAA,EACpC;AAAA,EAGA,IAAI,QAAQ;AACR,QAAI,KAAK,IAAI,MAAM,qBAAK;AACpB,aAAO;AAAA,IACX;AACA,WAAO,KAAK,IAAI,IAAI,KAAK,IAAI;AAAA,EACjC;AAAA,EAEA,IAAI,MAAM,OAAe;AACrB,SAAK,YAAY;AACjB,SAAK,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI;AAAA,EACpC;AAAA,EAGA,IAAI,IAAI;AACJ,WAAO,KAAK,IAAI;AAAA,EACpB;AAAA,EAEA,IAAI,EAAE,GAAW;AAEb,SAAK,YAAY;AACjB,SAAK,aAAa;AAElB,UAAM,QAAQ,KAAK;AACnB,SAAK,MAAM,IAAI,IAAI;AACnB,SAAK,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI;AAEhC,SAAK,cAAc;AAAA,EAEvB;AAAA,EAGA,IAAI,IAAI;AACJ,WAAO,KAAK,IAAI;AAAA,EACpB;AAAA,EAGA,IAAI,EAAE,GAAW;AAEb,SAAK,YAAY;AACjB,SAAK,aAAa;AAElB,UAAM,SAAS,KAAK;AACpB,SAAK,MAAM,IAAI,IAAI;AACnB,SAAK,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI;AAEhC,SAAK,cAAc;AAAA,EAEvB;AAAA,EAGA,IAAI,UAAU;AACV,WAAO,KAAK,IAAI,KAAK;AAAA,EACzB;AAAA,EAEA,IAAI,WAAW;AACX,WAAO,IAAI,uBAAQ,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA,EACzC;AAAA,EAEA,IAAI,aAAa;AACb,WAAO,IAAI,uBAAQ,KAAK,GAAG,KAAK,IAAI,CAAC;AAAA,EACzC;AAAA,EAEA,IAAI,cAAc;AACd,WAAO,KAAK,IAAI,KAAK;AAAA,EACzB;AAAA,EAGA,IAAI,SAAS;AACT,WAAO,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE,MAAM,GAAG,CAAC;AAAA,EAC/D;AAAA,EAEA,IAAI,OAAO,QAAiB;AACxB,SAAK,YAAY;AACjB,UAAM,SAAS,KAAK,OAAO,GAAG,MAAM;AACpC,SAAK,cAAc,MAAM;AAAA,EAC7B;AAAA,EAEA,cAAc,QAAiB;AAC3B,SAAK,YAAY;AACjB,SAAK,IAAI,IAAI,MAAM;AACnB,SAAK,IAAI,IAAI,MAAM;AAEnB,WAAO;AAAA,EACX;AAAA,EAGA,yBAAyB,WAAwB;AAC7C,SAAK,oBAAoB,UAAU,WAAW;AAC9C,SAAK,oBAAoB,UAAU,OAAO;AAC1C,WAAO;AAAA,EACX;AAAA,EAEA,sCAAsC,WAAwB;AAC1D,WAAO,KAAK,SAAS,EAAE,yBAAyB,SAAS;AAAA,EAC7D;AAAA,EAGA,mCAAmC,WAAqC;AAEpE,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,YAAY;AAEnB,WAAO,aAAa;AAEpB,UAAM,MAAM,OAAO;AACnB,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,UAAU,IAAI,IAAI,KAAK,IAAI,OAAO,OAAO,UAAU,KAAK;AAAA,IACpE;AACA,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,UAAU,IAAI,IAAI,KAAK,IAAI,OAAO,QAAQ,UAAU,MAAM;AAAA,IACtE;AAEA,UAAM,MAAM,OAAO;AACnB,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,UAAU,IAAI,IAAI,KAAK,IAAI,OAAO,OAAO,UAAU,KAAK;AAAA,IACpE;AACA,QAAI,IAAI,MAAM,qBAAK;AACf,UAAI,IAAI,UAAU,IAAI,IAAI,KAAK,IAAI,OAAO,QAAQ,UAAU,MAAM;AAAA,IACtE;AAEA,WAAO,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,UAAU,IAAI,CAAC;AACrD,WAAO,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,UAAU,IAAI,CAAC;AACrD,WAAO,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,UAAU,IAAI,CAAC;AACrD,WAAO,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,UAAU,IAAI,CAAC;AAGrD,QAAI,OAAO,SAAS,GAAG;AAEnB,YAAM,YAAY,KAAK,OAAO,IAAI,UAAU,OAAO,KAAK;AACxD,aAAO,IAAI,IAAI;AACf,aAAO,IAAI,IAAI;AAAA,IAEnB;AAEA,QAAI,OAAO,QAAQ,GAAG;AAElB,YAAM,YAAY,KAAK,OAAO,IAAI,UAAU,OAAO,KAAK;AACxD,aAAO,IAAI,IAAI;AACf,aAAO,IAAI,IAAI;AAAA,IAEnB;AAEA,WAAO,cAAc;AAErB,WAAO;AAAA,EAEX;AAAA,EAGA,IAAI,OAAO;AACP,WAAO,KAAK,SAAS,KAAK;AAAA,EAC9B;AAAA,EAGA,wBAAwB,WAAwB;AAC5C,WAAQ,KAAK,mCAAmC,SAAS,EAAE,QAAQ;AAAA,EACvE;AAAA,EAIA,oBAAoB,MAAc,OAAe,QAAgB,KAAa;AAC1E,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,YAAY;AACnB,WAAO,IAAI,IAAI,KAAK,IAAI,IAAI;AAC5B,WAAO,IAAI,IAAI,KAAK,IAAI,IAAI;AAC5B,WAAO,IAAI,IAAI,KAAK,IAAI,IAAI;AAC5B,WAAO,IAAI,IAAI,KAAK,IAAI,IAAI;AAC5B,WAAO;AAAA,EACX;AAAA,EAEA,mBAAmB,OAAe;AAC9B,WAAO,KAAK,oBAAoB,OAAO,OAAO,OAAO,KAAK;AAAA,EAC9D;AAAA,EAEA,oBAAoB,QAAoC,qBAA6B,qBAAK;AAEtF,aAAS,KAAK,4CAA4C,MAAM;AAEhE,QAAI,MAAM,kBAAkB,GAAG;AAC3B,2BAAqB;AAAA,IACzB;AAEA,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,SAAS;AAEhB,QAAI,sBAAsB,qBAAK;AAC3B,YAAM,SAAS,SAAS,KAAK;AAC7B,aAAO,cAAc,IAAI,uBAAQ,GAAG,SAAS,kBAAkB,EAAE,MAAM,EAAE,CAAC;AAAA,IAC9E;AAEA,WAAO;AAAA,EAEX;AAAA,EAEA,mBAAmB,OAAmC,qBAA6B,qBAAK;AAEpF,YAAQ,KAAK,2CAA2C,KAAK;AAE7D,QAAI,MAAM,kBAAkB,GAAG;AAC3B,2BAAqB;AAAA,IACzB;AAEA,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,QAAQ;AAEf,QAAI,sBAAsB,qBAAK;AAC3B,YAAM,SAAS,QAAQ,KAAK;AAC5B,aAAO,cAAc,IAAI,uBAAQ,SAAS,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;AAAA,IAC9E;AAEA,WAAO;AAAA,EAEX;AAAA,EAEA,mCAAmC,cAAsB,GAAG,qBAA6B,qBAAK;AAC1F,WAAO,KAAK,oBAAoB,KAAK,QAAQ,aAAa,kBAAkB;AAAA,EAChF;AAAA,EAEA,mCAAmC,aAAqB,GAAG,qBAA6B,qBAAK;AACzF,WAAO,KAAK,mBAAmB,KAAK,SAAS,YAAY,kBAAkB;AAAA,EAC/E;AAAA,EAEA,eAAe,GAAW,qBAA6B,GAAG;AAEtD,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,IAAI,IAAI,OAAO,QAAQ;AAE9B,WAAO;AAAA,EAEX;AAAA,EAEA,eAAe,GAAW,qBAA6B,GAAG;AAEtD,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,IAAI,IAAI,OAAO,SAAS;AAE/B,WAAO;AAAA,EAEX;AAAA,EAGA,mBAAmB,GAAW;AAE1B,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,IAAI,KAAK,IAAI;AAEpB,WAAO;AAAA,EAEX;AAAA,EAEA,mBAAmB,GAAW;AAE1B,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,IAAI,KAAK,IAAI;AAEpB,WAAO;AAAA,EAEX;AAAA,EAEA,uBAAuB,YAAoB,qBAAqB,GAAG;AAE/D,UAAM,SAAS,KAAK,mBAAmB,KAAK,QAAQ,YAAY,kBAAkB;AAElF,WAAO;AAAA,EAEX;AAAA,EAEA,wBAAwB,aAAqB,qBAAqB,GAAG;AAEjE,UAAM,SAAS,KAAK,oBAAoB,KAAK,SAAS,aAAa,kBAAkB;AAErF,WAAO;AAAA,EAEX;AAAA,EAGA,4BACI,mBACA,iBACA,mBACA,kBACF;AAEE,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,YAAY;AAEnB,UAAM,QAAQ,OAAO;AACrB,UAAM,SAAS,OAAO;AAEtB,WAAO,QAAQ,kBAAkB;AACjC,WAAO,SAAS,mBAAmB;AAEnC,WAAO,SAAS,IAAI;AAAA,MAChB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACxB;AAEA,WAAO;AAAA,EAEX;AAAA,EAOA,sBAAsB,UAAkB,qBAA6B,GAAgB;AACjF,QAAI,KAAK,SAAS,UAAU;AACxB,aAAO,KAAK,SAAS;AAAA,IACzB;AACA,WAAO,KAAK,mBAAmB,UAAU,kBAAkB;AAAA,EAC/D;AAAA,EAKA,uBAAuB,WAAmB,qBAA6B,GAAgB;AACnF,QAAI,KAAK,UAAU,WAAW;AAC1B,aAAO,KAAK,SAAS;AAAA,IACzB;AACA,WAAO,KAAK,oBAAoB,WAAW,kBAAkB;AAAA,EACjE;AAAA,EAKA,sBAAsB,UAAkB,qBAA6B,GAAgB;AACjF,QAAI,KAAK,SAAS,UAAU;AACxB,aAAO,KAAK,SAAS;AAAA,IACzB;AACA,WAAO,KAAK,mBAAmB,UAAU,kBAAkB;AAAA,EAC/D;AAAA,EAKA,uBAAuB,WAAmB,qBAA6B,GAAgB;AACnF,QAAI,KAAK,UAAU,WAAW;AAC1B,aAAO,KAAK,SAAS;AAAA,IACzB;AACA,WAAO,KAAK,oBAAoB,WAAW,kBAAkB;AAAA,EACjE;AAAA,EAIA,gCAAgC,oBAAiC,YAAY,KAAK,YAAY,KAAK;AAC/F,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,SAAS,mBAAmB,QAC9B,eAAe,YAAY,mBAAmB,KAAK,EACnD,eAAe,YAAY,mBAAmB,MAAM;AACzD,WAAO;AAAA,EACX;AAAA,EAGA,2BACI,SACA,WAAsE,GACtE,iBAA4E,qBAC9E;AAEE,YAAI,wBAAO,QAAQ,GAAG;AAClB,iBAAW;AAAA,IACf;AACA,QAAI,EAAG,oBAA4B,QAAQ;AACvC,iBAAW,CAAC,QAAQ,EAAE,iBAAiB,QAAQ,SAAS,CAAC;AAAA,IAC7D;AACA,eAAY,SAAmB,gCAAgC,QAAQ,SAAS,CAAC;AACjF,eAAW,SAAS,IAAI,aAAW,KAAK,2CAA2C,OAAO,CAAC;AAC3F,QAAI,EAAE,0BAA0B,cAAU,4BAAW,cAAc,GAAG;AAClE,uBAAiB,CAAC,cAAc,EAAE,iBAAiB,QAAQ,MAAM;AAAA,IACrE;AACA,qBAAiB,eAAe;AAAA,MAC5B,WAAS,KAAK,2CAA2C,KAAK;AAAA,IAClE;AAEA,cAAU,QAAQ,IAAI,YAAU,KAAK,2CAA2C,MAAM,CAAC;AACvF,UAAM,SAAwB,CAAC;AAC/B,UAAM,eAAgB,QAAqB;AAAA,MACvC,CAAC,GAAG,GAAG,UAAU;AACb,gBAAI,4BAAY,eAA4B,MAAM,GAAG;AACjD,cAAI;AAAA,QACR;AACA,eAAO,IAAI;AAAA,MACf;AAAA,MACA;AAAA,IACJ;AACA,UAAM,gBAAgB,SAAS;AAC/B,UAAM,sBAAuB,eAA4B;AACzD,UAAM,qBAAqB,KAAK,QAAQ,gBAAgB;AACxD,QAAI,mBAAmB,KAAK;AAE5B,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AAErC,UAAI;AACJ,cAAI,4BAAW,eAAe,EAAE,GAAG;AAC/B,sBAAe,eAAe,MAAM;AAAA,MACxC,OACK;AACD,sBAAc,sBAAsB,QAAQ,KAAe;AAAA,MAC/D;AAEA,YAAM,YAAY,KAAK,mBAAmB,WAAW;AAErD,UAAI,UAAU;AACd,UAAI,SAAS,SAAS,KAAK,SAAS,IAAI;AACpC,kBAAU,SAAS;AAAA,MACvB;AAEA,gBAAU,IAAI;AACd,yBAAmB,UAAU,IAAI,IAAI;AACrC,aAAO,KAAK,SAAS;AAAA,IAEzB;AAEA,WAAO;AAAA,EAEX;AAAA,EAEA,4BACI,SACA,WAAsE,GACtE,kBAA6E,qBAC/E;AAEE,YAAI,wBAAO,QAAQ,GAAG;AAClB,iBAAW;AAAA,IACf;AACA,QAAI,EAAG,oBAA4B,QAAQ;AACvC,iBAAW,CAAC,QAAQ,EAAE,iBAAiB,QAAQ,SAAS,CAAC;AAAA,IAC7D;AACA,eAAY,SAAsB,gCAAgC,QAAQ,SAAS,CAAC;AACpF,eAAW,SAAS,IAAI,aAAW,KAAK,4CAA4C,OAAO,CAAC;AAC5F,QAAI,EAAE,2BAA2B,cAAU,4BAAW,eAAe,GAAG;AACpE,wBAAkB,CAAC,eAAe,EAAE,iBAAiB,QAAQ,MAAM;AAAA,IACvE;AACA,sBAAkB,gBAAgB;AAAA,MAC9B,YAAU,KAAK,4CAA4C,MAAM;AAAA,IACrE;AAEA,cAAU,QAAQ,IAAI,YAAU,KAAK,4CAA4C,MAAM,CAAC;AACxF,UAAM,SAAwB,CAAC;AAC/B,UAAM,eAAgB,QAAqB;AAAA,MACvC,CAAC,GAAG,GAAG,UAAU;AACb,gBAAI,4BAAY,gBAA6B,MAAM,GAAG;AAClD,cAAI;AAAA,QACR;AACA,eAAO,IAAI;AAAA,MACf;AAAA,MACA;AAAA,IACJ;AACA,UAAM,gBAAgB,SAAS;AAC/B,UAAM,uBAAwB,gBAA6B;AAC3D,UAAM,sBAAsB,KAAK,SAAS,gBAAgB;AAC1D,QAAI,mBAAmB,KAAK;AAE5B,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,UAAI;AACJ,cAAI,4BAAW,gBAAgB,EAAE,GAAG;AAEhC,uBAAgB,gBAAgB,MAAM;AAAA,MAE1C,OACK;AAED,uBAAe,uBAAuB,QAAQ,KAAe;AAAA,MAEjE;AAEA,YAAM,YAAY,KAAK,oBAAoB,YAAY;AAEvD,UAAI,UAAU;AACd,UAAI,SAAS,SAAS,KAAK,SAAS,IAAI;AACpC,kBAAU,SAAS;AAAA,MACvB;AAEA,gBAAU,IAAI;AACd,yBAAmB,UAAU,IAAI,IAAI;AAErC,aAAO,KAAK,SAAS;AAAA,IACzB;AAEA,WAAO;AAAA,EAEX;AAAA,EAGA,kCAAkC,gBAAwB,UAAkB,GAAG;AAC3E,UAAM,SAAwB,CAAC;AAC/B,UAAM,eAAe,WAAW,iBAAiB;AACjD,UAAM,eAAe,KAAK,QAAQ,gBAAgB;AAClD,aAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACrC,YAAM,YAAY,KAAK,mBAAmB,aAAa,KAAK,iBAAiB,EAAE;AAC/E,aAAO,KAAK,SAAS;AAAA,IACzB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,mCAAmC,gBAAwB,UAAkB,GAAG;AAC5E,UAAM,SAAwB,CAAC;AAC/B,UAAM,eAAe,WAAW,iBAAiB;AACjD,UAAM,gBAAgB,KAAK,SAAS,gBAAgB;AACpD,aAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACrC,YAAM,YAAY,KAAK,oBAAoB,cAAc,KAAK,iBAAiB,EAAE;AACjF,aAAO,KAAK,SAAS;AAAA,IACzB;AACA,WAAO;AAAA,EACX;AAAA,EAGA,0BACI,OACA,UAAqE,GACrE,UACA,gBACF;AACE,QAAI,EAAE,mBAAmB,QAAQ;AAC7B,gBAAU,CAAC,OAAO,EAAE,iBAAiB,MAAM,MAAM;AAAA,IACrD;AACA,UAAM,SAAS,KAAK,2BAA2B,SAAS,UAAU,cAAc;AAChF,WAAO,QAAQ,CAAC,OAAO,cAAU,8BAAa,MAAM,MAAM,EAAE,QAAQ,KAAK;AACzE,WAAO;AAAA,EACX;AAAA,EAEA,2BACI,OACA,UAAqE,GACrE,UACA,iBACF;AACE,QAAI,EAAE,mBAAmB,QAAQ;AAC7B,gBAAU,CAAC,OAAO,EAAE,iBAAiB,MAAM,MAAM;AAAA,IACrD;AACA,UAAM,SAAS,KAAK,4BAA4B,SAAS,UAAU,eAAe;AAClF,WAAO,QAAQ,CAAC,OAAO,cAAU,8BAAa,MAAM,MAAM,EAAE,QAAQ,KAAK;AACzE,WAAO;AAAA,EACX;AAAA,EAGA,iCAAiC,OAAiB,SAAiB;AAC/D,UAAM,SAAS,KAAK,kCAAkC,MAAM,QAAQ,OAAO;AAC3E,WAAO,QAAQ,CAAC,OAAO,UAAU,MAAM,OAAO,QAAQ,KAAK;AAC3D,WAAO;AAAA,EACX;AAAA,EAEA,kCAAkC,OAAiB,SAAiB;AAChE,UAAM,SAAS,KAAK,mCAAmC,MAAM,QAAQ,OAAO;AAC5E,WAAO,QAAQ,CAAC,OAAO,UAAU,MAAM,OAAO,QAAQ,KAAK;AAC3D,WAAO;AAAA,EACX;AAAA,EAGA,4CAA4C,QAAoC;AAC5E,QAAI,kBAAkB,UAAU;AAC5B,aAAO,OAAO,KAAK,KAAK;AAAA,IAC5B;AACA,QAAI,kBAAkB,sBAAQ;AAC1B,aAAO,OAAO,uBAAuB,KAAK,KAAK;AAAA,IACnD;AACA,WAAO;AAAA,EACX;AAAA,EAEA,2CAA2C,OAAmC;AAC1E,QAAI,iBAAiB,UAAU;AAC3B,aAAO,MAAM,KAAK,MAAM;AAAA,IAC5B;AACA,QAAI,iBAAiB,sBAAQ;AACzB,aAAO,MAAM,sBAAsB,KAAK,MAAM;AAAA,IAClD;AACA,WAAO;AAAA,EACX;AAAA,EAEA,oBAAoB,UAAkB,GAAG,SAAqC,KAAK,QAAQ;AACvF,UAAM,eAAe,KAAK,4CAA4C,MAAM;AAC5E,UAAM,SAAS,KAAK,eAAe,KAAK,IAAI,IAAI,OAAO;AACvD,QAAI,gBAAgB,KAAK,QAAQ;AAC7B,aAAO,SAAS;AAAA,IACpB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,uBAAuB,UAAkB,GAAG,QAAoC,KAAK,OAAO;AACxF,UAAM,cAAc,KAAK,2CAA2C,KAAK;AACzE,UAAM,SAAS,KAAK,eAAe,KAAK,IAAI,IAAI,OAAO;AACvD,QAAI,eAAe,KAAK,OAAO;AAC3B,aAAO,QAAQ;AAAA,IACnB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,wBAAwB,UAAkB,GAAG,SAAqC,KAAK,QAAQ;AAC3F,UAAM,eAAe,KAAK,4CAA4C,MAAM;AAC5E,UAAM,SAAS,KAAK,eAAe,KAAK,IAAI,IAAI,eAAe,OAAO;AACtE,QAAI,gBAAgB,KAAK,QAAQ;AAC7B,aAAO,SAAS;AAAA,IACpB;AACA,WAAO;AAAA,EACX;AAAA,EAEA,2BAA2B,UAAkB,GAAG,QAAoC,KAAK,OAAO;AAC5F,UAAM,cAAc,KAAK,2CAA2C,KAAK;AACzE,UAAM,SAAS,KAAK,eAAe,KAAK,IAAI,IAAI,cAAc,OAAO;AACrE,QAAI,eAAe,KAAK,OAAO;AAC3B,aAAO,QAAQ;AAAA,IACnB;AACA,WAAO;AAAA,EAEX;AAAA,EAUA,kCACI,OACA,WAAsE,GACtE,kBAA6E,qBAC/E;AACE,UAAM,SAAwB,CAAC;AAC/B,QAAI,mBAAmB,KAAK,SAAS;AAErC,QAAI,EAAE,oBAAoB,QAAQ;AAC9B,iBAAW,CAAC,QAAQ,EAAE,iBAAiB,MAAM,SAAS,CAAC;AAAA,IAC3D;AACA,eAAW,SAAS,IAAI,aAAW,KAAK,4CAA4C,OAAO,CAAC;AAE5F,QAAI,EAAE,2BAA2B,cAAU,4BAAW,eAAe,GAAG;AACpE,wBAAkB,CAAC,eAAe,EAAE,iBAAiB,MAAM,MAAM;AAAA,IACrE;AACA,sBAAkB,gBAAgB;AAAA,MAC9B,YAAU,KAAK,4CAA4C,MAAM;AAAA,IACrE;AAEA,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,QAAQ,iBAAiB,oBAAoB,MAAM,EAAE;AAE3D,cAAI,4BAAW,gBAAgB,EAAE,GAAG;AAChC,cAAM,SAAS,gBAAgB;AAAA,MACnC;AAEA,YAAM,GAAG,QAAQ;AACjB,aAAO,KAAK,KAAK;AAEjB,YAAM,UAAW,SAAS,MAAM;AAChC,yBAAmB,MAAM,oBAAoB,OAAO;AAAA,IACxD;AAEA,WAAO;AAAA,EACX;AAAA,EAUA,+BACI,OACA,WAAsE,GACtE,iBAA4E,qBAC9E;AACE,UAAM,SAAwB,CAAC;AAC/B,QAAI,mBAAmB,KAAK,SAAS;AAErC,QAAI,EAAE,oBAAoB,QAAQ;AAC9B,iBAAW,CAAC,QAAQ,EAAE,iBAAiB,MAAM,SAAS,CAAC;AAAA,IAC3D;AACA,eAAW,SAAS,IAAI,aAAW,KAAK,2CAA2C,OAAO,CAAC;AAE3F,QAAI,EAAE,0BAA0B,cAAU,4BAAW,cAAc,GAAG;AAClE,uBAAiB,CAAC,cAAc,EAAE,iBAAiB,MAAM,MAAM;AAAA,IACnE;AACA,qBAAiB,eAAe;AAAA,MAC5B,WAAS,KAAK,2CAA2C,KAAK;AAAA,IAClE;AAEA,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,QAAQ,iBAAiB,mBAAmB,MAAM,EAAE;AAE1D,cAAI,4BAAW,eAAe,EAAE,GAAG;AAC/B,cAAM,QAAQ,eAAe;AAAA,MACjC;AAEA,YAAM,GAAG,QAAQ;AACjB,aAAO,KAAK,KAAK;AAEjB,YAAM,UAAW,SAAS,MAAM;AAChC,yBAAmB,MAAM,uBAAuB,OAAO;AAAA,IAC3D;AAEA,WAAO;AAAA,EACX;AAAA,EAYA,gCACI,OACA,WAAsE,GACtE,kBAA6E,qBAC/E;AACE,UAAM,SAA0B,CAAC;AACjC,QAAI,sBAAsB,KAAK,SAAS;AAExC,QAAI,EAAE,oBAAoB,QAAQ;AAC9B,iBAAW,CAAC,QAAQ,EAAE,iBAAiB,MAAM,SAAS,CAAC;AAAA,IAC3D;AACA,eAAW,SAAS,IAAI,aAAW,KAAK,4CAA4C,OAAO,CAAC;AAE5F,QAAI,EAAE,2BAA2B,cAAU,4BAAW,eAAe,GAAG;AACpE,wBAAkB,CAAC,eAAe,EAAE,iBAAiB,MAAM,MAAM;AAAA,IACrE;AACA,sBAAkB,gBAAgB;AAAA,MAC9B,YAAU,KAAK,4CAA4C,MAAM;AAAA,IACrE;AAEA,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,YAAM,WAAW,MAAM;AACvB,YAAM,YAAY,oBAAoB,+BAA+B,QAAQ;AAE7E,cAAI,4BAAW,gBAAgB,EAAE,GAAG;AAChC,cAAM,eAAe,gBAAgB;AACrC,kBAAU,QAAQ,CAAC,OAAO,MAAM;AAC5B,gBAAM,SAAS;AACf,mBAAS,GAAG,QAAQ;AAAA,QACxB,CAAC;AAAA,MACL;AAEA,aAAO,KAAK,SAAS;AAErB,YAAM,UAAW,SAAS,MAAM;AAChC,YAAM,YAAY,KAAK,IAAI,GAAG,UAAU,IAAI,OAAK,EAAE,MAAM,CAAC;AAC1D,4BAAsB,oBAAoB,oBAAoB,SAAS,SAAS;AAAA,IACpF;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,yCAAyC,MAAc,sBAAsB,GAAG,sBAAsB,GAAG;AACrG,UAAM,uBAAuB,KAAK,qBAAqB;AACvD,WAAO,KAAK,oBAAoB,qBAAqB,QAAQ,mBAAmB,EAC3E,mBAAmB,qBAAqB,OAAO,mBAAmB;AAAA,EAC3E;AAAA,EAEA,iBAAiB,WAAoB;AACjC,SAAK,YAAY;AACjB,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB,UAAmB;AAC/B,SAAK,WAAW;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,iBAAiB,WAAoB;AACjC,SAAK,YAAY;AACjB,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB,UAAmB;AAC/B,SAAK,WAAW;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,mCAAmC,sBAAsB,GAAG,sBAAsB,GAAG;AACjF,WAAO,KAAK;AAAA,MACR;AAAA,QACI,CAAC,KAAK,QAAQ,KAAK,SAAS,EAAE,OAAO,eAAS,kCAAiB,KAAK,CAAC,EAAE,IAAI;AAAA,QAC3E,KAAK;AAAA,MACT,EAAE,OAAO,eAAS,kCAAiB,KAAK,CAAC,EAAE,IAAI;AAAA,MAC/C;AAAA,IACJ,EAAE;AAAA,MACE;AAAA,QACI,CAAC,KAAK,OAAO,KAAK,QAAQ,EAAE,OAAO,eAAS,kCAAiB,KAAK,CAAC,EAAE,IAAI;AAAA,QACzE,KAAK;AAAA,MACT,EAAE,OAAO,eAAS,kCAAiB,KAAK,CAAC,EAAE,IAAI;AAAA,MAC/C;AAAA,IACJ;AAAA,EACJ;AAAA,EAGA,sBAAsB,MAAc,cAAc,KAAK,cAAc;AACjE,SAAK,QAAQ;AACb,SAAK,eAAe;AACpB,WAAO;AAAA,EACX;AAAA,EAGS,WAAW;AAEhB,UAAM,SAAS,MAAM,KAAK,MAAM,OAAO,YAAY,KAAK,IAAI,UAAU,KAAK,IAAI,eAC9D,KAAK,OAAO,QAAQ,CAAC,IAAI,cAAc,KAAK,OAAO,QAAQ,CAAC,IAAI;AAEjF,WAAO;AAAA,EAEX;AAAA,EAEA,KAAK,OAAO,eAAe;AACvB,WAAO,KAAK,SAAS;AAAA,EACzB;AAAA,EAGA,GAAG,WAA8D;AAC7D,UAAM,mBAAmB,IAAI,4BAA4B,MAAM,SAAS;AAExE,WAAO,iBAAiB,SAAS;AAAA,EACrC;AAAA,EAGA,QAAQ,WAAiC;AACrC,WAAO;AAAA,EACX;AAAA,EAEA,OAAoB;AAChB,WAAO;AAAA,EACX;AAAA,EAIA,MAAY,iBAA8C;AACtD,QAAI,iBAAiB;AACjB,aAAO,gBAAgB,IAAW;AAAA,IACtC;AACA,WAAO;AAAA,EACX;AAAA,EAIA,OAAO,qBAAqB,QAAmB;AAC3C,UAAM,SAAS,IAAI,YAAY;AAC/B,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACpC,aAAO,oBAAoB,OAAO,EAAE;AAAA,IACxC;AACA,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,kCAAkC,qBAAgD;AACrF,UAAM,SAAS,IAAI,YAAY;AAC/B,aAAS,IAAI,GAAG,IAAI,oBAAoB,QAAQ,KAAK;AACjD,YAAM,mBAAmB,oBAAoB;AAC7C,UAAI,4BAA4B,aAAa;AACzC,eAAO,oBAAoB,iBAAiB,GAAG;AAC/C,eAAO,oBAAoB,iBAAiB,GAAG;AAAA,MACnD,OACK;AACD,eAAO,oBAAoB,gBAAgB;AAAA,MAC/C;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAGA,eAAe;AACX,SAAK,kBAAkB;AAAA,EAC3B;AAAA,EAEA,gBAAgB;AACZ,SAAK,kBAAkB;AACvB,SAAK,UAAU;AAAA,EACnB;AAAA,EAGA,YAAY;AAAA,EAIZ;AAAA,EAEA,2BAA2B;AACvB,QAAI,CAAC,KAAK,iBAAiB;AACvB,WAAK,UAAU;AAAA,IACnB;AAAA,EACJ;AAGJ;AAqDA,MAAM,4BAA4B;AAAA,EAO9B,YAAY,eAA4B,WAAoB;AACxD,SAAK,iBAAiB;AACtB,SAAK,gBAAgB;AACrB,SAAK,eAAe;AAAA,EACxB;AAAA,EAEQ,cAAqD;AACzD,UAAM,OAAO;AAGb,WAAO,IAAI,MAAM,CAAC,GAAG;AAAA,MACjB,IAAI,GAAG,MAAM;AAIT,YAAI,SAAS,aAAa;AACtB,iBAAO,CAAwB,OAA4B;AACvD,gBAAI,KAAK,cAAc;AACnB,oBAAM,SAAS,GAAG,KAAK,aAAa;AACpC,mBAAK,gBAAgB;AAAA,YACzB;AACA,mBAAO,KAAK,YAAY;AAAA,UAC5B;AAAA,QACJ;AAEA,YAAI,SAAS,WAAW;AACpB,iBAAO,CAAI,cAAuB;AAE9B,gBAAI,CAAC,KAAK,cAAc;AACpB,mBAAK,eAAe;AAEpB,mBAAK,gBAAgB,KAAK;AAAA,YAC9B;AACA,mBAAO,KAAK,YAAY;AAAA,UAC5B;AAAA,QACJ;AAEA,YAAI,SAAS,QAAQ;AACjB,iBAAO,MAAS;AACZ,gBAAI,CAAC,KAAK,cAAc;AACpB,mBAAK,eAAe;AAEpB,mBAAK,gBAAgB,KAAK;AAAA,YAC9B;AACA,mBAAO,KAAK,YAAY;AAAA,UAC5B;AAAA,QACJ;AAEA,YAAI,SAAS,SAAS;AAGlB,cAASA,SAAT,SAAkB,iBAA+C;AAC7D,mBAAO,kBAAkB,gBAAgB,KAAK,aAAa,IAAI,KAAK;AAAA,UACxE;AAFS,sBAAAA;AAGT,iBAAOA;AAAA,QACX;AAIA,cAAM,QAAQ,KAAK,cAAc;AAGjC,YAAI,OAAO,UAAU,YAAY;AAC7B,iBAAO,IAAI,SAAgB;AACvB,gBAAI,KAAK,cAAc;AAEnB,oBAAM,SAAS,MAAM,MAAM,KAAK,eAAe,IAAI;AACnD,mBAAK,gBAAgB;AAAA,YACzB;AACA,mBAAO,KAAK,YAAY;AAAA,UAC5B;AAAA,QACJ;AAIA,YAAI,KAAK,cAAc;AACnB,eAAK,gBAAgB;AAAA,QACzB;AAEA,eAAO,KAAK,YAAY;AAAA,MAC5B;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,WAAkD;AAC9C,WAAO,KAAK,YAAY;AAAA,EAC5B;AAEJ;",
|
|
6
6
|
"names": ["endif"]
|
|
7
7
|
}
|
|
@@ -5,6 +5,9 @@ export declare class UITextField extends UITextView {
|
|
|
5
5
|
_placeholderTextKey?: string;
|
|
6
6
|
_defaultPlaceholderText?: string;
|
|
7
7
|
_viewHTMLElement: HTMLInputElement;
|
|
8
|
+
private _datalistElement?;
|
|
9
|
+
private _nativeAutocompleteData;
|
|
10
|
+
minCharactersForAutocomplete: number;
|
|
8
11
|
constructor(elementID?: string, viewHTMLElement?: null, type?: string | ValueOf<typeof UITextView.type>);
|
|
9
12
|
static controlEvent: {
|
|
10
13
|
readonly PointerDown: "PointerDown";
|
|
@@ -43,4 +46,15 @@ export declare class UITextField extends UITextView {
|
|
|
43
46
|
_setPlaceholderFromKeyIfPossible(): void;
|
|
44
47
|
get isSecure(): boolean;
|
|
45
48
|
set isSecure(secure: boolean);
|
|
49
|
+
/**
|
|
50
|
+
* Sets the data for native browser autocomplete using HTML datalist.
|
|
51
|
+
* Setting an empty array will remove the autocomplete functionality.
|
|
52
|
+
*
|
|
53
|
+
* @param data Array of strings to show as autocomplete suggestions
|
|
54
|
+
*/
|
|
55
|
+
set nativeAutocompleteData(data: string[]);
|
|
56
|
+
get nativeAutocompleteData(): string[];
|
|
57
|
+
private updateDatalist;
|
|
58
|
+
private _updateDatalistVisibility;
|
|
59
|
+
wasRemovedFromViewTree(): void;
|
|
46
60
|
}
|
|
@@ -29,6 +29,8 @@ var import_UIView = require("./UIView");
|
|
|
29
29
|
const _UITextField = class extends import_UITextView.UITextView {
|
|
30
30
|
constructor(elementID, viewHTMLElement = null, type = import_UITextView.UITextView.type.textField) {
|
|
31
31
|
super(elementID, type, viewHTMLElement);
|
|
32
|
+
this._nativeAutocompleteData = [];
|
|
33
|
+
this.minCharactersForAutocomplete = 0;
|
|
32
34
|
this.textElementView.viewHTMLElement.setAttribute("type", "text");
|
|
33
35
|
this.backgroundColor = import_UIColor.UIColor.whiteColor;
|
|
34
36
|
this.addTargetForControlEvent(
|
|
@@ -37,6 +39,7 @@ const _UITextField = class extends import_UITextView.UITextView {
|
|
|
37
39
|
);
|
|
38
40
|
this.textElementView.viewHTMLElement.oninput = (event) => {
|
|
39
41
|
this.sendControlEventForKey(_UITextField.controlEvent.TextChange, event);
|
|
42
|
+
this._updateDatalistVisibility();
|
|
40
43
|
};
|
|
41
44
|
this.textElementView.style.webkitUserSelect = "text";
|
|
42
45
|
this.nativeSelectionEnabled = import_UIObject.YES;
|
|
@@ -93,6 +96,55 @@ const _UITextField = class extends import_UITextView.UITextView {
|
|
|
93
96
|
}
|
|
94
97
|
this.textElementView.viewHTMLElement.type = type;
|
|
95
98
|
}
|
|
99
|
+
set nativeAutocompleteData(data) {
|
|
100
|
+
this._nativeAutocompleteData = data;
|
|
101
|
+
this.updateDatalist();
|
|
102
|
+
this._updateDatalistVisibility();
|
|
103
|
+
}
|
|
104
|
+
get nativeAutocompleteData() {
|
|
105
|
+
return this._nativeAutocompleteData;
|
|
106
|
+
}
|
|
107
|
+
updateDatalist() {
|
|
108
|
+
if (this._nativeAutocompleteData.length === 0) {
|
|
109
|
+
if (this._datalistElement) {
|
|
110
|
+
this._datalistElement.remove();
|
|
111
|
+
this.textElementView.viewHTMLElement.removeAttribute("list");
|
|
112
|
+
this._datalistElement = void 0;
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (!this._datalistElement) {
|
|
117
|
+
const datalistId = this.elementID + "_datalist";
|
|
118
|
+
this._datalistElement = document.createElement("datalist");
|
|
119
|
+
this._datalistElement.id = datalistId;
|
|
120
|
+
this.viewHTMLElement.appendChild(this._datalistElement);
|
|
121
|
+
this.textElementView.viewHTMLElement.setAttribute("list", datalistId);
|
|
122
|
+
}
|
|
123
|
+
this._datalistElement.innerHTML = "";
|
|
124
|
+
this._nativeAutocompleteData.forEach((item) => {
|
|
125
|
+
const option = document.createElement("option");
|
|
126
|
+
option.value = item;
|
|
127
|
+
this._datalistElement.appendChild(option);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
_updateDatalistVisibility() {
|
|
131
|
+
if (!this._datalistElement || this.minCharactersForAutocomplete === 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const shouldShow = this.text.length >= this.minCharactersForAutocomplete;
|
|
135
|
+
if (shouldShow) {
|
|
136
|
+
this.textElementView.viewHTMLElement.setAttribute("list", this._datalistElement.id);
|
|
137
|
+
} else {
|
|
138
|
+
this.textElementView.viewHTMLElement.removeAttribute("list");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
wasRemovedFromViewTree() {
|
|
142
|
+
super.wasRemovedFromViewTree();
|
|
143
|
+
if (this._datalistElement) {
|
|
144
|
+
this._datalistElement.remove();
|
|
145
|
+
this._datalistElement = void 0;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
96
148
|
};
|
|
97
149
|
let UITextField = _UITextField;
|
|
98
150
|
UITextField.controlEvent = Object.assign({}, import_UITextView.UITextView.controlEvent, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UITextField.ts"],
|
|
4
|
-
"sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { nil, NO, ValueOf, YES } from \"./UIObject\"\nimport { UITextView } from \"./UITextView\"\nimport { UIView, UIViewAddControlEventTargetObject, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextField extends UITextView {\n \n _placeholderTextKey?: string\n _defaultPlaceholderText?: string\n \n override _viewHTMLElement!: HTMLInputElement\n \n constructor(\n elementID?: string,\n viewHTMLElement = null,\n type: string | ValueOf<typeof UITextView.type> = UITextView.type.textField\n ) {\n \n super(elementID, type, viewHTMLElement)\n \n this.textElementView.viewHTMLElement.setAttribute(\"type\", \"text\")\n this.backgroundColor = UIColor.whiteColor\n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n this.textElementView.viewHTMLElement.oninput = (event) => {\n this.sendControlEventForKey(UITextField.controlEvent.TextChange, event)\n }\n this.textElementView.style.webkitUserSelect = \"text\"\n this.nativeSelectionEnabled = YES\n this.pausesPointerEvents = NO\n this.changesOften = YES\n \n }\n \n \n static override controlEvent = Object.assign({}, UITextView.controlEvent, {\n \n \"TextChange\": \"TextChange\"\n \n })\n \n \n override get controlEventTargetAccumulator(): UIViewAddControlEventTargetObject<typeof UITextField> {\n return (super.controlEventTargetAccumulator as any)\n }\n \n public override get viewHTMLElement() {\n return this._viewHTMLElement\n }\n \n \n public override set text(text: string) {\n this.textElementView.viewHTMLElement.value = text\n }\n \n public override get text(): string {\n return this.textElementView.viewHTMLElement.value\n }\n \n \n public set placeholderText(text: string) {\n this.textElementView.viewHTMLElement.placeholder = text\n }\n \n public get placeholderText(): string {\n return this.textElementView.viewHTMLElement.placeholder\n }\n \n \n setPlaceholderText(key: string, defaultString: string) {\n \n this._placeholderTextKey = key\n this._defaultPlaceholderText = defaultString\n \n const languageName = UICore.languageService.currentLanguageKey\n this.placeholderText = UICore.languageService.stringForKey(key, languageName, defaultString, nil)\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UIView.broadcastEventName.LanguageChanged || event.name ==\n UIView.broadcastEventName.AddedToViewTree) {\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n }\n \n \n override willMoveToSuperview(superview: UIView) {\n \n super.willMoveToSuperview(superview)\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n _setPlaceholderFromKeyIfPossible() {\n \n if (this._placeholderTextKey && this._defaultPlaceholderText) {\n \n this.setPlaceholderText(this._placeholderTextKey, this._defaultPlaceholderText)\n \n }\n \n }\n \n \n public get isSecure(): boolean {\n const result = (this.textElementView.viewHTMLElement.type == \"password\")\n return result\n }\n \n public set isSecure(secure: boolean) {\n let type = \"text\"\n if (secure) {\n type = \"password\"\n }\n this.textElementView.viewHTMLElement.type = type\n }\n \n \n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAwB;AACxB,oBAAuB;AACvB,sBAAsC;AACtC,wBAA2B;AAC3B,oBAAgF;AAGzE,MAAM,eAAN,cAA0B,6BAAW;AAAA,
|
|
4
|
+
"sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { nil, NO, ValueOf, YES } from \"./UIObject\"\nimport { UITextView } from \"./UITextView\"\nimport { UIView, UIViewAddControlEventTargetObject, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextField extends UITextView {\n \n _placeholderTextKey?: string\n _defaultPlaceholderText?: string\n \n override _viewHTMLElement!: HTMLInputElement\n \n // --- Native Autocomplete (HTML datalist) ---\n \n private _datalistElement?: HTMLDataListElement\n private _nativeAutocompleteData: string[] = []\n public minCharactersForAutocomplete: number = 0\n \n constructor(\n elementID?: string,\n viewHTMLElement = null,\n type: string | ValueOf<typeof UITextView.type> = UITextView.type.textField\n ) {\n \n super(elementID, type, viewHTMLElement)\n \n this.textElementView.viewHTMLElement.setAttribute(\"type\", \"text\")\n this.backgroundColor = UIColor.whiteColor\n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n this.textElementView.viewHTMLElement.oninput = (event) => {\n this.sendControlEventForKey(UITextField.controlEvent.TextChange, event)\n this._updateDatalistVisibility()\n }\n this.textElementView.style.webkitUserSelect = \"text\"\n this.nativeSelectionEnabled = YES\n this.pausesPointerEvents = NO\n this.changesOften = YES\n \n }\n \n \n static override controlEvent = Object.assign({}, UITextView.controlEvent, {\n \n \"TextChange\": \"TextChange\"\n \n })\n \n \n override get controlEventTargetAccumulator(): UIViewAddControlEventTargetObject<typeof UITextField> {\n return (super.controlEventTargetAccumulator as any)\n }\n \n public override get viewHTMLElement() {\n return this._viewHTMLElement\n }\n \n \n public override set text(text: string) {\n this.textElementView.viewHTMLElement.value = text\n }\n \n public override get text(): string {\n return this.textElementView.viewHTMLElement.value\n }\n \n \n public set placeholderText(text: string) {\n this.textElementView.viewHTMLElement.placeholder = text\n }\n \n public get placeholderText(): string {\n return this.textElementView.viewHTMLElement.placeholder\n }\n \n \n setPlaceholderText(key: string, defaultString: string) {\n \n this._placeholderTextKey = key\n this._defaultPlaceholderText = defaultString\n \n const languageName = UICore.languageService.currentLanguageKey\n this.placeholderText = UICore.languageService.stringForKey(key, languageName, defaultString, nil)\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UIView.broadcastEventName.LanguageChanged || event.name ==\n UIView.broadcastEventName.AddedToViewTree) {\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n }\n \n \n override willMoveToSuperview(superview: UIView) {\n \n super.willMoveToSuperview(superview)\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n _setPlaceholderFromKeyIfPossible() {\n \n if (this._placeholderTextKey && this._defaultPlaceholderText) {\n \n this.setPlaceholderText(this._placeholderTextKey, this._defaultPlaceholderText)\n \n }\n \n }\n \n \n public get isSecure(): boolean {\n const result = (this.textElementView.viewHTMLElement.type == \"password\")\n return result\n }\n \n public set isSecure(secure: boolean) {\n let type = \"text\"\n if (secure) {\n type = \"password\"\n }\n this.textElementView.viewHTMLElement.type = type\n }\n \n \n // --- Native Autocomplete Methods ---\n \n \n \n /**\n * Sets the data for native browser autocomplete using HTML datalist.\n * Setting an empty array will remove the autocomplete functionality.\n *\n * @param data Array of strings to show as autocomplete suggestions\n */\n public set nativeAutocompleteData(data: string[]) {\n this._nativeAutocompleteData = data\n this.updateDatalist()\n this._updateDatalistVisibility()\n }\n \n public get nativeAutocompleteData(): string[] {\n return this._nativeAutocompleteData\n }\n \n private updateDatalist() {\n // If no data, remove the datalist\n if (this._nativeAutocompleteData.length === 0) {\n if (this._datalistElement) {\n this._datalistElement.remove()\n this.textElementView.viewHTMLElement.removeAttribute(\"list\")\n this._datalistElement = undefined\n }\n return\n }\n \n // Create datalist if it doesn't exist\n if (!this._datalistElement) {\n const datalistId = this.elementID + \"_datalist\"\n this._datalistElement = document.createElement(\"datalist\")\n this._datalistElement.id = datalistId\n // Add datalist as a sibling to the text element within this view's container\n this.viewHTMLElement.appendChild(this._datalistElement)\n this.textElementView.viewHTMLElement.setAttribute(\"list\", datalistId)\n }\n \n // Update the options\n this._datalistElement.innerHTML = \"\"\n this._nativeAutocompleteData.forEach(item => {\n const option = document.createElement(\"option\")\n option.value = item\n this._datalistElement!.appendChild(option)\n })\n }\n \n private _updateDatalistVisibility() {\n if (!this._datalistElement || this.minCharactersForAutocomplete === 0) {\n return\n }\n \n const shouldShow = this.text.length >= this.minCharactersForAutocomplete\n \n if (shouldShow) {\n this.textElementView.viewHTMLElement.setAttribute(\"list\", this._datalistElement.id)\n } else {\n this.textElementView.viewHTMLElement.removeAttribute(\"list\")\n }\n }\n \n override wasRemovedFromViewTree() {\n \n super.wasRemovedFromViewTree()\n \n // Clean up datalist element when text field is removed\n if (this._datalistElement) {\n this._datalistElement.remove()\n this._datalistElement = undefined\n }\n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -156,6 +156,7 @@ export declare class UIView extends UIObject {
|
|
|
156
156
|
startVirtualLayout(): void;
|
|
157
157
|
finishVirtualLayout(): void;
|
|
158
158
|
_frameForVirtualLayouting?: UIRectangle;
|
|
159
|
+
_frameCacheForVirtualLayouting?: UIRectangle;
|
|
159
160
|
usesVirtualLayoutingForIntrinsicSizing: boolean;
|
|
160
161
|
_contentInsets: {
|
|
161
162
|
top: number;
|
|
@@ -640,7 +640,7 @@ const _UIView = class extends import_UIObject.UIObject {
|
|
|
640
640
|
}
|
|
641
641
|
}
|
|
642
642
|
get bounds() {
|
|
643
|
-
var _a, _b, _c, _d, _e
|
|
643
|
+
var _a, _b, _c, _d, _e;
|
|
644
644
|
let _frame;
|
|
645
645
|
if (!this.isVirtualLayouting) {
|
|
646
646
|
_frame = this._frame;
|
|
@@ -649,19 +649,29 @@ const _UIView = class extends import_UIObject.UIObject {
|
|
|
649
649
|
}
|
|
650
650
|
let result;
|
|
651
651
|
if ((0, import_UIObject.IS_NOT)(_frame)) {
|
|
652
|
-
|
|
652
|
+
let cachedFrame;
|
|
653
|
+
if (!this.isVirtualLayouting) {
|
|
654
|
+
cachedFrame = this._frameCache;
|
|
655
|
+
} else {
|
|
656
|
+
cachedFrame = this._frameCacheForVirtualLayouting;
|
|
657
|
+
}
|
|
658
|
+
result = cachedFrame != null ? cachedFrame : new import_UIRectangle.UIRectangle(
|
|
653
659
|
0,
|
|
654
660
|
0,
|
|
655
661
|
(_b = (_a = this._resizeObserverEntry) == null ? void 0 : _a.contentRect.height) != null ? _b : this.viewHTMLElement.offsetHeight,
|
|
656
662
|
(_d = (_c = this._resizeObserverEntry) == null ? void 0 : _c.contentRect.width) != null ? _d : this.viewHTMLElement.offsetWidth
|
|
657
663
|
);
|
|
658
|
-
this.
|
|
664
|
+
if (!this.isVirtualLayouting && this.isMemberOfViewTree && this.viewHTMLElement.isConnected) {
|
|
665
|
+
this._frameCache = result;
|
|
666
|
+
} else if (this.isMemberOfViewTree && this.viewHTMLElement.isConnected) {
|
|
667
|
+
this._frameCacheForVirtualLayouting = result;
|
|
668
|
+
}
|
|
659
669
|
} else {
|
|
660
670
|
let frame;
|
|
661
671
|
if (!this.isVirtualLayouting) {
|
|
662
672
|
frame = this.frame;
|
|
663
673
|
} else {
|
|
664
|
-
frame = (
|
|
674
|
+
frame = (_e = this._frameForVirtualLayouting) != null ? _e : this.frame;
|
|
665
675
|
}
|
|
666
676
|
result = frame.copy();
|
|
667
677
|
result.x = 0;
|
|
@@ -682,6 +692,7 @@ const _UIView = class extends import_UIObject.UIObject {
|
|
|
682
692
|
didResize(entry) {
|
|
683
693
|
this._resizeObserverEntry = entry;
|
|
684
694
|
this._frameCache = void 0;
|
|
695
|
+
this._frameCacheForVirtualLayouting = void 0;
|
|
685
696
|
this.setNeedsLayout();
|
|
686
697
|
this.boundsDidChange(new import_UIRectangle.UIRectangle(0, 0, entry.contentRect.height, entry.contentRect.width));
|
|
687
698
|
}
|
|
@@ -2327,6 +2338,8 @@ const _UIView = class extends import_UIObject.UIObject {
|
|
|
2327
2338
|
clearIntrinsicSizeCache() {
|
|
2328
2339
|
var _a;
|
|
2329
2340
|
this._intrinsicSizesCache = {};
|
|
2341
|
+
this._frameCacheForVirtualLayouting = void 0;
|
|
2342
|
+
this._frameCache = void 0;
|
|
2330
2343
|
if ((_a = this.superview) == null ? void 0 : _a.usesVirtualLayoutingForIntrinsicSizing) {
|
|
2331
2344
|
this.superview.clearIntrinsicSizeCache();
|
|
2332
2345
|
}
|