@sapui5/sap.fe.core 1.95.0 → 1.98.0

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.
Files changed (207) hide show
  1. package/package.json +5 -5
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +3 -3
  4. package/src/sap/fe/core/AppComponent.js +9 -44
  5. package/src/sap/fe/core/AppStateHandler.js +2 -2
  6. package/src/sap/fe/core/BaseController.js +1 -1
  7. package/src/sap/fe/core/BusyLocker.js +13 -1
  8. package/src/sap/fe/core/CommonUtils.js +129 -219
  9. package/src/sap/fe/core/ExtensionAPI.js +14 -6
  10. package/src/sap/fe/core/PageController.js +9 -35
  11. package/src/sap/fe/core/RouterProxy.js +79 -75
  12. package/src/sap/fe/core/Synchronization.js +1 -1
  13. package/src/sap/fe/core/TemplateComponent.js +16 -7
  14. package/src/sap/fe/core/TemplateModel.js +1 -1
  15. package/src/sap/fe/core/TransactionHelper.js +183 -65
  16. package/src/sap/fe/core/actions/draft.js +50 -23
  17. package/src/sap/fe/core/actions/messageHandling.js +86 -7
  18. package/src/sap/fe/core/actions/nonDraft.js +1 -1
  19. package/src/sap/fe/core/actions/operations.js +75 -33
  20. package/src/sap/fe/core/actions/sticky.js +1 -1
  21. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +1 -1
  22. package/src/sap/fe/core/controllerextensions/EditFlow.js +276 -122
  23. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +1 -1
  24. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +14 -6
  25. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +90 -46
  26. package/src/sap/fe/core/controllerextensions/InternalRouting.js +234 -232
  27. package/src/sap/fe/core/controllerextensions/KPIManagement.js +539 -209
  28. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +550 -213
  29. package/src/sap/fe/core/controllerextensions/MassEdit.js +79 -0
  30. package/src/sap/fe/core/controllerextensions/MessageHandler.js +227 -103
  31. package/src/sap/fe/core/controllerextensions/PageReady.js +2 -2
  32. package/src/sap/fe/core/controllerextensions/PageReady.ts +3 -7
  33. package/src/sap/fe/core/controllerextensions/Paginator.js +38 -12
  34. package/src/sap/fe/core/controllerextensions/Placeholder.js +16 -19
  35. package/src/sap/fe/core/controllerextensions/Routing.js +17 -2
  36. package/src/sap/fe/core/controllerextensions/RoutingListener.js +1 -1
  37. package/src/sap/fe/core/controllerextensions/Share.js +20 -7
  38. package/src/sap/fe/core/controllerextensions/SideEffects.js +8 -9
  39. package/src/sap/fe/core/controllerextensions/SideEffects.ts +19 -17
  40. package/src/sap/fe/core/controllerextensions/ViewState.js +54 -9
  41. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +40 -34
  42. package/src/sap/fe/core/controls/ActionParameterDialogValueHelp.fragment.xml +35 -0
  43. package/src/sap/fe/core/controls/CommandExecution.js +1 -1
  44. package/src/sap/fe/core/controls/ConditionalWrapper.js +1 -1
  45. package/src/sap/fe/core/controls/CustomQuickViewPage.js +110 -109
  46. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +7 -4
  47. package/src/sap/fe/core/controls/FieldWrapper.js +10 -4
  48. package/src/sap/fe/core/controls/FilterBar.js +1 -1
  49. package/src/sap/fe/core/controls/FormElementWrapper.js +1 -6
  50. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +45 -0
  51. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +1 -1
  52. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +1 -1
  53. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +1 -1
  54. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +1 -1
  55. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +1 -1
  56. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +106 -0
  57. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +78 -0
  58. package/src/sap/fe/core/converters/ConverterContext.js +13 -1
  59. package/src/sap/fe/core/converters/ConverterContext.ts +10 -0
  60. package/src/sap/fe/core/converters/ManifestSettings.js +2 -1
  61. package/src/sap/fe/core/converters/ManifestSettings.ts +7 -1
  62. package/src/sap/fe/core/converters/ManifestWrapper.js +18 -7
  63. package/src/sap/fe/core/converters/ManifestWrapper.ts +15 -6
  64. package/src/sap/fe/core/converters/MetaModelConverter.js +920 -882
  65. package/src/sap/fe/core/converters/MetaModelConverter.ts +829 -853
  66. package/src/sap/fe/core/converters/annotations/DataField.js +54 -4
  67. package/src/sap/fe/core/converters/annotations/DataField.ts +53 -3
  68. package/src/sap/fe/core/converters/common/AnnotationConverter.js +83 -48
  69. package/src/sap/fe/core/converters/controls/Common/Action.js +15 -3
  70. package/src/sap/fe/core/converters/controls/Common/Action.ts +12 -3
  71. package/src/sap/fe/core/converters/controls/Common/Chart.js +1 -3
  72. package/src/sap/fe/core/converters/controls/Common/Chart.ts +0 -2
  73. package/src/sap/fe/core/converters/controls/Common/Form.js +68 -21
  74. package/src/sap/fe/core/converters/controls/Common/Form.ts +60 -16
  75. package/src/sap/fe/core/converters/controls/Common/KPI.js +331 -248
  76. package/src/sap/fe/core/converters/controls/Common/KPI.ts +355 -287
  77. package/src/sap/fe/core/converters/controls/Common/Table.js +426 -332
  78. package/src/sap/fe/core/converters/controls/Common/Table.ts +516 -383
  79. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +468 -0
  80. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +609 -0
  81. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +30 -13
  82. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +31 -12
  83. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +2 -2
  84. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +1 -1
  85. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +15 -7
  86. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +27 -6
  87. package/src/sap/fe/core/converters/helpers/Aggregation.js +8 -1
  88. package/src/sap/fe/core/converters/helpers/Aggregation.ts +9 -1
  89. package/src/sap/fe/core/converters/helpers/BindingHelper.js +3 -2
  90. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +2 -2
  91. package/src/sap/fe/core/converters/helpers/ID.js +9 -1
  92. package/src/sap/fe/core/converters/helpers/ID.ts +6 -2
  93. package/src/sap/fe/core/converters/helpers/IssueManager.js +7 -5
  94. package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -4
  95. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +2 -2
  96. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +1 -1
  97. package/src/sap/fe/core/converters/templates/ListReportConverter.js +34 -4
  98. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +36 -7
  99. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +2 -5
  100. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +1 -2
  101. package/src/sap/fe/core/designtime/AppComponent.designtime.js +11 -2
  102. package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
  103. package/src/sap/fe/core/formatters/FPMFormatter.ts +8 -3
  104. package/src/sap/fe/core/formatters/TableFormatter.js +27 -4
  105. package/src/sap/fe/core/formatters/TableFormatter.ts +20 -3
  106. package/src/sap/fe/core/formatters/ValueFormatter.js +30 -5
  107. package/src/sap/fe/core/formatters/ValueFormatter.ts +25 -3
  108. package/src/sap/fe/core/fpm/Component.js +2 -2
  109. package/src/sap/fe/core/helpers/AppStartupHelper.js +359 -0
  110. package/src/sap/fe/core/helpers/AppStartupHelper.ts +388 -0
  111. package/src/sap/fe/core/helpers/BindingExpression.js +199 -111
  112. package/src/sap/fe/core/helpers/BindingExpression.ts +193 -102
  113. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +1 -1
  114. package/src/sap/fe/core/helpers/EditState.js +1 -1
  115. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +1 -3
  116. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  117. package/src/sap/fe/core/helpers/KeepAliveHelper.js +211 -0
  118. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +202 -0
  119. package/src/sap/fe/core/helpers/KeepAliveRefreshTypes.js +32 -0
  120. package/src/sap/fe/core/helpers/KeepAliveRefreshTypes.ts +36 -0
  121. package/src/sap/fe/core/helpers/MassEditHelper.js +678 -0
  122. package/src/sap/fe/core/helpers/ModelHelper.js +64 -1
  123. package/src/sap/fe/core/helpers/PasteHelper.js +7 -1
  124. package/src/sap/fe/core/helpers/SemanticDateOperators.js +1 -1
  125. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
  126. package/src/sap/fe/core/helpers/StableIdHelper.js +2 -2
  127. package/src/sap/fe/core/helpers/StableIdHelper.ts +1 -1
  128. package/src/sap/fe/core/library.js +28 -2
  129. package/src/sap/fe/core/library.support.js +10 -4
  130. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +62 -0
  131. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +66 -0
  132. package/src/sap/fe/core/messagebundle.properties +67 -3
  133. package/src/sap/fe/core/messagebundle_ar.properties +40 -3
  134. package/src/sap/fe/core/messagebundle_bg.properties +40 -3
  135. package/src/sap/fe/core/messagebundle_ca.properties +41 -4
  136. package/src/sap/fe/core/messagebundle_cs.properties +41 -4
  137. package/src/sap/fe/core/messagebundle_cy.properties +40 -3
  138. package/src/sap/fe/core/messagebundle_da.properties +40 -3
  139. package/src/sap/fe/core/messagebundle_de.properties +40 -3
  140. package/src/sap/fe/core/messagebundle_el.properties +40 -3
  141. package/src/sap/fe/core/messagebundle_en.properties +37 -0
  142. package/src/sap/fe/core/messagebundle_en_GB.properties +37 -0
  143. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +37 -0
  144. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +46 -2
  145. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +44 -0
  146. package/src/sap/fe/core/messagebundle_es.properties +40 -3
  147. package/src/sap/fe/core/messagebundle_es_MX.properties +41 -4
  148. package/src/sap/fe/core/messagebundle_et.properties +40 -3
  149. package/src/sap/fe/core/messagebundle_fi.properties +40 -3
  150. package/src/sap/fe/core/messagebundle_fr.properties +41 -4
  151. package/src/sap/fe/core/messagebundle_fr_CA.properties +40 -3
  152. package/src/sap/fe/core/messagebundle_hi.properties +40 -3
  153. package/src/sap/fe/core/messagebundle_hr.properties +40 -3
  154. package/src/sap/fe/core/messagebundle_hu.properties +41 -4
  155. package/src/sap/fe/core/messagebundle_id.properties +42 -5
  156. package/src/sap/fe/core/messagebundle_it.properties +40 -3
  157. package/src/sap/fe/core/messagebundle_iw.properties +40 -3
  158. package/src/sap/fe/core/messagebundle_ja.properties +49 -12
  159. package/src/sap/fe/core/messagebundle_kk.properties +40 -3
  160. package/src/sap/fe/core/messagebundle_ko.properties +40 -3
  161. package/src/sap/fe/core/messagebundle_lt.properties +40 -3
  162. package/src/sap/fe/core/messagebundle_lv.properties +40 -3
  163. package/src/sap/fe/core/messagebundle_ms.properties +40 -3
  164. package/src/sap/fe/core/messagebundle_nl.properties +40 -3
  165. package/src/sap/fe/core/messagebundle_no.properties +40 -3
  166. package/src/sap/fe/core/messagebundle_pl.properties +40 -3
  167. package/src/sap/fe/core/messagebundle_pt.properties +42 -5
  168. package/src/sap/fe/core/messagebundle_pt_PT.properties +40 -3
  169. package/src/sap/fe/core/messagebundle_ro.properties +40 -3
  170. package/src/sap/fe/core/messagebundle_ru.properties +40 -3
  171. package/src/sap/fe/core/messagebundle_sh.properties +40 -3
  172. package/src/sap/fe/core/messagebundle_sk.properties +40 -3
  173. package/src/sap/fe/core/messagebundle_sl.properties +40 -3
  174. package/src/sap/fe/core/messagebundle_sv.properties +41 -4
  175. package/src/sap/fe/core/messagebundle_th.properties +40 -3
  176. package/src/sap/fe/core/messagebundle_tr.properties +40 -3
  177. package/src/sap/fe/core/messagebundle_uk.properties +40 -3
  178. package/src/sap/fe/core/messagebundle_vi.properties +40 -3
  179. package/src/sap/fe/core/messagebundle_zh_CN.properties +40 -3
  180. package/src/sap/fe/core/messagebundle_zh_TW.properties +40 -3
  181. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +1 -1
  182. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +1 -1
  183. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +4 -3
  184. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +3 -0
  185. package/src/sap/fe/core/services/NavigationServiceFactory.js +1 -1
  186. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +1 -1
  187. package/src/sap/fe/core/services/RoutingServiceFactory.js +98 -328
  188. package/src/sap/fe/core/services/ShellServicesFactory.js +31 -2
  189. package/src/sap/fe/core/services/ShellServicesFactory.ts +30 -1
  190. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +8 -5
  191. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +11 -6
  192. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +14 -5
  193. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +1 -1
  194. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +38 -0
  195. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
  196. package/src/sap/fe/core/templating/DataModelPathHelper.js +8 -37
  197. package/src/sap/fe/core/templating/DataModelPathHelper.ts +13 -33
  198. package/src/sap/fe/core/templating/DisplayModeFormatter.js +114 -0
  199. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +86 -0
  200. package/src/sap/fe/core/templating/EntitySetHelper.js +86 -3
  201. package/src/sap/fe/core/templating/EntitySetHelper.ts +44 -0
  202. package/src/sap/fe/core/templating/FilterHelper.js +10 -7
  203. package/src/sap/fe/core/templating/FilterHelper.ts +8 -6
  204. package/src/sap/fe/core/templating/PropertyHelper.js +2 -2
  205. package/src/sap/fe/core/templating/PropertyHelper.ts +1 -1
  206. package/src/sap/fe/core/templating/UIFormatters.js +47 -107
  207. package/src/sap/fe/core/templating/UIFormatters.ts +76 -72
