bobe 0.0.59 → 0.0.61
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/dist/bobe.cjs.js +142 -27
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.compiler.cjs.js +142 -27
- package/dist/bobe.compiler.cjs.js.map +1 -1
- package/dist/bobe.compiler.esm.js +142 -27
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +142 -27
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +18 -5
- package/dist/index.umd.js +142 -27
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.esm.js
CHANGED
|
@@ -33,15 +33,15 @@ let FakeType = function (FakeType) {
|
|
|
33
33
|
FakeType[FakeType["ForItem"] = 64] = "ForItem";
|
|
34
34
|
FakeType[FakeType["Context"] = 128] = "Context";
|
|
35
35
|
FakeType[FakeType["DynamicText"] = 256] = "DynamicText";
|
|
36
|
+
FakeType[FakeType["Tp"] = 512] = "Tp";
|
|
36
37
|
return FakeType;
|
|
37
38
|
}({});
|
|
38
39
|
const CondBit = FakeType.If | FakeType.Fail | FakeType.Else;
|
|
39
|
-
const LogicalBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem;
|
|
40
40
|
const CtxProviderBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment | FakeType.DynamicText;
|
|
41
|
-
const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context;
|
|
41
|
+
const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context | FakeType.Tp;
|
|
42
42
|
const TokenizerSwitcherBit = FakeType.Component | FakeType.Fragment;
|
|
43
43
|
let NodeSort = function (NodeSort) {
|
|
44
|
-
NodeSort[NodeSort["
|
|
44
|
+
NodeSort[NodeSort["EffectNode"] = 1] = "EffectNode";
|
|
45
45
|
NodeSort[NodeSort["Real"] = 2] = "Real";
|
|
46
46
|
NodeSort[NodeSort["Component"] = 4] = "Component";
|
|
47
47
|
NodeSort[NodeSort["CtxProvider"] = 8] = "CtxProvider";
|
|
@@ -54,6 +54,7 @@ let NodeSort = function (NodeSort) {
|
|
|
54
54
|
TerpEvt["HandledComponentNode"] = "handled-component-node";
|
|
55
55
|
return TerpEvt;
|
|
56
56
|
})({});
|
|
57
|
+
const FakeNode = Symbol('fake-node');
|
|
57
58
|
let ParseErrorCode = function (ParseErrorCode) {
|
|
58
59
|
ParseErrorCode[ParseErrorCode["UNCLOSED_BRACE"] = 9001] = "UNCLOSED_BRACE";
|
|
59
60
|
ParseErrorCode[ParseErrorCode["UNCLOSED_STRING"] = 9002] = "UNCLOSED_STRING";
|
|
@@ -1429,6 +1430,14 @@ class InlineFragment {
|
|
|
1429
1430
|
}
|
|
1430
1431
|
const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
|
|
1431
1432
|
const isRenderAble = val => isStore(val) || isUI(val) || val instanceof InlineFragment;
|
|
1433
|
+
const SAFE_HANDLER = {
|
|
1434
|
+
has: () => true,
|
|
1435
|
+
get: (t, k) => {
|
|
1436
|
+
if (typeof k === 'symbol') return t[k];
|
|
1437
|
+
return k in t ? t[k] : undefined;
|
|
1438
|
+
}
|
|
1439
|
+
};
|
|
1440
|
+
const safe = data => new Proxy(data, SAFE_HANDLER);
|
|
1432
1441
|
|
|
1433
1442
|
const KEY_INDEX = '__BOBE_KEY_INDEX';
|
|
1434
1443
|
let _ctxStack;
|
|
@@ -1440,9 +1449,6 @@ class Interpreter {
|
|
|
1440
1449
|
constructor(tokenizer) {
|
|
1441
1450
|
this.tokenizer = tokenizer;
|
|
1442
1451
|
}
|
|
1443
|
-
isLogicNode(node) {
|
|
1444
|
-
return node && node.__logicType & LogicalBit;
|
|
1445
|
-
}
|
|
1446
1452
|
rootComponent = null;
|
|
1447
1453
|
program(root, componentNode, before, ctxProvider) {
|
|
1448
1454
|
this.rootComponent = componentNode;
|
|
@@ -1461,7 +1467,7 @@ class Interpreter {
|
|
|
1461
1467
|
stack.push({
|
|
1462
1468
|
node: ctxProvider,
|
|
1463
1469
|
prev: null
|
|
1464
|
-
}, (ctxProvider.__logicType
|
|
1470
|
+
}, (ctxProvider.__logicType && ctxProvider.effect ? NodeSort.EffectNode : 0) | NodeSort.CtxProvider);
|
|
1465
1471
|
}
|
|
1466
1472
|
const rootLen = stack.length;
|
|
1467
1473
|
const ctx = this.ctx = {
|
|
@@ -1484,18 +1490,22 @@ class Interpreter {
|
|
|
1484
1490
|
const token = this.tokenizer.token;
|
|
1485
1491
|
if (token.type & TokenType.Indent) {
|
|
1486
1492
|
this.tokenizer.nextToken();
|
|
1487
|
-
const
|
|
1493
|
+
const isEffectNode = ctx.current && ctx.current.__logicType && ctx.current.effect;
|
|
1488
1494
|
stack.push({
|
|
1489
1495
|
node: ctx.current,
|
|
1490
1496
|
prev: ctx.prevSibling
|
|
1491
|
-
}, !ctx.current.__logicType ? NodeSort.Real : (
|
|
1497
|
+
}, !ctx.current.__logicType ? NodeSort.Real : (isEffectNode ? NodeSort.EffectNode : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType & ContextBit ? NodeSort.Context : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | (ctx.current.__logicType & CtxProviderBit ? NodeSort.CtxProvider : 0));
|
|
1492
1498
|
if (ctx.current.__logicType) {
|
|
1493
1499
|
this.beforeLogicIndent?.(ctx.current);
|
|
1494
|
-
if (
|
|
1500
|
+
if (isEffectNode) {
|
|
1495
1501
|
setPulling(ctx.current.effect);
|
|
1496
1502
|
if (ctx.current.__logicType & FakeType.ForItem) {
|
|
1497
1503
|
ctx.prevSibling = ctx.current.realBefore;
|
|
1498
1504
|
}
|
|
1505
|
+
if (ctx.current.__logicType & FakeType.Tp) {
|
|
1506
|
+
ctx.realParent = ctx.current.tpData[Keys.Raw].node;
|
|
1507
|
+
ctx.prevSibling = ctx.current.contentBefore;
|
|
1508
|
+
}
|
|
1499
1509
|
}
|
|
1500
1510
|
} else {
|
|
1501
1511
|
if (ctx.current) {
|
|
@@ -1531,14 +1541,17 @@ class Interpreter {
|
|
|
1531
1541
|
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
1532
1542
|
ctx.realParent = prevSameType?.node || root;
|
|
1533
1543
|
} else {
|
|
1534
|
-
if (sort & NodeSort.
|
|
1535
|
-
const parentLogic = stack.peekByType(NodeSort.
|
|
1544
|
+
if (sort & NodeSort.EffectNode) {
|
|
1545
|
+
const parentLogic = stack.peekByType(NodeSort.EffectNode)?.node;
|
|
1536
1546
|
if (parentLogic) {
|
|
1537
1547
|
setPulling(parentLogic.effect);
|
|
1538
1548
|
} else {
|
|
1539
1549
|
setPulling(rootPulling);
|
|
1540
1550
|
}
|
|
1541
1551
|
}
|
|
1552
|
+
if (parent.__logicType === FakeType.Tp) {
|
|
1553
|
+
ctx.realParent = parent.realParent;
|
|
1554
|
+
}
|
|
1542
1555
|
if (sort & NodeSort.TokenizerSwitcher) {
|
|
1543
1556
|
const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
|
|
1544
1557
|
if (parent.resumeSnapshot) {
|
|
@@ -1575,13 +1588,17 @@ class Interpreter {
|
|
|
1575
1588
|
}
|
|
1576
1589
|
return componentNode;
|
|
1577
1590
|
}
|
|
1578
|
-
insertAnchor(name = 'anchor', isBefore = false) {
|
|
1591
|
+
insertAnchor(node, name = 'anchor', isBefore = false) {
|
|
1579
1592
|
const _this$ctx = this.ctx,
|
|
1580
1593
|
realParent = _this$ctx.realParent,
|
|
1581
1594
|
prevSibling = _this$ctx.prevSibling,
|
|
1582
1595
|
stack = _this$ctx.stack,
|
|
1583
1596
|
before = _this$ctx.before;
|
|
1597
|
+
_this$ctx.current;
|
|
1584
1598
|
const afterAnchor = this.createAnchor(name, isBefore);
|
|
1599
|
+
if (!isBefore) {
|
|
1600
|
+
this.anchorRefBack(afterAnchor, node);
|
|
1601
|
+
}
|
|
1585
1602
|
this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
|
|
1586
1603
|
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
1587
1604
|
return afterAnchor;
|
|
@@ -1626,6 +1643,8 @@ class Interpreter {
|
|
|
1626
1643
|
return this.condDeclaration(ctx);
|
|
1627
1644
|
} else if (value === 'context') {
|
|
1628
1645
|
_node = this.createContextNode();
|
|
1646
|
+
} else if (value === 'tp') {
|
|
1647
|
+
return this.createTpNode();
|
|
1629
1648
|
} else if (value === 'for') {
|
|
1630
1649
|
return this.forDeclaration();
|
|
1631
1650
|
} else if (hookType) {
|
|
@@ -1665,11 +1684,11 @@ class Interpreter {
|
|
|
1665
1684
|
effect: null,
|
|
1666
1685
|
textNode: null,
|
|
1667
1686
|
owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
|
|
1668
|
-
snapshot: this.tokenizer.snapshot(['dentStack']),
|
|
1687
|
+
snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
|
|
1669
1688
|
parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
|
|
1670
1689
|
};
|
|
1671
1690
|
let isUpdate = false;
|
|
1672
|
-
node.realAfter = this.insertAnchor(`dynamic-after`);
|
|
1691
|
+
node.realAfter = this.insertAnchor(node, `dynamic-after`);
|
|
1673
1692
|
node.effect = this.effect(({
|
|
1674
1693
|
old,
|
|
1675
1694
|
val
|
|
@@ -1678,7 +1697,7 @@ class Interpreter {
|
|
|
1678
1697
|
oldTextNode = node.textNode;
|
|
1679
1698
|
if (oldLogicType) {
|
|
1680
1699
|
this.removeLogicNode(node);
|
|
1681
|
-
pickInPlace(node, ['realParent', 'realBefore', 'realAfter'
|
|
1700
|
+
pickInPlace(node, ['realParent', 'realBefore', 'realAfter', 'owner', 'snapshot', 'parentDataProvider']);
|
|
1682
1701
|
}
|
|
1683
1702
|
if (isRenderAble(val)) {
|
|
1684
1703
|
if (oldTextNode) {
|
|
@@ -1708,7 +1727,7 @@ class Interpreter {
|
|
|
1708
1727
|
}
|
|
1709
1728
|
if (isUpdate) {
|
|
1710
1729
|
this.tokenizer.useDedentAsEof = false;
|
|
1711
|
-
this.program(node.realParent, node
|
|
1730
|
+
this.program(node.realParent, node, node.realBefore);
|
|
1712
1731
|
} else {
|
|
1713
1732
|
this.tokenizer.useDedentAsEof = true;
|
|
1714
1733
|
this.tokenizer.initIndentWhenUseDedentAsEof();
|
|
@@ -1749,6 +1768,93 @@ class Interpreter {
|
|
|
1749
1768
|
});
|
|
1750
1769
|
return node;
|
|
1751
1770
|
}
|
|
1771
|
+
createTpNode() {
|
|
1772
|
+
const child = deepSignal({}, getPulling());
|
|
1773
|
+
const node = {
|
|
1774
|
+
__logicType: FakeType.Tp,
|
|
1775
|
+
data: this.getData(),
|
|
1776
|
+
realParent: null,
|
|
1777
|
+
realBefore: null,
|
|
1778
|
+
realAfter: null,
|
|
1779
|
+
contentBefore: null,
|
|
1780
|
+
contentAfter: null,
|
|
1781
|
+
effect: null,
|
|
1782
|
+
snapshot: null,
|
|
1783
|
+
tpData: child,
|
|
1784
|
+
owner: this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node
|
|
1785
|
+
};
|
|
1786
|
+
this.onePropParsed = createStoreOnePropParsed(child);
|
|
1787
|
+
this.tokenizer.nextToken();
|
|
1788
|
+
this.headerLineAndExtensions(node);
|
|
1789
|
+
this.onePropParsed = this.oneRealPropParsed;
|
|
1790
|
+
node.realAfter = this.insertAnchor(node, 'tp-after');
|
|
1791
|
+
const before = node.contentBefore = this.createAnchor('tp-content-before', true);
|
|
1792
|
+
const after = node.contentAfter = this.createAnchor('tp-content-after', true);
|
|
1793
|
+
let firstRender = true;
|
|
1794
|
+
node.effect = this.effect(({
|
|
1795
|
+
old: oldDom,
|
|
1796
|
+
val: dom
|
|
1797
|
+
}) => {
|
|
1798
|
+
const removeTpChild = () => {
|
|
1799
|
+
if (oldDom) {
|
|
1800
|
+
let point = before;
|
|
1801
|
+
do {
|
|
1802
|
+
const next = this.nextSib(point);
|
|
1803
|
+
this.remove(point, oldDom, null);
|
|
1804
|
+
if (point === after) break;
|
|
1805
|
+
point = next;
|
|
1806
|
+
} while (true);
|
|
1807
|
+
}
|
|
1808
|
+
};
|
|
1809
|
+
if (firstRender) {
|
|
1810
|
+
if (dom) {
|
|
1811
|
+
this.handleInsert(dom, after, null);
|
|
1812
|
+
this.handleInsert(dom, before, null);
|
|
1813
|
+
} else {
|
|
1814
|
+
if (this.tokenizer.token.type === TokenType.Indent) {
|
|
1815
|
+
const dentLen = this.tokenizer.dentStack[this.tokenizer.dentStack.length - 2] ?? 0;
|
|
1816
|
+
this.tokenizer.skip(dentLen);
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
} else {
|
|
1820
|
+
if (dom) {
|
|
1821
|
+
if (oldDom) {
|
|
1822
|
+
let point = before,
|
|
1823
|
+
lastInsert = null;
|
|
1824
|
+
do {
|
|
1825
|
+
const next = this.nextSib(point);
|
|
1826
|
+
const fakeNode = point[FakeNode];
|
|
1827
|
+
if (fakeNode) {
|
|
1828
|
+
fakeNode.realParent = dom;
|
|
1829
|
+
}
|
|
1830
|
+
this.handleInsert(dom, point, lastInsert);
|
|
1831
|
+
if (point === after) break;
|
|
1832
|
+
lastInsert = point;
|
|
1833
|
+
point = next;
|
|
1834
|
+
} while (true);
|
|
1835
|
+
} else {
|
|
1836
|
+
this.handleInsert(dom, after, null);
|
|
1837
|
+
this.handleInsert(dom, before, null);
|
|
1838
|
+
this.tokenizer = node.owner.tokenizer;
|
|
1839
|
+
this.tokenizer.resume(node.snapshot);
|
|
1840
|
+
this.tokenizer.useDedentAsEof = false;
|
|
1841
|
+
this.program(dom, node.owner, before, node);
|
|
1842
|
+
}
|
|
1843
|
+
} else {
|
|
1844
|
+
removeTpChild();
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
firstRender = false;
|
|
1848
|
+
return isDestroy => {
|
|
1849
|
+
if (isDestroy) {
|
|
1850
|
+
removeTpChild();
|
|
1851
|
+
}
|
|
1852
|
+
};
|
|
1853
|
+
}, [() => child.node], {
|
|
1854
|
+
type: 'render'
|
|
1855
|
+
});
|
|
1856
|
+
return node;
|
|
1857
|
+
}
|
|
1752
1858
|
createContextNode() {
|
|
1753
1859
|
const child = deepSignal({}, getPulling());
|
|
1754
1860
|
const parentContext = this.ctx.stack.peekByType(NodeSort.Context)?.node?.context;
|
|
@@ -1763,7 +1869,7 @@ class Interpreter {
|
|
|
1763
1869
|
realBefore: null,
|
|
1764
1870
|
realAfter: null
|
|
1765
1871
|
};
|
|
1766
|
-
node.realAfter = this.insertAnchor('context-after');
|
|
1872
|
+
node.realAfter = this.insertAnchor(node, 'context-after');
|
|
1767
1873
|
return node;
|
|
1768
1874
|
}
|
|
1769
1875
|
formatForCollection(collection) {
|
|
@@ -1853,15 +1959,15 @@ class Interpreter {
|
|
|
1853
1959
|
i: 0
|
|
1854
1960
|
};
|
|
1855
1961
|
if (keyExp) {
|
|
1856
|
-
|
|
1962
|
+
const rawGetKey = new Function('data', `with(data){return (${keyExp})}`);
|
|
1963
|
+
forNode.getKey = data => rawGetKey(safe(data));
|
|
1857
1964
|
}
|
|
1858
|
-
window['for1'] = forNode;
|
|
1859
1965
|
const data = this.getData();
|
|
1860
1966
|
const cells = data[Keys.Meta].cells;
|
|
1861
1967
|
const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
|
|
1862
1968
|
const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new Computed(this.getFn(data, arrExp));
|
|
1863
1969
|
forNode.arrSignal = arrSignal;
|
|
1864
|
-
forNode.realAfter = this.insertAnchor('for-after');
|
|
1970
|
+
forNode.realAfter = this.insertAnchor(forNode, 'for-after');
|
|
1865
1971
|
const _forNode$snapshot = forNode.snapshot;
|
|
1866
1972
|
_forNode$snapshot.dentStack;
|
|
1867
1973
|
_forNode$snapshot.isFirstToken;
|
|
@@ -1884,8 +1990,8 @@ class Interpreter {
|
|
|
1884
1990
|
const len = arr.length;
|
|
1885
1991
|
for (let i = len; i--;) {
|
|
1886
1992
|
const item = this.createForItem(forNode, i, data);
|
|
1887
|
-
item.realAfter = this.insertAnchor('for-item-after');
|
|
1888
|
-
item.realBefore = this.insertAnchor('for-item-before', true);
|
|
1993
|
+
item.realAfter = this.insertAnchor(item, 'for-item-after');
|
|
1994
|
+
item.realBefore = this.insertAnchor(item, 'for-item-before', true);
|
|
1889
1995
|
item.realParent = forNode.realParent;
|
|
1890
1996
|
children[i] = item;
|
|
1891
1997
|
}
|
|
@@ -2047,10 +2153,14 @@ class Interpreter {
|
|
|
2047
2153
|
}, ScheduleType.Render);
|
|
2048
2154
|
return forNode.children[0] || forNode;
|
|
2049
2155
|
}
|
|
2156
|
+
anchorRefBack(anchor, node) {
|
|
2157
|
+
anchor[FakeNode] = node;
|
|
2158
|
+
}
|
|
2050
2159
|
insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
|
|
2051
2160
|
const item = this.createForItem(forNode, i, parentData);
|
|
2052
2161
|
newChildren[i] = item;
|
|
2053
2162
|
let realAfter = this.createAnchor('for-item-after');
|
|
2163
|
+
this.anchorRefBack(realAfter, item);
|
|
2054
2164
|
this.handleInsert(forNode.realParent, realAfter, before);
|
|
2055
2165
|
let realBefore = this.createAnchor('for-item-before', true);
|
|
2056
2166
|
this.handleInsert(forNode.realParent, realBefore, before);
|
|
@@ -2221,11 +2331,11 @@ class Interpreter {
|
|
|
2221
2331
|
resumeSnapshot
|
|
2222
2332
|
};
|
|
2223
2333
|
this.onePropParsed = onePropParsed;
|
|
2224
|
-
node.realAfter = this.insertAnchor('component-after');
|
|
2334
|
+
node.realAfter = this.insertAnchor(node, 'component-after');
|
|
2225
2335
|
return node;
|
|
2226
2336
|
}
|
|
2227
2337
|
getFn(data, expression) {
|
|
2228
|
-
return new Function('data', `
|
|
2338
|
+
return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
|
|
2229
2339
|
}
|
|
2230
2340
|
getAssignFn(data, expression) {
|
|
2231
2341
|
const valueId = `value_bobe_${date32()}`;
|
|
@@ -2316,7 +2426,7 @@ class Interpreter {
|
|
|
2316
2426
|
break;
|
|
2317
2427
|
}
|
|
2318
2428
|
ifNode.condition = signal;
|
|
2319
|
-
ifNode.realAfter = this.insertAnchor(`${keyWord.value}-after`);
|
|
2429
|
+
ifNode.realAfter = this.insertAnchor(ifNode, `${keyWord.value}-after`);
|
|
2320
2430
|
const ef = this.effect(({
|
|
2321
2431
|
val
|
|
2322
2432
|
}) => {
|
|
@@ -2359,10 +2469,11 @@ class Interpreter {
|
|
|
2359
2469
|
const tokenizer = this.tokenizer;
|
|
2360
2470
|
do {
|
|
2361
2471
|
const isComponent = _node.__logicType & TokenizerSwitcherBit;
|
|
2472
|
+
const isTp = _node.__logicType === FakeType.Tp;
|
|
2362
2473
|
let snapshot, dentLen;
|
|
2363
2474
|
const data = this.getData();
|
|
2364
2475
|
const unHandledKey = this.attributeList(_node, data);
|
|
2365
|
-
if (isComponent) {
|
|
2476
|
+
if (isComponent || isTp) {
|
|
2366
2477
|
snapshot = tokenizer.snapshot(undefined, -1);
|
|
2367
2478
|
dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
|
|
2368
2479
|
}
|
|
@@ -2374,6 +2485,9 @@ class Interpreter {
|
|
|
2374
2485
|
if ((tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
2375
2486
|
break;
|
|
2376
2487
|
}
|
|
2488
|
+
} else if (isTp) {
|
|
2489
|
+
_node.snapshot = snapshot;
|
|
2490
|
+
break;
|
|
2377
2491
|
} else {
|
|
2378
2492
|
break;
|
|
2379
2493
|
}
|
|
@@ -2575,6 +2689,7 @@ function bobe(fragments, ...values) {
|
|
|
2575
2689
|
return tokenizer;
|
|
2576
2690
|
};
|
|
2577
2691
|
ui.boundStore = Store.Current;
|
|
2692
|
+
ui[Keys.ProxyFreeObject] = true;
|
|
2578
2693
|
ui.__BOBE_IS_UI = true;
|
|
2579
2694
|
return ui;
|
|
2580
2695
|
}
|