lwc-convert 1.0.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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +719 -0
  3. package/dist/cli/commands/aura.d.ts +6 -0
  4. package/dist/cli/commands/aura.d.ts.map +1 -0
  5. package/dist/cli/commands/aura.js +225 -0
  6. package/dist/cli/commands/aura.js.map +1 -0
  7. package/dist/cli/commands/vf.d.ts +6 -0
  8. package/dist/cli/commands/vf.d.ts.map +1 -0
  9. package/dist/cli/commands/vf.js +218 -0
  10. package/dist/cli/commands/vf.js.map +1 -0
  11. package/dist/cli/interactive.d.ts +20 -0
  12. package/dist/cli/interactive.d.ts.map +1 -0
  13. package/dist/cli/interactive.js +577 -0
  14. package/dist/cli/interactive.js.map +1 -0
  15. package/dist/cli/options.d.ts +21 -0
  16. package/dist/cli/options.d.ts.map +1 -0
  17. package/dist/cli/options.js +24 -0
  18. package/dist/cli/options.js.map +1 -0
  19. package/dist/generators/full-conversion.d.ts +41 -0
  20. package/dist/generators/full-conversion.d.ts.map +1 -0
  21. package/dist/generators/full-conversion.js +538 -0
  22. package/dist/generators/full-conversion.js.map +1 -0
  23. package/dist/generators/scaffolding.d.ts +40 -0
  24. package/dist/generators/scaffolding.d.ts.map +1 -0
  25. package/dist/generators/scaffolding.js +716 -0
  26. package/dist/generators/scaffolding.js.map +1 -0
  27. package/dist/generators/test-comparison.d.ts +47 -0
  28. package/dist/generators/test-comparison.d.ts.map +1 -0
  29. package/dist/generators/test-comparison.js +855 -0
  30. package/dist/generators/test-comparison.js.map +1 -0
  31. package/dist/generators/test-generator.d.ts +27 -0
  32. package/dist/generators/test-generator.d.ts.map +1 -0
  33. package/dist/generators/test-generator.js +385 -0
  34. package/dist/generators/test-generator.js.map +1 -0
  35. package/dist/index.d.ts +6 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +226 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/mappings/aura-to-lwc.json +321 -0
  40. package/dist/mappings/vf-to-lwc.json +354 -0
  41. package/dist/parsers/aura/controller-parser.d.ts +36 -0
  42. package/dist/parsers/aura/controller-parser.d.ts.map +1 -0
  43. package/dist/parsers/aura/controller-parser.js +269 -0
  44. package/dist/parsers/aura/controller-parser.js.map +1 -0
  45. package/dist/parsers/aura/helper-parser.d.ts +21 -0
  46. package/dist/parsers/aura/helper-parser.d.ts.map +1 -0
  47. package/dist/parsers/aura/helper-parser.js +173 -0
  48. package/dist/parsers/aura/helper-parser.js.map +1 -0
  49. package/dist/parsers/aura/markup-parser.d.ts +59 -0
  50. package/dist/parsers/aura/markup-parser.d.ts.map +1 -0
  51. package/dist/parsers/aura/markup-parser.js +279 -0
  52. package/dist/parsers/aura/markup-parser.js.map +1 -0
  53. package/dist/parsers/aura/style-parser.d.ts +37 -0
  54. package/dist/parsers/aura/style-parser.d.ts.map +1 -0
  55. package/dist/parsers/aura/style-parser.js +151 -0
  56. package/dist/parsers/aura/style-parser.js.map +1 -0
  57. package/dist/parsers/vf/apex-parser.d.ts +51 -0
  58. package/dist/parsers/vf/apex-parser.d.ts.map +1 -0
  59. package/dist/parsers/vf/apex-parser.js +251 -0
  60. package/dist/parsers/vf/apex-parser.js.map +1 -0
  61. package/dist/parsers/vf/page-parser.d.ts +61 -0
  62. package/dist/parsers/vf/page-parser.d.ts.map +1 -0
  63. package/dist/parsers/vf/page-parser.js +403 -0
  64. package/dist/parsers/vf/page-parser.js.map +1 -0
  65. package/dist/transformers/aura-to-lwc/controller.d.ts +36 -0
  66. package/dist/transformers/aura-to-lwc/controller.d.ts.map +1 -0
  67. package/dist/transformers/aura-to-lwc/controller.js +372 -0
  68. package/dist/transformers/aura-to-lwc/controller.js.map +1 -0
  69. package/dist/transformers/aura-to-lwc/events.d.ts +47 -0
  70. package/dist/transformers/aura-to-lwc/events.d.ts.map +1 -0
  71. package/dist/transformers/aura-to-lwc/events.js +262 -0
  72. package/dist/transformers/aura-to-lwc/events.js.map +1 -0
  73. package/dist/transformers/aura-to-lwc/markup.d.ts +51 -0
  74. package/dist/transformers/aura-to-lwc/markup.d.ts.map +1 -0
  75. package/dist/transformers/aura-to-lwc/markup.js +465 -0
  76. package/dist/transformers/aura-to-lwc/markup.js.map +1 -0
  77. package/dist/transformers/vf-to-lwc/components.d.ts +40 -0
  78. package/dist/transformers/vf-to-lwc/components.d.ts.map +1 -0
  79. package/dist/transformers/vf-to-lwc/components.js +374 -0
  80. package/dist/transformers/vf-to-lwc/components.js.map +1 -0
  81. package/dist/transformers/vf-to-lwc/data-binding.d.ts +53 -0
  82. package/dist/transformers/vf-to-lwc/data-binding.d.ts.map +1 -0
  83. package/dist/transformers/vf-to-lwc/data-binding.js +660 -0
  84. package/dist/transformers/vf-to-lwc/data-binding.js.map +1 -0
  85. package/dist/transformers/vf-to-lwc/markup.d.ts +44 -0
  86. package/dist/transformers/vf-to-lwc/markup.d.ts.map +1 -0
  87. package/dist/transformers/vf-to-lwc/markup.js +816 -0
  88. package/dist/transformers/vf-to-lwc/markup.js.map +1 -0
  89. package/dist/utils/confidence-scorer.d.ts +100 -0
  90. package/dist/utils/confidence-scorer.d.ts.map +1 -0
  91. package/dist/utils/confidence-scorer.js +358 -0
  92. package/dist/utils/confidence-scorer.js.map +1 -0
  93. package/dist/utils/file-io.d.ts +62 -0
  94. package/dist/utils/file-io.d.ts.map +1 -0
  95. package/dist/utils/file-io.js +248 -0
  96. package/dist/utils/file-io.js.map +1 -0
  97. package/dist/utils/logger.d.ts +34 -0
  98. package/dist/utils/logger.d.ts.map +1 -0
  99. package/dist/utils/logger.js +130 -0
  100. package/dist/utils/logger.js.map +1 -0
  101. package/dist/utils/open-folder.d.ts +9 -0
  102. package/dist/utils/open-folder.d.ts.map +1 -0
  103. package/dist/utils/open-folder.js +76 -0
  104. package/dist/utils/open-folder.js.map +1 -0
  105. package/dist/utils/path-resolver.d.ts +29 -0
  106. package/dist/utils/path-resolver.d.ts.map +1 -0
  107. package/dist/utils/path-resolver.js +240 -0
  108. package/dist/utils/path-resolver.js.map +1 -0
  109. package/dist/utils/session-store.d.ts +158 -0
  110. package/dist/utils/session-store.d.ts.map +1 -0
  111. package/dist/utils/session-store.js +518 -0
  112. package/dist/utils/session-store.js.map +1 -0
  113. package/dist/utils/vf-controller-resolver.d.ts +36 -0
  114. package/dist/utils/vf-controller-resolver.d.ts.map +1 -0
  115. package/dist/utils/vf-controller-resolver.js +162 -0
  116. package/dist/utils/vf-controller-resolver.js.map +1 -0
  117. package/package.json +81 -0