@@ -87,6 +87,11 @@ export type ConcatExpression = BaseExpression<string> & {
87
87
  expressions: Expression<string>[];
88
88
  };
89
89
 
90
+ export type LengthExpression = BaseExpression<string> & {
91
+ _type: "Length";
92
+ bindingExpression: BindingExpressionExpression<any>;
93
+ };
94
+
90
95
  export type UnresolveableBindingExpression = BaseExpression<string> & {
91
96
  _type: "Unresolveable";
92
97
  };
@@ -154,6 +159,7 @@ export type Expression<T> =
154
159
  | NotExpression
155
160
  | TruthyExpression
156
161
  | ConcatExpression
162
+ | LengthExpression
157
163
  | BindingExpressionExpression<T>
158
164
  | EmbeddedBindingExpression<T>
159
165
  | EmbeddedExpressionBindingExpression<T>
@@ -245,6 +251,9 @@ export function _checkExpressionsAreEqual<T>(a: Expression<T>, b: Expression<T>)
245
251
  return _checkExpressionsAreEqual(expression, bExpressions[index]);
246
252
  });
247
253
 
254
+ case "Length":
255
+ return _checkExpressionsAreEqual(a.bindingExpression, (b as LengthExpression).bindingExpression);
256
+
248
257
  case "Binding":
249
258
  return (
250
259
  a.modelName === (b as BindingExpressionExpression<T>).modelName &&
@@ -989,6 +998,16 @@ function comparison<T extends PrimitiveType>(
989
998
  }
990
999
  }
991
1000
 