@@ -0,0 +1,354 @@
1
+ {
2
+ "components": {
3
+ "apex:page": {
4
+ "lwc": "template",
5
+ "notes": "Root element becomes <template>. Page-level attributes need handling."
6
+ },
7
+ "apex:form": {
8
+ "lwc": "lightning-record-edit-form",
9
+ "alternativeLwc": "form",
10
+ "notes": "Use lightning-record-edit-form for record operations, or plain form with lightning-inputs"
11
+ },
12
+ "apex:inputText": {
13
+ "lwc": "lightning-input",
14
+ "attributes": {
15
+ "value": "value",
16
+ "id": "data-id",
17
+ "styleClass": "class",
18
+ "disabled": "disabled",
19
+ "maxlength": "max-length",
20
+ "size": null
21
+ },
22
+ "events": {
23
+ "onchange": "onchange",
24
+ "onfocus": "onfocus",
25
+ "onblur": "onblur"
26
+ },
27
+ "notes": "Requires onchange handler to update reactive property"
28
+ },
29
+ "apex:inputTextarea": {
30
+ "lwc": "lightning-textarea",
31
+ "attributes": {
32
+ "value": "value",
33
+ "rows": null,
34
+ "cols": null,
35
+ "styleClass": "class"
36
+ },
37
+ "notes": "Use CSS for sizing instead of rows/cols"
38
+ },
39
+ "apex:inputCheckbox": {
40
+ "lwc": "lightning-input",
41
+ "attributes": {
42
+ "value": "checked",
43
+ "selected": "checked"
44
+ },
45
+ "typeOverride": "checkbox",
46
+ "notes": "Use type='checkbox' on lightning-input"
47
+ },
48
+ "apex:selectList": {
49
+ "lwc": "lightning-combobox",
50
+ "alternativeLwc": "lightning-dual-listbox",
51
+ "attributes": {
52
+ "value": "value",
53
+ "multiselect": null,
54
+ "size": null
55
+ },
56
+ "notes": "Use lightning-dual-listbox for multiselect"
57
+ },
58
+ "apex:selectOptions": {
59
+ "lwc": "options-property",
60
+ "notes": "Options are passed as a JavaScript array property"
61
+ },
62
+ "apex:selectOption": {
63
+ "lwc": "option-object",
64
+ "notes": "Individual options become objects in the options array: { label, value }"
65
+ },
66
+ "apex:selectRadio": {
67
+ "lwc": "lightning-radio-group",
68
+ "notes": "Radio buttons use lightning-radio-group component"
69
+ },
70
+ "apex:commandButton": {
71
+ "lwc": "lightning-button",
72
+ "attributes": {
73
+ "action": "onclick",
74
+ "value": "label",
75
+ "disabled": "disabled",
76
+ "styleClass": "class",
77
+ "reRender": null,
78
+ "status": null,
79
+ "oncomplete": null
80
+ },
81
+ "notes": "Action becomes onclick handler; reRender logic handled via reactive properties"
82
+ },
83
+ "apex:commandLink": {
84
+ "lwc": "lightning-button",
85
+ "alternativeLwc": "a",
86
+ "attributes": {
87
+ "action": "onclick",
88
+ "value": "label"
89
+ },
90
+ "notes": "Use variant='base' for link appearance, or use anchor tag"
91
+ },
92
+ "apex:outputText": {
93
+ "lwc": "text-interpolation",
94
+ "alternativeLwc": "lightning-formatted-text",
95
+ "notes": "Simple output can be direct text interpolation {value}"
96
+ },
97
+ "apex:outputLink": {
98
+ "lwc": "a",
99
+ "alternativeLwc": "lightning-formatted-url",
100
+ "attributes": {
101
+ "value": "href",
102
+ "target": "target",
103
+ "styleClass": "class"
104
+ },
105
+ "notes": "Use anchor tag or lightning-formatted-url for links"
106
+ },
107
+ "apex:outputLabel": {
108
+ "lwc": "label",
109
+ "notes": "Use HTML label element or include label in lightning-input"
110
+ },
111
+ "apex:outputField": {
112
+ "lwc": "lightning-output-field",
113
+ "notes": "Use within lightning-record-view-form"
114
+ },
115
+ "apex:inputField": {
116
+ "lwc": "lightning-input-field",
117
+ "notes": "Use within lightning-record-edit-form"
118
+ },
119
+ "apex:pageBlock": {
120
+ "lwc": "lightning-card",
121
+ "alternativeLwc": "div",
122
+ "attributes": {
123
+ "title": "title",
124
+ "mode": null
125
+ },
126
+ "notes": "lightning-card provides similar visual grouping"
127
+ },
128
+ "apex:pageBlockSection": {
129
+ "lwc": "lightning-layout",
130
+ "alternativeLwc": "div",
131
+ "notes": "Use lightning-layout for grid-based sections"
132
+ },
133
+ "apex:pageBlockSectionItem": {
134
+ "lwc": "lightning-layout-item",
135
+ "alternativeLwc": "div",
136
+ "notes": "Use lightning-layout-item within lightning-layout"
137
+ },
138
+ "apex:pageBlockButtons": {
139
+ "lwc": "div.slds-button-group",
140
+ "notes": "Use SLDS button-group classes"
141
+ },
142
+ "apex:pageBlockTable": {
143
+ "lwc": "lightning-datatable",
144
+ "attributes": {
145
+ "value": "data",
146
+ "var": null,
147
+ "columns": "columns"
148
+ },
149
+ "notes": "Columns defined as JavaScript array; iterate logic in columns definition"
150
+ },
151
+ "apex:column": {
152
+ "lwc": "column-definition",
153
+ "notes": "Becomes object in columns array: { label, fieldName, type }"
154
+ },
155
+ "apex:dataTable": {
156
+ "lwc": "lightning-datatable",
157
+ "notes": "Similar to pageBlockTable conversion"
158
+ },
159
+ "apex:dataList": {
160
+ "lwc": "template-for-each",
161
+ "notes": "Use for:each directive with ul/li elements"
162
+ },
163
+ "apex:repeat": {
164
+ "lwc": "template-for-each",
165
+ "attributes": {
166
+ "value": "for:each",
167
+ "var": "for:item"
168
+ },
169
+ "notes": "Becomes for:each template directive"
170
+ },
171
+ "apex:panelGrid": {
172
+ "lwc": "lightning-layout",
173
+ "notes": "Use lightning-layout with column specifications"
174
+ },
175
+ "apex:panelGroup": {
176
+ "lwc": "div",
177
+ "notes": "Simple div grouping, or slot for component composition"
178
+ },
179
+ "apex:outputPanel": {
180
+ "lwc": "div",
181
+ "attributes": {
182
+ "layout": null,
183
+ "rendered": "if:true/if:false"
184
+ },
185
+ "notes": "Use div with conditional rendering directive"
186
+ },
187
+ "apex:actionFunction": {
188
+ "lwc": "imperative-apex",
189
+ "notes": "Replace with imported Apex method called imperatively"
190
+ },
191
+ "apex:actionSupport": {
192
+ "lwc": "event-handler",
193
+ "notes": "Event handling via onchange, onclick etc. handlers"
194
+ },
195
+ "apex:actionPoller": {
196
+ "lwc": "setInterval",
197
+ "notes": "Use setInterval in connectedCallback, clear in disconnectedCallback"
198
+ },
199
+ "apex:actionStatus": {
200
+ "lwc": "lightning-spinner",
201
+ "notes": "Show/hide spinner based on loading state property"
202
+ },
203
+ "apex:messages": {
204
+ "lwc": "ShowToastEvent",
205
+ "alternativeLwc": "lightning-messages",
206
+ "notes": "Use toast for user notifications or lightning-messages component"
207
+ },
208
+ "apex:pageMessages": {
209
+ "lwc": "ShowToastEvent",
210
+ "notes": "Use ShowToastEvent from lightning/platformShowToastEvent"
211
+ },
212
+ "apex:message": {
213
+ "lwc": "lightning-helptext",
214
+ "notes": "Field-level messages use lightning-helptext or custom error display"
215
+ },
216
+ "apex:facet": {
217
+ "lwc": "slot",
218
+ "notes": "Use named slots for content projection"
219
+ },
220
+ "apex:tab": {
221
+ "lwc": "lightning-tab",
222
+ "notes": "Use within lightning-tabset"
223
+ },
224
+ "apex:tabPanel": {
225
+ "lwc": "lightning-tabset",
226
+ "notes": "Container for lightning-tab components"
227
+ },
228
+ "apex:detail": {
229
+ "lwc": "lightning-record-form",
230
+ "notes": "Use lightning-record-form with mode='view' or 'edit'"
231
+ },
232
+ "apex:relatedList": {
233
+ "lwc": "lightning-related-list-view",
234
+ "notes": "Use lightning-related-list-view component"
235
+ },
236
+ "apex:enhancedList": {
237
+ "lwc": "lightning-datatable",
238
+ "notes": "Build custom datatable with search/filter"
239
+ },
240
+ "apex:iframe": {
241
+ "lwc": "iframe",
242
+ "notes": "Use standard iframe, be mindful of CSP restrictions"
243
+ },
244
+ "apex:image": {
245
+ "lwc": "img",
246
+ "notes": "Use standard img element, static resources via @salesforce/resourceUrl"
247
+ },
248
+ "apex:includeScript": {
249
+ "lwc": "loadScript",
250
+ "notes": "Use loadScript from lightning/platformResourceLoader"
251
+ },
252
+ "apex:stylesheet": {
253
+ "lwc": "loadStyle",
254
+ "notes": "Use loadStyle from lightning/platformResourceLoader"
255
+ },
256
+ "apex:slds": {
257
+ "lwc": null,
258
+ "notes": "SLDS is automatically available in LWC"
259
+ },
260
+ "apex:variable": {
261
+ "lwc": "class-property",
262
+ "notes": "Define as reactive class property"
263
+ },
264
+ "apex:param": {
265
+ "lwc": "custom-event-detail",
266
+ "notes": "Pass data via custom event detail or component properties"
267
+ }
268
+ },
269
+ "expressions": {
270
+ "controllerProperty": {
271
+ "pattern": "\\{!([a-zA-Z_][a-zA-Z0-9_]*)\\}",
272
+ "replacement": "{$1}",
273
+ "notes": "Controller properties become class properties"
274
+ },
275
+ "objectField": {
276
+ "pattern": "\\{!([a-zA-Z_][a-zA-Z0-9_]*)\\.([a-zA-Z_][a-zA-Z0-9_]*)\\}",
277
+ "replacement": "{$1.$2}",
278
+ "notes": "Object field access preserved"
279
+ },
280
+ "currentPage": {
281
+ "pattern": "\\{!\\$CurrentPage\\.parameters\\.(\\w+)\\}",
282
+ "replacement": "currentPageReference",
283
+ "notes": "Use CurrentPageReference wire adapter"
284
+ },
285
+ "label": {
286
+ "pattern": "\\{!\\$Label\\.(\\w+)\\.(\\w+)\\}",
287
+ "replacement": "@salesforce/label",
288
+ "notes": "Import labels using @salesforce/label/namespace.labelName"
289
+ },
290
+ "resource": {
291
+ "pattern": "\\{!\\$Resource\\.(\\w+)\\}",
292
+ "replacement": "@salesforce/resourceUrl",
293
+ "notes": "Import static resources using @salesforce/resourceUrl/resourceName"
294
+ },
295
+ "user": {
296
+ "pattern": "\\{!\\$User\\.(\\w+)\\}",
297
+ "replacement": "@salesforce/user",
298
+ "notes": "Use @salesforce/user/Id or getRecord with User object"
299
+ },
300
+ "objectType": {
301
+ "pattern": "\\{!\\$ObjectType\\.(\\w+)\\.fields\\.(\\w+)\\.label\\}",
302
+ "replacement": "@salesforce/schema",
303
+ "notes": "Import field info using @salesforce/schema/Object.Field"
304
+ }
305
+ },
306
+ "globalVariables": {
307
+ "$CurrentPage": {
308
+ "lwc": "CurrentPageReference",
309
+ "import": "import { CurrentPageReference } from 'lightning/navigation';",
310
+ "notes": "Wire CurrentPageReference to access page state"
311
+ },
312
+ "$User": {
313
+ "lwc": "@salesforce/user",
314
+ "import": "import userId from '@salesforce/user/Id';",
315
+ "notes": "Import user info from @salesforce/user"
316
+ },
317
+ "$Label": {
318
+ "lwc": "@salesforce/label",
319
+ "import": "import labelName from '@salesforce/label/c.LabelName';",
320
+ "notes": "Import each label individually"
321
+ },
322
+ "$Resource": {
323
+ "lwc": "@salesforce/resourceUrl",
324
+ "import": "import resourceName from '@salesforce/resourceUrl/ResourceName';",
325
+ "notes": "Import static resources"
326
+ },
327
+ "$Api": {
328
+ "lwc": "platformConstant",
329
+ "notes": "API version handled by platform"
330
+ },
331
+ "$Action": {
332
+ "lwc": null,
333
+ "notes": "Actions handled differently in LWC - use navigation or Apex"
334
+ }
335
+ },
336
+ "dataAccess": {
337
+ "controllerGetter": {
338
+ "lwc": "@wire",
339
+ "notes": "Read-only data uses wire service"
340
+ },
341
+ "actionMethod": {
342
+ "lwc": "imperative-apex",
343
+ "notes": "Methods that modify data use imperative Apex"
344
+ },
345
+ "remoteAction": {
346
+ "lwc": "imperative-apex",
347
+ "notes": "Remote actions become imperative Apex calls"
348
+ },
349
+ "actionFunction": {
350
+ "lwc": "imperative-apex",
351
+ "notes": "Action functions become imperative Apex calls"
352
+ }
353
+ }
354
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Parser for Aura JavaScript controller files
3
+ */
4
+ export interface AuraControllerFunction {
5
+ name: string;
6
+ params: string[];
7
+ body: string;
8
+ hasComponent: boolean;
9
+ hasEvent: boolean;
10
+ hasHelper: boolean;
11
+ usesGetSet: boolean;
12
+ serverCalls: AuraServerCall[];
13
+ eventFires: string[];
14
+ helperCalls: string[];
15
+ attributeAccess: AttributeAccess[];
16
+ }
17
+ export interface AuraServerCall {
18
+ actionName: string;
19
+ controllerMethod?: string;
20
+ params: string[];
21
+ callback?: string;
22
+ }
23
+ export interface AttributeAccess {
24
+ name: string;
25
+ operation: 'get' | 'set';
26
+ value?: string;
27
+ }
28
+ export interface ParsedAuraController {
29
+ functions: AuraControllerFunction[];
30
+ rawSource: string;
31
+ }
32
+ /**
33
+ * Parse Aura controller JavaScript
34
+ */
35
+ export declare function parseAuraController(source: string): ParsedAuraController;
36
+ //# sourceMappingURL=controller-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller-parser.d.ts","sourceRoot":"","sources":["../../../src/parsers/aura/controller-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,eAAe,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AA2ID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAmIxE"}
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ /**
3
+ * Parser for Aura JavaScript controller files
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.parseAuraController = parseAuraController;
43
+ const parser = __importStar(require("@babel/parser"));
44
+ const traverse_1 = __importDefault(require("@babel/traverse"));
45
+ const t = __importStar(require("@babel/types"));
46
+ const logger_1 = require("../../utils/logger");
47
+ /**
48
+ * Extract the body of a function as a string
49
+ */
50
+ function extractFunctionBody(node, source) {
51
+ if (node.body.start != null && node.body.end != null) {
52
+ // Get the body including braces
53
+ let body = source.substring(node.body.start, node.body.end);
54
+ // Remove outer braces and trim
55
+ body = body.replace(/^\{/, '').replace(/\}$/, '').trim();
56
+ return body;
57
+ }
58
+ return '';
59
+ }
60
+ /**
61
+ * Parse attribute access patterns like component.get("v.name") and component.set("v.name", value)
62
+ */
63
+ function parseAttributeAccess(path) {
64
+ const callee = path.node.callee;
65
+ if (!t.isMemberExpression(callee))
66
+ return null;
67
+ const property = callee.property;
68
+ if (!t.isIdentifier(property))
69
+ return null;
70
+ if (property.name !== 'get' && property.name !== 'set')
71
+ return null;
72
+ const args = path.node.arguments;
73
+ if (args.length === 0)
74
+ return null;
75
+ const firstArg = args[0];
76
+ if (!t.isStringLiteral(firstArg))
77
+ return null;
78
+ const attrPath = firstArg.value;
79
+ if (!attrPath.startsWith('v.'))
80
+ return null;
81
+ const attrName = attrPath.substring(2);
82
+ const operation = property.name;
83
+ return {
84
+ name: attrName,
85
+ operation,
86
+ };
87
+ }
88
+ /**
89
+ * Parse server action calls ($A.enqueueAction patterns)
90
+ */
91
+ function parseServerCall(path, _source) {
92
+ const callee = path.node.callee;
93
+ // Look for $A.enqueueAction(action) pattern
94
+ if (t.isMemberExpression(callee) &&
95
+ t.isIdentifier(callee.object, { name: '$A' }) &&
96
+ t.isIdentifier(callee.property, { name: 'enqueueAction' })) {
97
+ // This is the enqueue call, but we need to find the action setup
98
+ return {
99
+ actionName: 'enqueueAction',
100
+ params: [],
101
+ };
102
+ }
103
+ // Look for component.get("c.methodName") pattern - getting action
104
+ if (t.isMemberExpression(callee)) {
105
+ const property = callee.property;
106
+ if (t.isIdentifier(property, { name: 'get' })) {
107
+ const args = path.node.arguments;
108
+ if (args.length > 0 && t.isStringLiteral(args[0])) {
109
+ const value = args[0].value;
110
+ if (value.startsWith('c.')) {
111
+ return {
112
+ actionName: value,
113
+ controllerMethod: value.substring(2),
114
+ params: [],
115
+ };
116
+ }
117
+ }
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ /**
123
+ * Parse helper calls like helper.methodName(cmp, ...)
124
+ */
125
+ function parseHelperCall(path) {
126
+ const callee = path.node.callee;
127
+ if (t.isMemberExpression(callee) &&
128
+ t.isIdentifier(callee.object, { name: 'helper' }) &&
129
+ t.isIdentifier(callee.property)) {
130
+ return callee.property.name;
131
+ }
132
+ return null;
133
+ }
134
+ /**
135
+ * Parse event fire patterns like event.fire() or $A.get("e.c:MyEvent")
136
+ */
137
+ function parseEventFire(path) {
138
+ const callee = path.node.callee;
139
+ // Check for $A.get("e.c:EventName") pattern
140
+ if (t.isMemberExpression(callee) &&
141
+ t.isIdentifier(callee.object, { name: '$A' }) &&
142
+ t.isIdentifier(callee.property, { name: 'get' })) {
143
+ const args = path.node.arguments;
144
+ if (args.length > 0 && t.isStringLiteral(args[0])) {
145
+ const value = args[0].value;
146
+ if (value.startsWith('e.')) {
147
+ return value.substring(2);
148
+ }
149
+ }
150
+ }
151
+ // Check for component.getEvent("eventName") pattern
152
+ if (t.isMemberExpression(callee) &&
153
+ t.isIdentifier(callee.property, { name: 'getEvent' })) {
154
+ const args = path.node.arguments;
155
+ if (args.length > 0 && t.isStringLiteral(args[0])) {
156
+ return args[0].value;
157
+ }
158
+ }
159
+ return null;
160
+ }
161
+ /**
162
+ * Parse Aura controller JavaScript
163
+ */
164
+ function parseAuraController(source) {
165
+ const result = {
166
+ functions: [],
167
+ rawSource: source,
168
+ };
169
+ // Handle the Aura controller pattern: ({ functionName: function(cmp, event, helper) {...}, ... })
170
+ // We need to extract the object literal inside the parentheses
171
+ let objectSource = source.trim();
172
+ // Remove leading ( and trailing ) if present
173
+ if (objectSource.startsWith('(')) {
174
+ objectSource = objectSource.substring(1);
175
+ }
176
+ if (objectSource.endsWith(')')) {
177
+ objectSource = objectSource.substring(0, objectSource.length - 1);
178
+ }
179
+ // Wrap in a variable declaration for parsing
180
+ const wrappedSource = `const __auraController = ${objectSource}`;
181
+ let ast;
182
+ try {
183
+ ast = parser.parse(wrappedSource, {
184
+ sourceType: 'script',
185
+ plugins: [],
186
+ });
187
+ }
188
+ catch (error) {
189
+ logger_1.logger.warn(`Failed to parse controller: ${error.message}`);
190
+ return result;
191
+ }
192
+ // Traverse to find the object expression
193
+ (0, traverse_1.default)(ast, {
194
+ ObjectExpression(path) {
195
+ // Check if this is the top-level object
196
+ if (path.parent.type === 'VariableDeclarator' &&
197
+ t.isIdentifier(path.parent.id, {
198
+ name: '__auraController',
199
+ })) {
200
+ // Process each property (function)
201
+ for (const prop of path.node.properties) {
202
+ if (t.isObjectProperty(prop) &&
203
+ t.isIdentifier(prop.key) &&
204
+ t.isFunctionExpression(prop.value)) {
205
+ const funcName = prop.key.name;
206
+ const funcExpr = prop.value;
207
+ const funcDef = {
208
+ name: funcName,
209
+ params: funcExpr.params
210
+ .filter((p) => t.isIdentifier(p))
211
+ .map((p) => p.name),
212
+ body: extractFunctionBody(funcExpr, wrappedSource),
213
+ hasComponent: false,
214
+ hasEvent: false,
215
+ hasHelper: false,
216
+ usesGetSet: false,
217
+ serverCalls: [],
218
+ eventFires: [],
219
+ helperCalls: [],
220
+ attributeAccess: [],
221
+ };
222
+ // Check parameter names
223
+ funcDef.hasComponent = funcDef.params.some((p) => p === 'component' || p === 'cmp');
224
+ funcDef.hasEvent = funcDef.params.some((p) => p === 'event' || p === 'evt');
225
+ funcDef.hasHelper = funcDef.params.some((p) => p === 'helper');
226
+ // Traverse function body for patterns
227
+ const funcPath = path.get('properties').find((propPath) => {
228
+ const propNode = propPath.node;
229
+ return (t.isObjectProperty(propNode) &&
230
+ t.isIdentifier(propNode.key, { name: funcName }));
231
+ });
232
+ if (funcPath) {
233
+ funcPath.traverse({
234
+ CallExpression(callPath) {
235
+ // Check for attribute access
236
+ const attrAccess = parseAttributeAccess(callPath);
237
+ if (attrAccess) {
238
+ funcDef.usesGetSet = true;
239
+ funcDef.attributeAccess.push(attrAccess);
240
+ }
241
+ // Check for server calls
242
+ const serverCall = parseServerCall(callPath, wrappedSource);
243
+ if (serverCall) {
244
+ funcDef.serverCalls.push(serverCall);
245
+ }
246
+ // Check for helper calls
247
+ const helperCall = parseHelperCall(callPath);
248
+ if (helperCall) {
249
+ funcDef.helperCalls.push(helperCall);
250
+ }
251
+ // Check for event fires
252
+ const eventFire = parseEventFire(callPath);
253
+ if (eventFire) {
254
+ funcDef.eventFires.push(eventFire);
255
+ }
256
+ },
257
+ });
258
+ }
259
+ result.functions.push(funcDef);
260
+ logger_1.logger.debug(`Parsed controller function: ${funcName}(${funcDef.params.join(', ')})`);
261
+ }
262
+ }
263
+ }
264
+ },
265
+ });
266
+ logger_1.logger.debug(`Parsed ${result.functions.length} controller functions`);
267
+ return result;
268
+ }
269
+ //# sourceMappingURL=controller-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller-parser.js","sourceRoot":"","sources":["../../../src/parsers/aura/controller-parser.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmLH,kDAmIC;AApTD,sDAAwC;AACxC,+DAAqD;AACrD,gDAAkC;AAClC,+CAA4C;AAkC5C;;GAEG;AACH,SAAS,mBAAmB,CAAC,IAA0B,EAAE,MAAc;IACrE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;QACrD,gCAAgC;QAChC,IAAI,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAe,EAAE,IAAI,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;QAChF,+BAA+B;QAC/B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAgC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAEhC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAEpE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IACjC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;IAChC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAqB,CAAC;IAEjD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAgC,EAAE,OAAe;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAEhC,4CAA4C;IAC5C,IACE,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC5B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC7C,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAC1D,CAAC;QACD,iEAAiE;QACjE,OAAO;YACL,UAAU,EAAE,eAAe;YAC3B,MAAM,EAAE,EAAE;SACX,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,IAAI,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;YACjC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3B,OAAO;wBACL,UAAU,EAAE,KAAK;wBACjB,gBAAgB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;wBACpC,MAAM,EAAE,EAAE;qBACX,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAgC;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAEhC,IACE,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC5B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QACjD,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC/B,CAAC;QACD,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,IAAgC;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAEhC,4CAA4C;IAC5C,IACE,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC5B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC7C,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAChD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3B,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,IACE,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC5B,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EACrD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,MAAc;IAChD,MAAM,MAAM,GAAyB;QACnC,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,MAAM;KAClB,CAAC;IAEF,kGAAkG;IAClG,+DAA+D;IAE/D,IAAI,YAAY,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAEjC,6CAA6C;IAC7C,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,6CAA6C;IAC7C,MAAM,aAAa,GAAG,4BAA4B,YAAY,EAAE,CAAC;IAEjE,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;YAChC,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,eAAM,CAAC,IAAI,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,yCAAyC;IACzC,IAAA,kBAAQ,EAAC,GAAG,EAAE;QACZ,gBAAgB,CAAC,IAAI;YACnB,wCAAwC;YACxC,IACE,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB;gBACzC,CAAC,CAAC,YAAY,CAAE,IAAI,CAAC,MAA+B,CAAC,EAAE,EAAE;oBACvD,IAAI,EAAE,kBAAkB;iBACzB,CAAC,EACF,CAAC;gBACD,mCAAmC;gBACnC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACxC,IACE,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC;wBACxB,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;wBACxB,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,EAClC,CAAC;wBACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;wBAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;wBAE5B,MAAM,OAAO,GAA2B;4BACtC,IAAI,EAAE,QAAQ;4BACd,MAAM,EAAE,QAAQ,CAAC,MAAM;iCACpB,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;iCACnD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;4BACrB,IAAI,EAAE,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC;4BAClD,YAAY,EAAE,KAAK;4BACnB,QAAQ,EAAE,KAAK;4BACf,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,KAAK;4BACjB,WAAW,EAAE,EAAE;4BACf,UAAU,EAAE,EAAE;4BACd,WAAW,EAAE,EAAE;4BACf,eAAe,EAAE,EAAE;yBACpB,CAAC;wBAEF,wBAAwB;wBACxB,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,KAAK,CACxC,CAAC;wBACF,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,KAAK,CACpC,CAAC;wBACF,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;wBAE/D,sCAAsC;wBACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;4BACxD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC;4BAC/B,OAAO,CACL,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC;gCAC5B,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CACjD,CAAC;wBACJ,CAAC,CAAC,CAAC;wBAEH,IAAI,QAAQ,EAAE,CAAC;4BACb,QAAQ,CAAC,QAAQ,CAAC;gCAChB,cAAc,CAAC,QAAQ;oCACrB,6BAA6B;oCAC7B,MAAM,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;oCAClD,IAAI,UAAU,EAAE,CAAC;wCACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;wCAC1B,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oCAC3C,CAAC;oCAED,yBAAyB;oCACzB,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;oCAC5D,IAAI,UAAU,EAAE,CAAC;wCACf,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oCACvC,CAAC;oCAED,yBAAyB;oCACzB,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;oCAC7C,IAAI,UAAU,EAAE,CAAC;wCACf,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oCACvC,CAAC;oCAED,wBAAwB;oCACxB,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;oCAC3C,IAAI,SAAS,EAAE,CAAC;wCACd,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oCACrC,CAAC;gCACH,CAAC;6BACF,CAAC,CAAC;wBACL,CAAC;wBAED,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAC/B,eAAM,CAAC,KAAK,CACV,+BAA+B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACxE,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,eAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,SAAS,CAAC,MAAM,uBAAuB,CAAC,CAAC;IAEvE,OAAO,MAAM,CAAC;AAChB,CAAC"}