1001
+ export function length(bindingExpression: BindingExpressionExpression<any> | UnresolveableBindingExpression): Expression<number> {
1002
+ if (bindingExpression._type === "Unresolveable") {
1003
+ return bindingExpression;
1004
+ }
1005
+ return {
1006
+ _type: "Length",
1007
+ bindingExpression
1008
+ };
1009
+ }
1010
+
992
1011
  /**
993
1012
  * Comparison: "equal" (===).
994
1013
  *
@@ -1013,6 +1032,9 @@ export function equal<T extends PrimitiveType>(
1013
1032
  // ((a === c) === true) => (a === c)
1014
1033
  if (leftExpression._type === "Comparison" && isConstant(rightExpression) && rightExpression.value === true) {
1015
1034
  return leftExpression;
1035
+ } else if (rightExpression._type === "Comparison" && isConstant(leftExpression) && leftExpression.value === true) {
1036
+ // (true === (a === c)) => (a === c)
1037
+ return rightExpression;
1016
1038
  } else if (leftExpression._type === "Comparison" && isConstant(rightExpression) && rightExpression.value === true) {
1017
1039
  // ((a === c) === false) => !(a === c)
1018
1040
  return not(leftExpression);
@@ -1500,6 +1522,7 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1500
1522
  break;
1501
1523
  case "DefaultBinding":
1502
1524
  case "Ref":
1525
+ case "Length":
1503
1526
  case "Binding":
1504
1527
  case "Constant":
1505
1528
  // Do nothing
@@ -1513,6 +1536,135 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1513
1536
 
1514
1537
  export type BindingExpression<T> = T | string | undefined;
1515
1538
 
1539
+ const needParenthesis = function<T extends PrimitiveType>(expr: ExpressionOrPrimitive<T>): boolean {
1540
+ return !isConstant(expr) && !isBinding(expr) && isExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
1541
+ };
1542
+
1543
+ /**
1544
+ * Compiles a constant object to a string.
1545
+ * @param expr
1546
+ * @param isNullable
1547
+ * @returns {string} The compiled string
1548
+ */
1549
+ function compileConstantObject<T>(expr: ConstantExpression<object>, isNullable = false) {
1550
+ if (isNullable && Object.keys(expr.value).length === 0) {
1551
+ return "";
1552
+ }
1553
+ // Objects
1554
+ const o = expr.value as PlainExpressionObject;
1555
+ const properties: string[] = [];
1556
+ Object.keys(o).forEach(key => {
1557
+ const value = o[key];
1558
+ const childResult = compileBinding(value, true, false, true);
1559
+ if (childResult && childResult.length > 0) {
1560
+ properties.push(`${key}: ${childResult}`);
1561
+ }
1562
+ });
1563
+ return `{${properties.join(", ")}}`;
1564
+ }
1565
+
1566
+ /**
1567
+ * Compiles a Constant Binding Expression.
1568
+ * @param expr
1569
+ * @param embeddedInBinding
1570
+ * @param isNullable
1571
+ * @returns {string} The compiled string
1572
+ */
1573
+ function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, embeddedInBinding: boolean, isNullable = false) {
1574
+ if (expr.value === null) {
1575
+ return "null";
1576
+ }
1577
+ if (expr.value === undefined) {
1578
+ return "undefined";
1579
+ }
1580
+ if (typeof expr.value === "object") {
1581
+ if (Array.isArray(expr.value)) {
1582
+ const entries = expr.value.map(expression => compileBinding(expression, true));
1583
+ return `[${entries.join(", ")}]`;
1584
+ } else {
1585
+ return compileConstantObject(expr as ConstantExpression<object>, isNullable);
1586
+ }
1587
+ }
1588
+
1589
+ if (embeddedInBinding) {
1590
+ switch (typeof expr.value) {
1591
+ case "number":
1592
+ case "bigint":
1593
+ case "boolean":
1594
+ return expr.value.toString();
1595
+ case "string":
1596
+ return `'${escapeXmlAttribute(expr.value.toString())}'`;
1597
+ default:
1598
+ return "";
1599
+ }
1600
+ } else {
1601
+ return expr.value.toString();
1602
+ }
1603
+ }
1604
+
1605
+ /**
1606
+ * Generates the binding string for a Binding expression.
1607
+ *
1608
+ * @param expressionForBinding The expression to compile
1609
+ * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1610
+ * @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
1611
+ * @returns {BindingExpression<T>} The corresponding expression binding
1612
+ */
1613
+ function compileBindingForBinding<T extends PrimitiveType>(
1614
+ expressionForBinding: BindingExpressionExpression<T> | DefaultBindingExpressionExpression<T>,
1615
+ embeddedInBinding: boolean,
1616
+ embeddedSeparator: string
1617
+ ) {
1618
+ if (
1619
+ expressionForBinding.type ||
1620
+ expressionForBinding.parameters ||
1621
+ expressionForBinding.targetType ||
1622
+ expressionForBinding.formatOptions ||
1623
+ expressionForBinding.constraints
1624
+ ) {
1625
+ // This is now a complex binding definition, let's prepare for it
1626
+ const complexBindingDefinition = {
1627
+ path: `${expressionForBinding.modelName ? expressionForBinding.modelName + ">" : ""}${expressionForBinding.path}`,
1628
+ type: expressionForBinding.type,
1629
+ targetType: expressionForBinding.targetType,
1630
+ parameters: expressionForBinding.parameters,
1631
+ formatOptions: expressionForBinding.formatOptions,
1632
+ constraints: expressionForBinding.constraints
1633
+ };
1634
+ let outBinding = compileBinding(complexBindingDefinition);
1635
+ if (embeddedInBinding) {
1636
+ outBinding = `${embeddedSeparator}` + outBinding;
1637
+ }
1638
+ return outBinding;
1639
+ } else if (embeddedInBinding) {
1640
+ return `${embeddedSeparator}{${expressionForBinding.modelName ? expressionForBinding.modelName + ">" : ""}${
1641
+ expressionForBinding.path
1642
+ }}`;
1643
+ } else {
1644
+ return `{${expressionForBinding.modelName ? expressionForBinding.modelName + ">" : ""}${expressionForBinding.path}}`;
1645
+ }
1646
+ }
1647
+
1648
+ /**
1649
+ * Wrap the compiled binding string as required dependening on its context.
1650
+ *
1651
+ * @param expression The compiled expression
1652
+ * @param embeddedInBinding True if the compiled expression is to be embedded in a binding
1653
+ * @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
1654
+ * @returns {BindingExpression<string>} Finalized compiled expression
1655
+ */
1656
+ function wrapBindingExpression(expression: string, embeddedInBinding: boolean, parenthesisRequired = false): BindingExpression<string> {
1657
+ if (embeddedInBinding) {
1658
+ if (parenthesisRequired) {
1659
+ return `(${expression})`;
1660
+ } else {
1661
+ return expression;
1662
+ }
1663
+ } else {
1664
+ return `{= ${expression}}`;
1665
+ }
1666
+ }
1667
+
1516
1668
  /**
1517
1669
  * Compile an expression into an expression binding.
1518
1670
  *
@@ -1520,12 +1672,14 @@ export type BindingExpression<T> = T | string | undefined;
1520
1672
  * @param expression The expression to compile
1521
1673
  * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1522
1674
  * @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
1675
+ * @param isNullable Whether binding expression can resolve to empty string or not
1523
1676
  * @returns {BindingExpression<T>} The corresponding expression binding
1524
1677
  */
1525
1678
  export function compileBinding<T extends PrimitiveType>(
1526
1679
  expression: ExpressionOrPrimitive<T>,
1527
- embeddedInBinding: boolean = false,
1528
- keepTargetType: boolean = false
1680
+ embeddedInBinding = false,
1681
+ keepTargetType = false,
1682
+ isNullable = false
1529
1683
  ): BindingExpression<string> {
1530
1684
  const expr = wrapPrimitive(expression);
1531
1685
  const embeddedSeparator = keepTargetType ? "$" : "%";
@@ -1534,41 +1688,7 @@ export function compileBinding<T extends PrimitiveType>(
1534
1688
  case "Unresolveable":
1535
1689
  return undefined;
1536
1690
  case "Constant":
1537
- if (expr.value === null) {
1538
- return "null";
1539
- }
1540
- if (expr.value === undefined) {
1541
- return "undefined";
1542
- }
1543
- if (typeof expr.value === "object") {
1544
- if (Array.isArray(expr.value)) {
1545
- const entries = expr.value.map(expression => compileBinding(expression, true));
1546
- return `[${entries.join(", ")}]`;
1547
- } else {
1548
- // Objects
1549
- const o = expr.value as PlainExpressionObject;
1550
- const properties = Object.keys(o).map(key => {
1551
- const value = o[key];
1552
- return `${key}: ${compileBinding(value, true)}`;
1553
- });
1554
- return `{${properties.join(", ")}}`;
1555
- }
1556
- }
1557
-
1558
- if (embeddedInBinding) {
1559
- switch (typeof expr.value) {
1560
- case "number":
1561
- case "bigint":
1562
- case "boolean":
1563
- return expr.value.toString();
1564
- case "string":
1565
- return `'${escapeXmlAttribute(expr.value.toString())}'`;
1566
- default:
1567
- return "";
1568
- }
1569
- } else {
1570
- return expr.value.toString();
1571
- }
1691
+ return compileConstant(expr, embeddedInBinding, isNullable);
1572
1692
 
1573
1693
  case "Ref":
1574
1694
  return expr.ref || "null";
@@ -1592,84 +1712,55 @@ export function compileBinding<T extends PrimitiveType>(
1592
1712
  }
1593
1713
  case "DefaultBinding":
1594
1714
  case "Binding":
1595
- if (expr.type || expr.parameters || expr.targetType) {
1596
- let outBinding = "";
1597
- if (embeddedInBinding) {
1598
- outBinding += `${embeddedSeparator}`;
1599
- }
1600
- outBinding += `{path:'${expr.modelName ? `${expr.modelName}>` : ""}${expr.path}'`;
1601
- if (expr.type) {
1602
- outBinding += `, type: '${expr.type}'`;
1603
- }
1604
- if (expr.constraints && Object.keys(expr.constraints).length > 0) {
1605
- outBinding += `, constraints: ${compileBinding(expr.constraints)}`;
1606
- }
1607
- if (expr.formatOptions) {
1608
- outBinding += `, formatOptions: ${compileBinding(expr.formatOptions)}`;
1609
- }
1610
- if (expr.parameters && Object.keys(expr.parameters).length > 0) {
1611
- outBinding += `, parameters: ${compileBinding(expr.parameters)}`;
1612
- }
1613
- if (expr.targetType) {
1614
- outBinding += `, targetType: '${expr.targetType}'`;
1615
- }
1616
- outBinding += "}";
1617
- return outBinding;
1618
- } else {
1619
- if (embeddedInBinding) {
1620
- return `${embeddedSeparator}{${expr.modelName ? `${expr.modelName}>` : ""}${expr.path}}`;
1621
- } else {
1622
- return `{${expr.modelName ? `${expr.modelName}>` : ""}${expr.path}}`;
1623
- }
1624
- }
1715
+ return compileBindingForBinding(expr, embeddedInBinding, embeddedSeparator);
1625
1716
 
1626
1717
  case "Comparison":
1627
- const comparisonPart = `${compileBinding(expr.operand1, true)} ${expr.operator} ${compileBinding(expr.operand2, true)}`;
1628
- if (embeddedInBinding) {
1629
- return comparisonPart;
1718
+ const isOperand1Complex = needParenthesis(expr.operand1);
1719
+ const isOperand2Complex = needParenthesis(expr.operand2);
1720
+ let comparisonPart = "";
1721
+ if (isOperand1Complex) {
1722
+ comparisonPart += "(";
1723
+ }
1724
+ comparisonPart += `${compileBinding(expr.operand1, true)}`;
1725
+ if (isOperand1Complex) {
1726
+ comparisonPart += ")";
1727
+ }
1728
+ comparisonPart += ` ${expr.operator} `;
1729
+ if (isOperand2Complex) {
1730
+ comparisonPart += "(";
1630
1731
  }
1631
- return `{= ${comparisonPart}}`;
1732
+ comparisonPart += `${compileBinding(expr.operand2, true)}`;
1733
+ if (isOperand2Complex) {
1734
+ comparisonPart += ")";
1735
+ }
1736
+ return wrapBindingExpression(comparisonPart, embeddedInBinding);
1632
1737
 
1633
1738
  case "IfElse":
1634
- if (embeddedInBinding) {
1635
- return `(${compileBinding(expr.condition, true)} ? ${compileBinding(expr.onTrue, true)} : ${compileBinding(
1636
- expr.onFalse,
1637
- true
1638
- )})`;
1639
- } else {
1640
- return `{= ${compileBinding(expr.condition, true)} ? ${compileBinding(expr.onTrue, true)} : ${compileBinding(
1641
- expr.onFalse,
1642
- true
1643
- )}}`;
1644
- }
1739
+ const ifElseExpression = `${compileBinding(expr.condition, true)} ? ${compileBinding(expr.onTrue, true)} : ${compileBinding(
1740
+ expr.onFalse,
1741
+ true
1742
+ )}`;
1743
+ return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
1645
1744
 
1646
1745
  case "Set":
1647
- if (embeddedInBinding) {
1648
- return `(${expr.operands.map(expression => compileBinding(expression, true)).join(` ${expr.operator} `)})`;
1649
- } else {
1650
- return `{= (${expr.operands.map(expression => compileBinding(expression, true)).join(` ${expr.operator} `)})}`;
1651
- }
1746
+ const setExpression = expr.operands.map(operand => compileBinding(operand, true)).join(` ${expr.operator} `);
1747
+ return wrapBindingExpression(setExpression, embeddedInBinding, true);
1652
1748
 
1653
1749
  case "Concat":
1654
- if (embeddedInBinding) {
1655
- return `${expr.expressions.map(expression => compileBinding(expression, true, true)).join(` + `)}`;
1656
- } else {
1657
- return `{= ${expr.expressions.map(expression => compileBinding(expression, true, true)).join(` + `)} }`;
1658
- }
1750
+ const concatExpression = expr.expressions.map(nestedExpression => compileBinding(nestedExpression, true, true)).join(" + ");
1751
+ return wrapBindingExpression(concatExpression, embeddedInBinding);
1752
+
1753
+ case "Length":
1754
+ const lengthExpression = `${compileBinding(expr.bindingExpression, true)}.length`;
1755
+ return wrapBindingExpression(lengthExpression, embeddedInBinding);
1659
1756
 
1660
1757
  case "Not":
1661
- if (embeddedInBinding) {
1662
- return `!${compileBinding(expr.operand, true)}`;
1663
- } else {
1664
- return `{= !${compileBinding(expr.operand, true)}}`;
1665
- }
1758
+ const notExpression = `!${compileBinding(expr.operand, true)}`;
1759
+ return wrapBindingExpression(notExpression, embeddedInBinding);
1666
1760
 
1667
1761
  case "Truthy":
1668
- if (embeddedInBinding) {
1669
- return `!!${compileBinding(expr.operand, true)}`;
1670
- } else {
1671
- return `{= !!${compileBinding(expr.operand, true)}}`;
1672
- }
1762
+ const truthyExpression = `!!${compileBinding(expr.operand, true)}`;
1763
+ return wrapBindingExpression(truthyExpression, embeddedInBinding);
1673
1764
 
1674
1765
  case "Formatter":
1675
1766
  if (expr.parameters.length === 1) {
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * SAPUI5
3
- * (c) Copyright 2009-2021 SAP SE. All rights reserved.
3
+ * (c) Copyright 2009-2022 SAP SE. All rights reserved.
4
4
  */
5
5
  sap.ui.define(["sap/ui/base/BindingParser"], function(BindingParser) {
6
6
  "use strict";
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * SAPUI5
3
- * (c) Copyright 2009-2021 SAP SE. All rights reserved.
3
+ * (c) Copyright 2009-2022 SAP SE. All rights reserved.
4
4
  */
5
5
 
6
6
  sap.ui.define(["sap/base/Log"], function(Log) {
@@ -1,10 +1,9 @@
1
1
  /*!
2
2
  * SAPUI5
3
- * (c) Copyright 2009-2021 SAP SE. All rights reserved.
3
+ * (c) Copyright 2009-2022 SAP SE. All rights reserved.
4
4
  */
5
5
  sap.ui.define(["sap/ui/core/format/DateFormat"], function(DateFormat) {
6
6
  "use strict";
7
-
8
7
  var ExcelFormatHelper = {
9
8
  /**
10
9
  * Method for converting JS Date format to Excel custom date format.
@@ -44,7 +43,6 @@ sap.ui.define(["sap/ui/core/format/DateFormat"], function(DateFormat) {
44
43
  if (sJSTimeFormat && sJSTimeFormat.includes("a")) {
45
44
  sJSTimeFormat = sJSTimeFormat.replace("a", "AM/PM");
46
45
  }
47
-
48
46
  return sJSTimeFormat;
49
47
  }
50
48
  };
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * SAPUI5
3
- * (c) Copyright 2009-2021 SAP SE. All rights reserved.
3
+ * (c) Copyright 2009-2022 SAP SE. All rights reserved.
4
4
  */
5
5
  sap.ui.define(["sap/fe/core/CommonUtils", "sap/base/util/ObjectPath"], function(CommonUtils, ObjectPath) {
6
6
  "use strict";
@@ -0,0 +1,211 @@
1
+ /*!
2
+ * SAP UI development toolkit for HTML5 (SAPUI5)
3
+ * (c) Copyright 2009-2021 SAP SE. All rights reserved
4
+ */
5
+ sap.ui.define(["sap/base/Log", "sap/fe/core/helpers/ModelHelper", "sap/fe/core/helpers/KeepAliveRefreshTypes"], function (Log, ModelHelper, KeepAliveRefreshTypes) {
6
+ "use strict";
7
+
8
+ var PATH_TO_STORE = KeepAliveRefreshTypes.PATH_TO_STORE;
9
+ var RefreshStrategyType = KeepAliveRefreshTypes.RefreshStrategyType;
10
+ var getEntitySetPath = ModelHelper.getEntitySetPath;
11
+
12
+ // Private functions - start
13
+ var _fnSimplifyEntitySetPath = function (metaModel, entitySetPathToUse) {
14
+ var entitySetPath = getEntitySetPath(entitySetPathToUse);
15
+ var entitySet = entitySetPath.indexOf("$NavigationPropertyBinding") > -1 && metaModel.getObject(entitySetPath);
16
+ return entitySet ? "/" + entitySet : entitySetPathToUse;
17
+ };
18
+
19
+ var _fnIsApplicable = function (primaryPath, key, strategy) {
20
+ return primaryPath === key || strategy === RefreshStrategyType.IncludingDependents && primaryPath.startsWith(key);
21
+ };
22
+ /**
23
+ * Check if given path resides in the context path provided.
24
+ *
25
+ * @param {ODataMetaModel} metaModel MetaModel to be used
26
+ * @param {string} contextPath Context path to be used
27
+ * @param {string} path Path to be used
28
+ * @param {RefreshStrategyType} strategy Strategy, it could be 'self' | 'includingDependents'
29
+ * @returns {boolean} Returns true if the context path is applicable.
30
+ */
31
+
32
+
33
+ var _isPathApplicableToContextPath = function (metaModel, contextPath, path, strategy) {
34
+ var contextPathToCheck = contextPath.startsWith("/") ? contextPath : "/" + contextPath,
35
+ pathToCheck = path.startsWith("/") ? path : "/" + path;
36
+
37
+ if (!_fnIsApplicable(contextPathToCheck, pathToCheck, strategy)) {
38
+ contextPathToCheck = _fnSimplifyEntitySetPath(metaModel, contextPathToCheck);
39
+
40
+ if (!_fnIsApplicable(contextPathToCheck, pathToCheck, strategy)) {
41
+ pathToCheck = _fnSimplifyEntitySetPath(metaModel, pathToCheck);
42
+ } else {
43
+ return true;
44
+ }
45
+ }
46
+
47
+ return _fnIsApplicable(contextPathToCheck, pathToCheck, strategy);
48
+ }; // Private functions - end
49
+
50
+ /**
51
+ * Get controls to refresh in a view.
52
+ *
53
+ * @param {View} view View of the controls
54
+ * @param {Control[]} controls Context path to be used
55
+ * @returns {Control[]} Returns controls that need to be refreshed.
56
+ */
57
+
58
+
59
+ var getControlsForRefresh = function (view, controls) {
60
+ var controlsForRefresh = [];
61
+ var metaModel = view.getModel().getMetaModel();
62
+ var internalModel = view.getModel("internal");
63
+ var refreshStrategy = internalModel.getProperty(PATH_TO_STORE) || {};
64
+
65
+ if (controls) {
66
+ controls.forEach(function (control) {
67
+ var contextPath = control.data("targetCollectionPath");
68
+
69
+ for (var key in refreshStrategy) {
70
+ var strategy = refreshStrategy[key];
71
+
72
+ if (controlsForRefresh.indexOf(control) === -1 && _isPathApplicableToContextPath(metaModel, contextPath, key, strategy)) {
73
+ controlsForRefresh.push(control);
74
+ }
75
+ }
76
+ });
77
+ }
78
+
79
+ return controlsForRefresh;
80
+ };
81
+ /**
82
+ * Get refresh strategy for the control for a context path.
83
+ *
84
+ * @param {Control} control Control from which refresh info is needed
85
+ * @param {string} contextPath ContextPath for properities
86
+ * @returns {RefreshStrategyType} Returns strategy for control refresh.
87
+ */
88
+
89
+
90
+ var getControlRefreshStrategyForContextPath = function (control, contextPath) {
91
+ var metaModel = control.getModel().getMetaModel();
92
+ var internalModel = control.getModel("internal");
93
+ var refreshStrategy = internalModel.getProperty(PATH_TO_STORE) || {};
94
+ var strategy;
95
+
96
+ if (contextPath) {
97
+ for (var key in refreshStrategy) {
98
+ var strategyToCheck = refreshStrategy[key];
99
+
100
+ if (_isPathApplicableToContextPath(metaModel, contextPath, key, strategyToCheck)) {
101
+ strategy = strategyToCheck;
102
+
103
+ if (strategy === "includingDependents") {
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ return strategy;
111
+ };
112
+ /**
113
+ * Get refresh info from view.
114
+ *
115
+ * @param {View} view View from which refresh info is needed
116
+ * @returns {RefreshStrategyType | undefined} Returns strategy for view refresh.
117
+ */
118
+
119
+
120
+ var getViewRefreshInfo = function (view) {
121
+ var viewData = view.getViewData(),
122
+ contextPath = viewData && ((viewData === null || viewData === void 0 ? void 0 : viewData.contextPath) || "/" + (viewData === null || viewData === void 0 ? void 0 : viewData.entitySet));
123
+ return KeepAliveHelper.getControlRefreshStrategyForContextPath(view, contextPath);
124
+ };
125
+ /**
126
+ * Get refresh strategy for an intent.
127
+ *
128
+ * @param {RefreshStrategies} refreshStrategies RefreshStrategies to consider
129
+ * @param {string} semanticObject Outbound Semantic Object
130
+ * @param {string} action Outbound Action
131
+ * @returns {SORefreshStrategy | undefined} Returns refresh strategies to use for the intent.
132
+ */
133
+
134
+
135
+ var getRefreshStrategyForIntent = function (refreshStrategies, semanticObject, action) {
136
+ var soAction = semanticObject && action && semanticObject + "-" + action;
137
+ var intents = refreshStrategies.intents;
138
+ var soActionIntentMatch = intents && soAction && intents[soAction];
139
+ var soIntentMatch = !soActionIntentMatch && intents && semanticObject && intents[semanticObject];
140
+ return soActionIntentMatch || soIntentMatch || (refreshStrategies === null || refreshStrategies === void 0 ? void 0 : refreshStrategies.defaultBehavior) || (refreshStrategies === null || refreshStrategies === void 0 ? void 0 : refreshStrategies._feDefault);
141
+ };
142
+ /**
143
+ * Store control refresh strategy for hash in the internal model.
144
+ *
145
+ * @param {Control} control Control for the refresh strategy
146
+ * @param {SOAction} hash Shell hash object
147
+ */
148
+
149
+
150
+ var storeControlRefreshStrategyForHash = function (control, hash) {
151
+ if (control && control.getModel("viewData") && control.getModel("internal")) {
152
+ var viewData = control.getModel("viewData");
153
+ var refreshStrategies = viewData.getProperty(PATH_TO_STORE);
154
+
155
+ if (refreshStrategies) {
156
+ var internalModel = control.getModel("internal");
157
+ var refreshStrategy = KeepAliveHelper.getRefreshStrategyForIntent(refreshStrategies, hash === null || hash === void 0 ? void 0 : hash.semanticObject, hash === null || hash === void 0 ? void 0 : hash.action);
158
+ internalModel.setProperty(PATH_TO_STORE, refreshStrategy);
159
+ }
160
+ }
161
+ };
162
+ /**
163
+ * Method to refresh and restore the view if neccessary.
164
+ *
165
+ * @param {object} view Control for the refresh strategy
166
+ * @returns {object} A promise after view refresh and restore are triggered
167
+ */
168
+
169
+
170
+ var restoreView = function (view) {
171
+ var internalModelContext = view.getBindingContext("internal");
172
+ var controller = view.getController();
173
+ var viewState = controller === null || controller === void 0 ? void 0 : controller.viewState;
174
+ var refreshBindings = Promise.resolve();
175
+
176
+ if (internalModelContext && internalModelContext.getProperty("restoreStatus") === "pending") {
177
+ if (viewState.refreshViewBindings) {
178
+ refreshBindings = viewState.refreshViewBindings();
179
+ refreshBindings.then(function () {
180
+ Log.info("FE V4: Refresh was triggered successfull: " + view.getId());
181
+ }).catch(function (err) {
182
+ Log.warning("FE V4: Refresh was unsuccessfull: " + view.getId(), err);
183
+ });
184
+ }
185
+
186
+ refreshBindings = refreshBindings.then(function () {
187
+ viewState.onRestore();
188
+ internalModelContext.setProperty("restoreStatus", "done");
189
+ }).catch(function (error) {
190
+ Log.warning("FE V4: Restore was unsuccessfull: " + view.getId(), error);
191
+ });
192
+ }
193
+
194
+ return refreshBindings;
195
+ };
196
+ /**
197
+ * helper class for KeepAlive feature in sap.fe.
198
+ */
199
+
200
+
201
+ var KeepAliveHelper = {
202
+ getControlsForRefresh: getControlsForRefresh,
203
+ getControlRefreshStrategyForContextPath: getControlRefreshStrategyForContextPath,
204
+ getViewRefreshInfo: getViewRefreshInfo,
205
+ getRefreshStrategyForIntent: getRefreshStrategyForIntent,
206
+ storeControlRefreshStrategyForHash: storeControlRefreshStrategyForHash,
207
+ restoreView: restoreView
208
+ };
209
+ return KeepAliveHelper;
210
+ }, false);
211
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIktlZXBBbGl2ZUhlbHBlci50cyJdLCJuYW1lcyI6WyJfZm5TaW1wbGlmeUVudGl0eVNldFBhdGgiLCJtZXRhTW9kZWwiLCJlbnRpdHlTZXRQYXRoVG9Vc2UiLCJlbnRpdHlTZXRQYXRoIiwiZ2V0RW50aXR5U2V0UGF0aCIsImVudGl0eVNldCIsImluZGV4T2YiLCJnZXRPYmplY3QiLCJfZm5Jc0FwcGxpY2FibGUiLCJwcmltYXJ5UGF0aCIsImtleSIsInN0cmF0ZWd5IiwiUmVmcmVzaFN0cmF0ZWd5VHlwZSIsIkluY2x1ZGluZ0RlcGVuZGVudHMiLCJzdGFydHNXaXRoIiwiX2lzUGF0aEFwcGxpY2FibGVUb0NvbnRleHRQYXRoIiwiY29udGV4dFBhdGgiLCJwYXRoIiwiY29udGV4dFBhdGhUb0NoZWNrIiwicGF0aFRvQ2hlY2siLCJnZXRDb250cm9sc0ZvclJlZnJlc2giLCJ2aWV3IiwiY29udHJvbHMiLCJjb250cm9sc0ZvclJlZnJlc2giLCJnZXRNb2RlbCIsImdldE1ldGFNb2RlbCIsImludGVybmFsTW9kZWwiLCJyZWZyZXNoU3RyYXRlZ3kiLCJnZXRQcm9wZXJ0eSIsIlBBVEhfVE9fU1RPUkUiLCJmb3JFYWNoIiwiY29udHJvbCIsImRhdGEiLCJwdXNoIiwiZ2V0Q29udHJvbFJlZnJlc2hTdHJhdGVneUZvckNvbnRleHRQYXRoIiwic3RyYXRlZ3lUb0NoZWNrIiwiZ2V0Vmlld1JlZnJlc2hJbmZvIiwidmlld0RhdGEiLCJnZXRWaWV3RGF0YSIsIktlZXBBbGl2ZUhlbHBlciIsImdldFJlZnJlc2hTdHJhdGVneUZvckludGVudCIsInJlZnJlc2hTdHJhdGVnaWVzIiwic2VtYW50aWNPYmplY3QiLCJhY3Rpb24iLCJzb0FjdGlvbiIsImludGVudHMiLCJzb0FjdGlvbkludGVudE1hdGNoIiwic29JbnRlbnRNYXRjaCIsImRlZmF1bHRCZWhhdmlvciIsIl9mZURlZmF1bHQiLCJzdG9yZUNvbnRyb2xSZWZyZXNoU3RyYXRlZ3lGb3JIYXNoIiwiaGFzaCIsInNldFByb3BlcnR5IiwicmVzdG9yZVZpZXciLCJpbnRlcm5hbE1vZGVsQ29udGV4dCIsImdldEJpbmRpbmdDb250ZXh0IiwiY29udHJvbGxlciIsImdldENvbnRyb2xsZXIiLCJ2aWV3U3RhdGUiLCJyZWZyZXNoQmluZGluZ3MiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlZnJlc2hWaWV3QmluZGluZ3MiLCJ0aGVuIiwiTG9nIiwiaW5mbyIsImdldElkIiwiY2F0Y2giLCJlcnIiLCJ3YXJuaW5nIiwib25SZXN0b3JlIiwiZXJyb3IiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FBYUE7QUFDQSxNQUFNQSx3QkFBd0IsR0FBRyxVQUFTQyxTQUFULEVBQW9DQyxrQkFBcEMsRUFBd0U7QUFDeEcsUUFBTUMsYUFBYSxHQUFHQyxnQkFBZ0IsQ0FBQ0Ysa0JBQUQsQ0FBdEM7QUFDQSxRQUFNRyxTQUFTLEdBQUdGLGFBQWEsQ0FBQ0csT0FBZCxDQUFzQiw0QkFBdEIsSUFBc0QsQ0FBQyxDQUF2RCxJQUE0REwsU0FBUyxDQUFDTSxTQUFWLENBQW9CSixhQUFwQixDQUE5RTtBQUNBLFdBQU9FLFNBQVMsR0FBRyxNQUFNQSxTQUFULEdBQXFCSCxrQkFBckM7QUFDQSxHQUpEOztBQUtBLE1BQU1NLGVBQWUsR0FBRyxVQUFTQyxXQUFULEVBQThCQyxHQUE5QixFQUEyQ0MsUUFBM0MsRUFBbUY7QUFDMUcsV0FBT0YsV0FBVyxLQUFLQyxHQUFoQixJQUF3QkMsUUFBUSxLQUFLQyxtQkFBbUIsQ0FBQ0MsbUJBQWpDLElBQXdESixXQUFXLENBQUNLLFVBQVosQ0FBdUJKLEdBQXZCLENBQXZGO0FBQ0EsR0FGRDtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsTUFBTUssOEJBQThCLEdBQUcsVUFDdENkLFNBRHNDLEVBRXRDZSxXQUZzQyxFQUd0Q0MsSUFIc0MsRUFJdENOLFFBSnNDLEVBSzVCO0FBQ1YsUUFBSU8sa0JBQWtCLEdBQUdGLFdBQVcsQ0FBQ0Ys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dkJFLElBQUFBLGtCQUFrQixFQUFsQkEsa0JBSHVCO0FBSXZCSSxJQUFBQSwyQkFBMkIsRUFBM0JBLDJCQUp1QjtBQUt2QlUsSUFBQUEsa0NBQWtDLEVBQWxDQSxrQ0FMdUI7QUFNdkJHLElBQUFBLFdBQVcsRUFBWEE7QUFOdUIsR0FBeEI7U0FRZWQsZSIsInNvdXJjZVJvb3QiOiIuIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29udHJvbCB9IGZyb20gXCJzYXAvdWkvY29yZVwiO1xuaW1wb3J0IHsgVmlldyB9IGZyb20gXCJzYXAvdWkvY29yZS9tdmNcIjtcbmltcG9ydCB7IExvZyB9IGZyb20gXCJzYXAvYmFzZVwiO1xuaW1wb3J0IHsgT0RhdGFNZXRhTW9kZWwgfSBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0XCI7XG5pbXBvcnQgeyBnZXRFbnRpdHlTZXRQYXRoIH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvTW9kZWxIZWxwZXJcIjtcbmltcG9ydCB7IEJhc2VNYW5pZmVzdFNldHRpbmdzIH0gZnJvbSBcInNhcC9mZS9jb3JlL2NvbnZlcnRlcnMvTWFuaWZlc3RTZXR0aW5nc1wiO1xuaW1wb3J0IHsgSlNPTk1vZGVsIH0gZnJvbSBcInNhcC91aS9tb2RlbC9qc29uXCI7XG5pbXBvcnQge1xuXHRSZWZyZXNoU3RyYXRlZ3lUeXBlLFxuXHRTT1JlZnJlc2hTdHJhdGVneSxcblx0UmVmcmVzaFN0cmF0ZWdpZXMsXG5cdFBBVEhfVE9fU1RPUkUsXG5cdFNPQWN0aW9uXG59IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL0tlZXBBbGl2ZVJlZnJlc2hUeXBlc1wiO1xuXG4vLyBQcml2YXRlIGZ1bmN0aW9ucyAtIHN0YXJ0XG5jb25zdCBfZm5TaW1wbGlmeUVudGl0eVNldFBhdGggPSBmdW5jdGlvbihtZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsLCBlbnRpdHlTZXRQYXRoVG9Vc2U6IHN0cmluZyk6IHN0cmluZyB7XG5cdGNvbnN0IGVudGl0eVNldFBhdGggPSBnZXRFbnRpdHlTZXRQYXRoKGVudGl0eVNldFBhdGhUb1VzZSk7XG5cdGNvbnN0IGVudGl0eVNldCA9IGVudGl0eVNldFBhdGguaW5kZXhPZihcIiROYXZpZ2F0aW9uUHJvcGVydHlCaW5kaW5nXCIpID4gLTEgJiYgbWV0YU1vZGVsLmdldE9iamVjdChlbnRpdHlTZXRQYXRoKTtcblx0cmV0dXJuIGVudGl0eVNldCA/IFwiL1wiICsgZW50aXR5U2V0IDogZW50aXR5U2V0UGF0aFRvVXNlO1xufTtcbmNvbnN0IF9mbklzQXBwbGljYWJsZSA9IGZ1bmN0aW9uKHByaW1hcnlQYXRoOiBzdHJpbmcsIGtleTogc3RyaW5nLCBzdHJhdGVneTogUmVmcmVzaFN0cmF0ZWd5VHlwZSk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gcHJpbWFyeVBhdGggPT09IGtleSB8fCAoc3RyYXRlZ3kgPT09IFJlZnJlc2hTdHJhdGVneVR5cGUuSW5jbHVkaW5nRGVwZW5kZW50cyAmJiBwcmltYXJ5UGF0aC5zdGFydHNXaXRoKGtleSkpO1xufTtcbi8qKlxuICogQ2hlY2sgaWYgZ2l2ZW4gcGF0aCByZXNpZGVzIGluIHRoZSBjb250ZXh0IHBhdGggcHJvdmlkZWQuXG4gKlxuICogQHBhcmFtIHtPRGF0YU1ldGFNb2RlbH0gbWV0YU1vZGVsIE1ldGFNb2RlbCB0byBiZSB1c2VkXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dFBhdGggQ29udGV4dCBwYXRoIHRvIGJlIHVzZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFBhdGggdG8gYmUgdXNlZFxuICogQHBhcmFtIHtSZWZyZXNoU3RyYXRlZ3lUeXBlfSBzdHJhdGVneSBTdHJhdGVneSwgaXQgY291bGQgYmUgJ3NlbGYnIHwgJ2luY2x1ZGluZ0RlcGVuZGVudHMnXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBjb250ZXh0IHBhdGggaXMgYXBwbGljYWJsZS5cbiAqL1xuY29uc3QgX2lzUGF0aEFwcGxpY2FibGVUb0NvbnRleHRQYXRoID0gZnVuY3Rpb24oXG5cdG1ldGFNb2RlbDogT0RhdGFNZXRhTW9kZWwsXG5cdGNvbnRleHRQYXRoOiBzdHJpbmcsXG5cdHBhdGg6IHN0cmluZyxcblx0c3RyYXRlZ3k6IFJlZnJlc2hTdHJhdGVneVR5cGVcbik6IGJvb2xlYW4ge1xuXHRsZXQgY29udGV4dFBhdGhUb0NoZWNrID0gY29udGV4dFBhdGguc3RhcnRzV2l0aChcIi9cIikgPyBjb250ZXh0UGF0aCA6IFwiL1wiICsgY29udGV4dFBhdGgsXG5cdFx0cGF0aFRvQ2hlY2sgPSBwYXRoLnN0YXJ0c1dpdGgoXCIvXCIpID8gcGF0aCA6IFwiL1wiICsgcGF0aDtcblx0aWYgKCFfZm5Jc0FwcGxpY2FibGUoY29udGV4dFBhdGhUb0NoZWNrLCBwYXRoVG9DaGVjaywgc3RyYXRlZ3kpKSB7XG5cdFx0Y29udGV4dFBhdGhUb0NoZWNrID0gX2ZuU2ltcGxpZnlFbnRpdHlTZXRQYXRoKG1ldGFNb2RlbCwgY29udGV4dFBhdGhUb0NoZWNrKTtcblx0XHRpZiAoIV9mbklzQXBwbGljYWJsZShjb250ZXh0UGF0aFRvQ2hlY2ssIHBhdGhUb0NoZWNrLCBzdHJhdGVneSkpIHtcblx0XHRcdHBhdGhUb0NoZWNrID0gX2ZuU2ltcGxpZnlFbnRpdHlTZXRQYXRoKG1ldGFNb2RlbCwgcGF0aFRvQ2hlY2spO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIF9mbklzQXBwbGljYWJsZShjb250ZXh0UGF0aFRvQ2hlY2ssIHBhdGhUb0NoZWNrLCBzdHJhdGVneSk7XG59O1xuLy8gUHJpdmF0ZSBmdW5jdGlvbnMgLSBlbmRcbi8qKlxuICogR2V0IGNvbnRyb2xzIHRvIHJlZnJlc2ggaW4gYSB2aWV3LlxuICpcbiAqIEBwYXJhbSB7Vmlld30gdmlldyBWaWV3IG9mIHRoZSBjb250cm9sc1xuICogQHBhcmFtIHtDb250cm9sW119IGNvbnRyb2xzIENvbnRleHQgcGF0aCB0byBiZSB1c2VkXG4gKiBAcmV0dXJucyB7Q29udHJvbFtdfSBSZXR1cm5zIGNvbnRyb2xzIHRoYXQgbmVlZCB0byBiZSByZWZyZXNoZWQuXG4gKi9cbmNvbnN0IGdldENvbnRyb2xzRm9yUmVmcmVzaCA9IGZ1bmN0aW9uKHZpZXc6IFZpZXcsIGNvbnRyb2xzOiBDb250cm9sW10pOiBDb250cm9sW10ge1xuXHRjb25zdCBjb250cm9sc0ZvclJlZnJlc2g6IENvbnRyb2xbXSA9IFtdO1xuXHRjb25zdCBtZXRhTW9kZWwgPSB2aWV3LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCkgYXMgT0RhdGFNZXRhTW9kZWw7XG5cdGNvbnN0IGludGVybmFsTW9kZWwgPSB2aWV3LmdldE1vZGVsKFwiaW50ZXJuYWxcIik7XG5cdGNvbnN0IHJlZnJlc2hTdHJhdGVneSA9IGludGVybmFsTW9kZWwuZ2V0UHJvcGVydHkoUEFUSF9UT19TVE9SRSkgfHwge307XG5cdGlmIChjb250cm9scykge1xuXHRcdGNvbnRyb2xzLmZvckVhY2goZnVuY3Rpb24oY29udHJvbCkge1xuXHRcdFx0Y29uc3QgY29udGV4dFBhdGggPSBjb250cm9sLmRhdGEoXCJ0YXJnZXRDb2xsZWN0aW9uUGF0aFwiKTtcblx0XHRcdGZvciAoY29uc3Qga2V5IGluIHJlZnJlc2hTdHJhdGVneSkge1xuXHRcdFx0XHRjb25zdCBzdHJhdGVneSA9IHJlZnJlc2hTdHJhdGVneVtrZXldO1xuXHRcdFx0XHRpZiAoY29udHJvbHNGb3JSZWZyZXNoLmluZGV4T2YoY29udHJvbCkgPT09IC0xICYmIF9pc1BhdGhBcHBsaWNhYmxlVG9Db250ZXh0UGF0aChtZXRhTW9kZWwsIGNvbnRleHRQYXRoLCBrZXksIHN0cmF0ZWd5KSkge1xuXHRcdFx0XHRcdGNvbnRyb2xzRm9yUmVmcmVzaC5wdXNoKGNvbnRyb2wpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblx0cmV0dXJuIGNvbnRyb2xzRm9yUmVmcmVzaDtcbn07XG4vKipcbiAqIEdldCByZWZyZXNoIHN0cmF0ZWd5IGZvciB0aGUgY29udHJvbCBmb3IgYSBjb250ZXh0IHBhdGguXG4gKlxuICogQHBhcmFtIHtDb250cm9sfSBjb250cm9sIENvbnRyb2wgZnJvbSB3aGljaCByZWZyZXNoIGluZm8gaXMgbmVlZGVkXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dFBhdGggQ29udGV4dFBhdGggZm9yIHByb3Blcml0aWVzXG4gKiBAcmV0dXJucyB7UmVmcmVzaFN0cmF0ZWd5VHlwZX0gUmV0dXJucyBzdHJhdGVneSBmb3IgY29udHJvbCByZWZyZXNoLlxuICovXG5jb25zdCBnZXRDb250cm9sUmVmcmVzaFN0cmF0ZWd5Rm9yQ29udGV4dFBhdGggPSBmdW5jdGlvbihjb250cm9sOiBDb250cm9sLCBjb250ZXh0UGF0aDogc3RyaW5nKTogUmVmcmVzaFN0cmF0ZWd5VHlwZSB8IHVuZGVmaW5lZCB7XG5cdGNvbnN0IG1ldGFNb2RlbCA9IGNvbnRyb2wuZ2V0TW9kZWwoKS5nZXRNZXRhTW9kZWwoKSBhcyBPRGF0YU1ldGFNb2RlbDtcblx0Y29uc3QgaW50ZXJuYWxNb2RlbCA9IGNvbnRyb2wuZ2V0TW9kZWwoXCJpbnRlcm5hbFwiKTtcblx0Y29uc3QgcmVmcmVzaFN0cmF0ZWd5ID0gaW50ZXJuYWxNb2RlbC5nZXRQcm9wZXJ0eShQQVRIX1RPX1NUT1JFKSB8fCB7fTtcblx0bGV0IHN0cmF0ZWd5O1xuXHRpZiAoY29udGV4dFBhdGgpIHtcblx0XHRmb3IgKGNvbnN0IGtleSBpbiByZWZyZXNoU3RyYXRlZ3kpIHtcblx0XHRcdGNvbnN0IHN0cmF0ZWd5VG9DaGVjayA9IHJlZnJlc2hTdHJhdGVneVtrZXldO1xuXHRcdFx0aWYgKF9pc1BhdGhBcHBsaWNhYmxlVG9Db250ZXh0UGF0aChtZXRhTW9kZWwsIGNvbnRleHRQYXRoLCBrZXksIHN0cmF0ZWd5VG9DaGVjaykpIHtcblx0XHRcdFx0c3RyYXRlZ3kgPSBzdHJhdGVneVRvQ2hlY2s7XG5cdFx0XHRcdGlmIChzdHJhdGVneSA9PT0gXCJpbmNsdWRpbmdEZXBlbmRlbnRzXCIpIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gc3RyYXRlZ3k7XG59O1xuLyoqXG4gKiBHZXQgcmVmcmVzaCBpbmZvIGZyb20gdmlldy5cbiAqXG4gKiBAcGFyYW0ge1ZpZXd9IHZpZXcgVmlldyBmcm9tIHdoaWNoIHJlZnJlc2ggaW5mbyBpcyBuZWVkZWRcbiAqIEByZXR1cm5zIHtSZWZyZXNoU3RyYXRlZ3lUeXBlIHwgdW5kZWZpbmVkfSBSZXR1cm5zIHN0cmF0ZWd5IGZvciB2aWV3IHJlZnJlc2guXG4gKi9cbmNvbnN0IGdldFZpZXdSZWZyZXNoSW5mbyA9IGZ1bmN0aW9uKHZpZXc6IFZpZXcpOiBSZWZyZXNoU3RyYXRlZ3lUeXBlIHwgdW5kZWZpbmVkIHtcblx0Y29uc3Qgdmlld0RhdGEgPSB2aWV3LmdldFZpZXdEYXRhKCkgYXMgQmFzZU1hbmlmZXN0U2V0dGluZ3MsXG5cdFx0Y29udGV4dFBhdGggPSB2aWV3RGF0YSAmJiAodmlld0RhdGE/LmNvbnRleHRQYXRoIHx8IFwiL1wiICsgdmlld0RhdGE/LmVudGl0eVNldCk7XG5cdHJldHVybiBLZWVwQWxpdmVIZWxwZXIuZ2V0Q29udHJvbFJlZnJlc2hTdHJhdGVneUZvckNvbnRleHRQYXRoKHZpZXcsIGNvbnRleHRQYXRoKTtcbn07XG5cbi8qKlxuICogR2V0IHJlZnJlc2ggc3RyYXRlZ3kgZm9yIGFuIGludGVudC5cbiAqXG4gKiBAcGFyYW0ge1JlZnJlc2hTdHJhdGVnaWVzfSByZWZyZXNoU3RyYXRlZ2llcyBSZWZyZXNoU3RyYXRlZ2llcyB0byBjb25zaWRlclxuICogQHBhcmFtIHtzdHJpbmd9IHNlbWFudGljT2JqZWN0IE91dGJvdW5kIFNlbWFudGljIE9iamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiBPdXRib3VuZCBBY3Rpb25cbiAqIEByZXR1cm5zIHtTT1JlZnJlc2hTdHJhdGVneSB8IHVuZGVmaW5lZH0gUmV0dXJucyByZWZyZXNoIHN0cmF0ZWdpZXMgdG8gdXNlIGZvciB0aGUgaW50ZW50LlxuICovXG5jb25zdCBnZXRSZWZyZXNoU3RyYXRlZ3lGb3JJbnRlbnQgPSBmdW5jdGlvbihcblx0cmVmcmVzaFN0cmF0ZWdpZXM6IFJlZnJlc2hTdHJhdGVnaWVzLFxuXHRzZW1hbnRpY09iamVjdD86IHN0cmluZyxcblx0YWN0aW9uPzogc3RyaW5nXG4pOiBTT1JlZnJlc2hTdHJhdGVneSB8IHVuZGVmaW5lZCB7XG5cdGNvbnN0IHNvQWN0aW9uID0gc2VtYW50aWNPYmplY3QgJiYgYWN0aW9uICYmIHNlbWFudGljT2JqZWN0ICsgXCItXCIgKyBhY3Rpb247XG5cdGNvbnN0IGludGVudHMgPSByZWZyZXNoU3RyYXRlZ2llcy5pbnRlbnRzO1xuXHRjb25zdCBzb0FjdGlvbkludGVudE1hdGNoID0gaW50ZW50cyAmJiBzb0FjdGlvbiAmJiBpbnRlbnRzW3NvQWN0aW9uXTtcblx0Y29uc3Qgc29JbnRlbnRNYXRjaCA9ICFzb0FjdGlvbkludGVudE1hdGNoICYmIGludGVudHMgJiYgc2VtYW50aWNPYmplY3QgJiYgaW50ZW50c1tzZW1hbnRpY09iamVjdF07XG5cblx0cmV0dXJuIHNvQWN0aW9uSW50ZW50TWF0Y2ggfHwgc29JbnRlbnRNYXRjaCB8fCByZWZyZXNoU3RyYXRlZ2llcz8uZGVmYXVsdEJlaGF2aW9yIHx8IHJlZnJlc2hTdHJhdGVnaWVzPy5fZmVEZWZhdWx0O1xufTtcbi8qKlxuICogU3RvcmUgY29udHJvbCByZWZyZXNoIHN0cmF0ZWd5IGZvciBoYXNoIGluIHRoZSBpbnRlcm5hbCBtb2RlbC5cbiAqXG4gKiBAcGFyYW0ge0NvbnRyb2x9IGNvbnRyb2wgQ29udHJvbCBmb3IgdGhlIHJlZnJlc2ggc3RyYXRlZ3lcbiAqIEBwYXJhbSB7U09BY3Rpb259IGhhc2ggU2hlbGwgaGFzaCBvYmplY3RcbiAqL1xuY29uc3Qgc3RvcmVDb250cm9sUmVmcmVzaFN0cmF0ZWd5Rm9ySGFzaCA9IGZ1bmN0aW9uKGNvbnRyb2w6IENvbnRyb2wsIGhhc2g6IFNPQWN0aW9uKTogdm9pZCB7XG5cdGlmIChjb250cm9sICYmIGNvbnRyb2wuZ2V0TW9kZWwoXCJ2aWV3RGF0YVwiKSAmJiBjb250cm9sLmdldE1vZGVsKFwiaW50ZXJuYWxcIikpIHtcblx0XHRjb25zdCB2aWV3RGF0YSA9IGNvbnRyb2wuZ2V0TW9kZWwoXCJ2aWV3RGF0YVwiKTtcblx0XHRjb25zdCByZWZyZXNoU3RyYXRlZ2llczogUmVmcmVzaFN0cmF0ZWdpZXMgPSB2aWV3RGF0YS5nZXRQcm9wZXJ0eShQQVRIX1RPX1NUT1JFKTtcblx0XHRpZiAocmVmcmVzaFN0cmF0ZWdpZXMpIHtcblx0XHRcdGNvbnN0IGludGVybmFsTW9kZWwgPSBjb250cm9sLmdldE1vZGVsKFwiaW50ZXJuYWxcIik7XG5cdFx0XHRjb25zdCByZWZyZXNoU3RyYXRlZ3k6IFNPUmVmcmVzaFN0cmF0ZWd5IHwgdW5kZWZpbmVkID0gS2VlcEFsaXZlSGVscGVyLmdldFJlZnJlc2hTdHJhdGVneUZvckludGVudChcblx0XHRcdFx0cmVmcmVzaFN0cmF0ZWdpZXMsXG5cdFx0XHRcdGhhc2g/LnNlbWFudGljT2JqZWN0LFxuXHRcdFx0XHRoYXNoPy5hY3Rpb25cblx0XHRcdCk7XG5cdFx0XHQoaW50ZXJuYWxNb2RlbCBhcyBKU09OTW9kZWw8e30+KS5zZXRQcm9wZXJ0eShQQVRIX1RPX1NUT1JFLCByZWZyZXNoU3RyYXRlZ3kpO1xuXHRcdH1cblx0fVxufTtcblxuLyoqXG4gKiBNZXRob2QgdG8gcmVmcmVzaCBhbmQgcmVzdG9yZSB0aGUgdmlldyBpZiBuZWNjZXNzYXJ5LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB2aWV3IENvbnRyb2wgZm9yIHRoZSByZWZyZXNoIHN0cmF0ZWd5XG4gKiBAcmV0dXJucyB7b2JqZWN0fSBBIHByb21pc2UgYWZ0ZXIgdmlldyByZWZyZXNoIGFuZCByZXN0b3JlIGFyZSB0cmlnZ2VyZWRcbiAqL1xuY29uc3QgcmVzdG9yZVZpZXcgPSBmdW5jdGlvbih2aWV3OiBWaWV3KTogUHJvbWlzZTxhbnk+IHtcblx0Y29uc3QgaW50ZXJuYWxNb2RlbENvbnRleHQgPSB2aWV3LmdldEJpbmRpbmdDb250ZXh0KFwiaW50ZXJuYWxcIik7XG5cdGNvbnN0IGNvbnRyb2xsZXIgPSB2aWV3LmdldENvbnRyb2xsZXIoKTtcblx0Y29uc3Qgdmlld1N0YXRlID0gKGNvbnRyb2xsZXIgYXMgYW55KT8udmlld1N0YXRlO1xuXHRsZXQgcmVmcmVzaEJpbmRpbmdzID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdGlmIChpbnRlcm5hbE1vZGVsQ29udGV4dCAmJiBpbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRQcm9wZXJ0eShcInJlc3RvcmVTdGF0dXNcIikgPT09IFwicGVuZGluZ1wiKSB7XG5cdFx0aWYgKHZpZXdTdGF0ZS5yZWZyZXNoVmlld0JpbmRpbmdzKSB7XG5cdFx0XHRyZWZyZXNoQmluZGluZ3MgPSB2aWV3U3RhdGUucmVmcmVzaFZpZXdCaW5kaW5ncygpO1xuXHRcdFx0cmVmcmVzaEJpbmRpbmdzXG5cdFx0XHRcdC50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdExvZy5pbmZvKFwiRkUgVjQ6IFJlZnJlc2ggd2FzIHRyaWdnZXJlZCBzdWNjZXNzZnVsbDogXCIgKyB2aWV3LmdldElkKCkpO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG5cdFx0XHRcdFx0TG9nLndhcm5pbmcoXCJGRSBWNDogUmVmcmVzaCB3YXMgdW5zdWNjZXNzZnVsbDogXCIgKyB2aWV3LmdldElkKCksIGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZWZyZXNoQmluZGluZ3MgPSByZWZyZXNoQmluZGluZ3Ncblx0XHRcdC50aGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2aWV3U3RhdGUub25SZXN0b3JlKCk7XG5cdFx0XHRcdGludGVybmFsTW9kZWxDb250ZXh0LnNldFByb3BlcnR5KFwicmVzdG9yZVN0YXR1c1wiLCBcImRvbmVcIik7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uKGVycm9yKSB7XG5cdFx0XHRcdExvZy53YXJuaW5nKFwiRkUgVjQ6IFJlc3RvcmUgd2FzIHVuc3VjY2Vzc2Z1bGw6IFwiICsgdmlldy5nZXRJZCgpLCBlcnJvcik7XG5cdFx0XHR9KTtcblx0fVxuXHRyZXR1cm4gcmVmcmVzaEJpbmRpbmdzO1xufTtcblxuLyoqXG4gKiBoZWxwZXIgY2xhc3MgZm9yIEtlZXBBbGl2ZSBmZWF0dXJlIGluIHNhcC5mZS5cbiAqL1xuY29uc3QgS2VlcEFsaXZlSGVscGVyID0ge1xuXHRnZXRDb250cm9sc0ZvclJlZnJlc2gsXG5cdGdldENvbnRyb2xSZWZyZXNoU3RyYXRlZ3lGb3JDb250ZXh0UGF0aCxcblx0Z2V0Vmlld1JlZnJlc2hJbmZvLFxuXHRnZXRSZWZyZXNoU3RyYXRlZ3lGb3JJbnRlbnQsXG5cdHN0b3JlQ29udHJvbFJlZnJlc2hTdHJhdGVneUZvckhhc2gsXG5cdHJlc3RvcmVWaWV3XG59O1xuZXhwb3J0IGRlZmF1bHQgS2VlcEFsaXZlSGVscGVyO1xuIl19