@pictogrammers/components 0.5.15 → 0.5.18

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 (149) hide show
  1. package/package.json +1 -1
  2. package/pg/autocompleteItem/__examples__/basic/basic.html +3 -0
  3. package/pg/autocompleteItem/autocompleteItem.css +55 -0
  4. package/pg/autocompleteItem/autocompleteItem.html +1 -0
  5. package/pg/autocompleteItem/autocompleteItem.ts +65 -0
  6. package/pg/button/button.css +5 -0
  7. package/pg/buttonMenu/buttonMenu.ts +1 -1
  8. package/pg/inputCombobox/__examples__/basic/basic.ts +33 -0
  9. package/pg/inputCombobox/inputCombobox.ts +158 -0
  10. package/pg/inputCombobox/inputCombobox.ts.tmp.44252.751480cb81cc +158 -0
  11. package/pg/inputCombobox/inputCombobox.ts.tmp.44252.dcea847c40a8 +156 -0
  12. package/pg/inputPill/inputPill.html +6 -0
  13. package/pg/inputPill/inputPill.html.tmp.26852.84ac63f4c46f +6 -0
  14. package/pg/inputPill/inputPill.ts +41 -0
  15. package/pg/inputPills/__examples__/basic/basic.html +9 -0
  16. package/pg/inputPills/__examples__/basic/basic.html.tmp.26852.4771e4cad5b7 +9 -0
  17. package/pg/inputPills/__examples__/basic/basic.ts.tmp.26852.d8fe41df18bd +0 -0
  18. package/pg/inputPixelEditor/README.md +104 -69
  19. package/pg/inputPixelEditor/README.md.tmp.42596.658de5f0a6f5 +0 -0
  20. package/pg/inputPixelEditor/__examples__/basic/basic.ts +6 -5
  21. package/pg/inputPixelEditor/inputPixelEditor.ts +96 -24
  22. package/pg/inputPixelEditor/inputPixelEditor.ts.tmp.38516.96529dd82670 +1703 -0
  23. package/pg/inputPixelEditor/inputPixelEditor.ts.tmp.42596.48ecc3ad9c72 +1724 -0
  24. package/pg/inputPixelEditor/utils/bitmapToMask.ts +113 -79
  25. package/pg/inputPixelEditor/utils/getLassoPixels.ts +51 -0
  26. package/pg/inputSelect/inputSelect.ts +5 -1
  27. package/pg/inputText/README.md +6 -6
  28. package/pg/inputText/__examples__/basic/basic.ts +1 -1
  29. package/pg/inputText/inputText.css +2 -2
  30. package/pg/inputText copy/README.md +38 -0
  31. package/pg/inputText copy/inputText.css +41 -0
  32. package/pg/inputText copy/inputText.html +1 -0
  33. package/pg/inputText copy/inputText.spec.ts +59 -0
  34. package/pg/inputText copy/inputText.ts +67 -0
  35. package/pg/inputTextarea/README.md +39 -0
  36. package/pg/inputTextarea/__examples__/basic/basic.html +9 -0
  37. package/pg/inputTextarea/__examples__/basic/basic.ts +30 -0
  38. package/pg/inputTextarea/inputTextarea.ts +121 -0
  39. package/pg/inputTextarea copy/README.md +39 -0
  40. package/pg/inputTextarea copy/inputTextarea.css +41 -0
  41. package/pg/inputTextarea copy/inputTextarea.html +1 -0
  42. package/pg/inputTextarea copy/inputTextarea.spec.ts +59 -0
  43. package/pg/inputTextarea copy/inputTextarea.ts +79 -0
  44. package/pg/inputTextareaAutocomplete/README.md +70 -0
  45. package/pg/inputTextareaAutocomplete/__examples__/basic/basic.ts +67 -0
  46. package/pg/inputTextareaAutocomplete/inputTextareaAutocomplete.ts +267 -0
  47. package/pg/node/README.md +35 -0
  48. package/pg/node/__examples__/basic/basic.ts +34 -0
  49. package/pg/node/index.ts +3 -0
  50. package/pg/node/node.css +53 -0
  51. package/pg/node/node.html +5 -0
  52. package/pg/node/node.ts +270 -0
  53. package/pg/nodeEditorLink/nodeEditorLink.css +69 -0
  54. package/pg/nodeEditorLink/nodeEditorLink.css.tmp.1408.09e961fd0dcc +69 -0
  55. package/pg/nodeEditorLink/nodeEditorLink.html +9 -0
  56. package/pg/nodeEditorNumber/nodeEditorNumber.css +59 -0
  57. package/pg/nodeEditorNumber/nodeEditorNumber.ts +57 -0
  58. package/pg/nodeEditorRange/nodeEditorRange.css +23 -0
  59. package/pg/nodeEditorRange/nodeEditorRange.ts +69 -0
  60. package/pg/nodeEditorText/__examples__/basic/basic.html +9 -0
  61. package/pg/nodeEditorText/__examples__/basic/basic.ts +30 -0
  62. package/pg/nodeEditorText/nodeEditorText.css +17 -0
  63. package/pg/nodeEditorText/nodeEditorText.html +4 -0
  64. package/pg/nodeEditorText/nodeEditorText.ts +57 -0
  65. package/pg/nodeEditorText copy/README.md +35 -0
  66. package/pg/nodeEditorText copy/nodeEditorText.css +49 -0
  67. package/pg/nodeEditorText copy/nodeEditorText.html +4 -0
  68. package/pg/nodeEditorText copy/nodeEditorText.ts +50 -0
  69. package/pg/nodeEditorTextArray/nodeEditorTextArray.css +68 -0
  70. package/pg/nodeEditorTextArray/nodeEditorTextArray.html +9 -0
  71. package/pg/nodeEditorTextArray/nodeEditorTextArray.ts +162 -0
  72. package/pg/nodeEntry/nodeEntry.css +61 -0
  73. package/pg/nodeEntry/nodeEntry.ts +164 -0
  74. package/pg/nodeEntry/nodeEntry.ts.tmp.28724.dda67762bca5 +164 -0
  75. package/pg/nodeInputText/nodeInputText.css +75 -0
  76. package/pg/nodeInputText/nodeInputText.html +4 -0
  77. package/pg/nodeInputText/nodeInputText.ts +105 -0
  78. package/pg/nodeOutput/nodeOutput.css +32 -0
  79. package/pg/nodeResize/README.md +3 -0
  80. package/pg/nodeResize/THINKING.md +81 -0
  81. package/pg/nodeResize/THINKING.md.tmp.24812.99a70ba81062 +81 -0
  82. package/pg/nodeResize/basic/basic.ts +17 -0
  83. package/pg/nodeResize/dragUtil.ts +105 -0
  84. package/pg/nodeResize/dragUtil.ts.tmp.34372.787464c73309 +75 -0
  85. package/pg/nodeResize/nodeResize.css +187 -0
  86. package/pg/nodeResize/nodeResize.html +9 -0
  87. package/pg/nodeResize/nodeResize.ts +156 -0
  88. package/pg/nodes/README.md +177 -0
  89. package/pg/nodes/__examples__/basic/basic.html +33 -0
  90. package/pg/nodes/__examples__/basic/basic.ts +716 -0
  91. package/pg/nodes/__examples__/basic/exampleNodes.ts +129 -0
  92. package/pg/nodes/__examples__/basic/exampleScripts.ts +129 -0
  93. package/pg/nodes/__examples__/basic/keystore.ts +38 -0
  94. package/pg/nodes/executeInSandbox.ts +32 -0
  95. package/pg/nodes/index.ts +3 -0
  96. package/pg/nodes/nodes.css +69 -0
  97. package/pg/nodes/nodes.html +6 -0
  98. package/pg/nodes/nodes.ts +1240 -0
  99. package/pg/nodes copy/nodes.css +41 -0
  100. package/pg/nodes copy/nodes.html +1 -0
  101. package/pg/overlayContextMenu/__examples__/filter/filter.ts +87 -0
  102. package/pg/overlayContextMenu/overlayContextMenu.css +14 -0
  103. package/pg/overlayContextMenu/overlayContextMenu.html +4 -3
  104. package/pg/overlayContextMenu/overlayContextMenu.ts +6 -2
  105. package/pg/overlayContextMenu/overlayContextMenu.ts.tmp.37088.530ff1c0a321 +0 -0
  106. package/pg/overlayMenu/overlayMenu.css +3 -1
  107. package/pg/overlayMenu/overlayMenu.ts +11 -2
  108. package/pg/overlayMenu/overlayMenu.ts.tmp.44252.9bb22fd59ede +80 -0
  109. package/pg/overlaySelectMenu/overlaySelectMenu.css +2 -0
  110. package/pg/overlaySubMenu/overlaySubMenu.css +8 -6
  111. package/pg/poco/README.md +22 -0
  112. package/pg/poco/__examples__/basic/basic.html +11 -0
  113. package/pg/poco/__examples__/basic/basic.ts +95 -0
  114. package/pg/poco/__examples__/basic/examples.ts +258 -0
  115. package/pg/poco/__examples__/basic/myFont.ts +1300 -0
  116. package/pg/poco/index.ts +3 -0
  117. package/pg/poco/mockPoco.ts +640 -0
  118. package/pg/poco/poco.css +7 -0
  119. package/pg/poco/poco.html +1 -0
  120. package/pg/poco/poco.ts +75 -0
  121. package/pg/popover/README.md +47 -0
  122. package/pg/popover/__examples__/basic/basic.html +3 -0
  123. package/pg/popover/popover.html +3 -0
  124. package/pg/popover/popover.ts +44 -0
  125. package/pg/popoverAutocomplete/__examples__/basic/basic.html +4 -0
  126. package/pg/popoverAutocomplete/__examples__/basic/basic.ts +46 -0
  127. package/pg/popoverAutocomplete/popoverAutocomplete.css +25 -0
  128. package/pg/popoverAutocomplete/popoverAutocomplete.html +1 -0
  129. package/pg/popoverAutocomplete/popoverAutocomplete.ts +134 -0
  130. package/pg/popoverAutocompleteItem/popoverAutocompleteItem.css +69 -0
  131. package/pg/popoverAutocompleteItem/popoverAutocompleteItem.ts +90 -0
  132. package/pg/table/__examples__/basic/basic.ts +1 -0
  133. package/pg/tableCellFileLocal/tableCellFileLocal.html +3 -0
  134. package/pg/tableCellFileLocal/tableCellFileLocal.html.tmp.20484.68ee2e30710e +3 -0
  135. package/pg/tableCellFileLocal/tableCellFileLocal.ts +44 -0
  136. package/pg/tableCellSelect/tableCellSelect.html +3 -0
  137. package/pg/tableCellSelect/tableCellSelect.html.tmp.41808.99c1a6f14340 +3 -0
  138. package/pg/tableCellSelect/tableCellSelect.ts +51 -0
  139. package/pg/tree/__examples__/basic/basic.ts +12 -5
  140. package/pg/tree/tree.html +1 -1
  141. package/pg/tree/tree.ts +385 -227
  142. package/pg/tree/tree.ts.tmp.38376.07d376a04f41 +343 -0
  143. package/pg/tree/tree.ts.tmp.38376.2a04599ade9f +361 -0
  144. package/pg/tree/tree.ts.tmp.38376.6cb2c663d476 +0 -0
  145. package/pg/tree/tree.ts.tmp.38376.ac5af1aff2b0 +393 -0
  146. package/pg/tree/tree.ts.tmp.38376.ac9acfc4f95f +324 -0
  147. package/pg/treeItem/treeItem.ts +536 -558
  148. package/pg/treeItem/treeItem.ts.tmp.38376.145d3121d648 +530 -0
  149. package/pg/treeItem/treeItem.ts.tmp.38376.b5224d48e5c0 +0 -0
@@ -0,0 +1,716 @@
1
+ import { Component, Part, Local } from '@pictogrammers/element';
2
+ import PgNodes from '../../nodes';
3
+
4
+ import template from './basic.html';
5
+ import PgNodeEditorText from 'components/pg/nodeEditorText/nodeEditorText';
6
+ import PgNodeEditorRange from 'components/pg/nodeEditorRange/nodeEditorRange';
7
+ import PgNodeEditorNumber from 'components/pg/nodeEditorNumber/nodeEditorNumber';
8
+ import PgInputSelect from 'components/pg/inputSelect/inputSelect';
9
+ import PgNodeEditorTextArray from 'components/pg/nodeEditorTextArray/nodeEditorTextArray';
10
+ import PgNodeEditorLink from 'components/pg/nodeEditorLink/nodeEditorLink';
11
+ import { KeyStore } from './keystore';
12
+
13
+ @Component({
14
+ selector: 'x-pg-nodes-basic',
15
+ template,
16
+ })
17
+ export default class XPgNodesBasic extends HTMLElement {
18
+
19
+ @Part() $script: PgNodes;
20
+ @Part() $state: HTMLPreElement;
21
+ @Part() $log: HTMLPreElement;
22
+
23
+ @Part() $files: PgInputSelect;
24
+ @Part() $save: HTMLButtonElement;
25
+ @Part() $open: HTMLButtonElement;
26
+ @Part() $new: HTMLButtonElement;
27
+
28
+ @Part() $debug: HTMLButtonElement;
29
+ @Part() $debugNext: HTMLButtonElement;
30
+ @Part() $play: HTMLButtonElement;
31
+ @Part() $restart: HTMLButtonElement;
32
+ @Part() $fullscreen: HTMLButtonElement;
33
+
34
+ @Local('nodes.basic') store = new Map<string, any>([
35
+ ['list', []]
36
+ ]);
37
+
38
+ #state = new KeyStore();
39
+
40
+ connectedCallback() {
41
+ // State
42
+ this.#state.add({ name: '' });
43
+ // Wire up script
44
+ this.$script.state = this.#state;
45
+ this.$script.globals.push([
46
+ 'trace',
47
+ (message) => {
48
+ this.$log.appendChild(document.createTextNode(`${message}\n`));
49
+ }
50
+ ]);
51
+ // Node Editors
52
+ this.$script.editors.push(PgNodeEditorText);
53
+ this.$script.editors.push(PgNodeEditorNumber);
54
+ this.$script.editors.push(PgNodeEditorRange);
55
+ this.$script.editors.push(PgNodeEditorTextArray);
56
+ this.$script.editors.push(PgNodeEditorLink);
57
+ // Node type registry
58
+ this.$script.nodes.push({
59
+ name: 'stateHas',
60
+ label: 'Has',
61
+ width: 6,
62
+ args: [{
63
+ key: 'key',
64
+ label: 'Key',
65
+ editor: 'Text',
66
+ value: '',
67
+ }],
68
+ nodes: [{
69
+ key: 't',
70
+ label: 'True',
71
+ }, {
72
+ key: 'f',
73
+ label: 'False',
74
+ }],
75
+ handler: ({ state, key, t, f }: any) => {
76
+ return state.has(key) ? t : f;
77
+ },
78
+ }, {
79
+ name: 'stateAdd',
80
+ label: 'Add',
81
+ width: 6,
82
+ args: [{
83
+ key: 'key',
84
+ label: 'Key',
85
+ editor: 'Text',
86
+ value: '',
87
+ }, {
88
+ key: 'value',
89
+ label: 'Value',
90
+ editor: 'Number',
91
+ value: 0,
92
+ }],
93
+ nodes: [{
94
+ key: 'then',
95
+ label: 'Then',
96
+ }],
97
+ handler: ({ state, key, node, then, value }: any) => {
98
+ const current = parseFloat(state.get(key) ?? 0);
99
+ state.set(key, current + value);
100
+ state.delete('$state');
101
+ return then;
102
+ },
103
+ }, {
104
+ name: 'link',
105
+ label: 'Link',
106
+ width: 6,
107
+ args: [{
108
+ key: 'link',
109
+ label: 'Link',
110
+ editor: 'Link',
111
+ value: 0,
112
+ }],
113
+ nodes: [],
114
+ handler: ({ state, link }: any) => {
115
+ return link;
116
+ },
117
+ }, {
118
+ name: 'stateSet',
119
+ label: 'Set',
120
+ width: 6,
121
+ args: [{
122
+ key: 'value',
123
+ label: 'Value',
124
+ editor: 'Text',
125
+ value: '',
126
+ }],
127
+ nodes: [{
128
+ key: 'then',
129
+ label: 'Then',
130
+ }],
131
+ handler: ({ state, then, value }: any) => {
132
+ if (!state.has('$state')) {
133
+ throw new Error('Missing get before set');
134
+ }
135
+ const key = state.get('$state');
136
+ state.set(key, value);
137
+ state.delete('$state');
138
+ return then;
139
+ },
140
+ }, {
141
+ name: 'equals',
142
+ label: 'Equals',
143
+ width: 10,
144
+ args: [{
145
+ key: 'value',
146
+ label: 'Value',
147
+ editor: 'Text',
148
+ value: '',
149
+ }],
150
+ nodes: [{
151
+ key: 't',
152
+ label: 'True',
153
+ }, {
154
+ key: 'f',
155
+ label: 'False',
156
+ }],
157
+ handler: ({ state, t, f, value }: any) => {
158
+ if (!state.has('$state')) {
159
+ throw new Error('Missing get before equals');
160
+ }
161
+ const key = state.get('$state');
162
+ if (state.get(key) === String(value)) {
163
+ return t;
164
+ } else {
165
+ return f;
166
+ }
167
+ },
168
+ }, {
169
+ name: 'lessThan',
170
+ label: 'Less Than',
171
+ width: 10,
172
+ args: [{
173
+ key: 'value',
174
+ label: 'Value',
175
+ editor: 'Number',
176
+ value: 0,
177
+ }],
178
+ nodes: [{
179
+ key: 't',
180
+ label: 'True',
181
+ }, {
182
+ key: 'f',
183
+ label: 'False',
184
+ }],
185
+ handler: ({ state, t, f, value }: any) => {
186
+ if (!state.has('$state')) {
187
+ throw new Error('Missing get before lessThan');
188
+ }
189
+ const key = state.get('$state');
190
+ if (parseFloat(state.get(key)) < value) {
191
+ return t;
192
+ } else {
193
+ return f;
194
+ }
195
+ },
196
+ }, {
197
+ name: 'lessThanOrEqual',
198
+ label: 'Less Than or Equal',
199
+ width: 10,
200
+ args: [{
201
+ key: 'value',
202
+ label: 'Value',
203
+ editor: 'Number',
204
+ value: 0,
205
+ }],
206
+ nodes: [{
207
+ key: 't',
208
+ label: 'True',
209
+ }, {
210
+ key: 'f',
211
+ label: 'False',
212
+ }],
213
+ handler: ({ state, t, f, value }: any) => {
214
+ if (!state.has('$state')) {
215
+ throw new Error('Missing get before lessThanOrEqual');
216
+ }
217
+ const key = state.get('$state');
218
+ if (parseFloat(state.get(key)) <= value) {
219
+ return t;
220
+ } else {
221
+ return f;
222
+ }
223
+ },
224
+ }, {
225
+ name: 'greaterThan',
226
+ label: 'Greater Than',
227
+ width: 10,
228
+ args: [{
229
+ key: 'value',
230
+ label: 'Value',
231
+ editor: 'Number',
232
+ value: 0,
233
+ }],
234
+ nodes: [{
235
+ key: 't',
236
+ label: 'True',
237
+ }, {
238
+ key: 'f',
239
+ label: 'False',
240
+ }],
241
+ handler: ({ state, t, f, value }: any) => {
242
+ if (!state.has('$state')) {
243
+ throw new Error('Missing get before greaterThan');
244
+ }
245
+ const key = state.get('$state');
246
+ if (parseFloat(state.get(key)) > value) {
247
+ return t;
248
+ } else {
249
+ return f;
250
+ }
251
+ },
252
+ }, {
253
+ name: 'greaterThanOrEqual',
254
+ label: 'Greater Than or Equal',
255
+ width: 10,
256
+ args: [{
257
+ key: 'value',
258
+ label: 'Value',
259
+ editor: 'Number',
260
+ value: 0,
261
+ }],
262
+ nodes: [{
263
+ key: 't',
264
+ label: 'True',
265
+ }, {
266
+ key: 'f',
267
+ label: 'False',
268
+ }],
269
+ handler: ({ state, t, f, value }: any) => {
270
+ if (!state.has('$state')) {
271
+ throw new Error('Missing get before greaterThanOrEqual');
272
+ }
273
+ const key = state.get('$state');
274
+ if (parseFloat(state.get(key)) >= value) {
275
+ return t;
276
+ } else {
277
+ return f;
278
+ }
279
+ },
280
+ }, {
281
+ name: 'log',
282
+ label: 'Log',
283
+ width: 12,
284
+ args: [{
285
+ key: 'message',
286
+ label: 'Message',
287
+ editor: 'Text',
288
+ value: '',
289
+ }],
290
+ nodes: [{
291
+ key: 'then',
292
+ label: 'Then',
293
+ }],
294
+ handler: ({ then, message }: any) => {
295
+ this.$log.appendChild(document.createTextNode(`${message}\n`));
296
+ return then;
297
+ },
298
+ }, {
299
+ name: 'coin',
300
+ label: 'Coin Flip',
301
+ args: [],
302
+ nodes: [{
303
+ key: 't',
304
+ label: 'True',
305
+ }, {
306
+ key: 'f',
307
+ label: 'False',
308
+ }],
309
+ handler: ({ t, f }: any) => {
310
+ return Math.random() < 0.5 ? t : f;
311
+ },
312
+ }, {
313
+ name: 'some',
314
+ label: 'Some',
315
+ width: 10,
316
+ args: [{
317
+ key: 'keys',
318
+ label: 'Keys',
319
+ editor: 'TextArray',
320
+ value: [''],
321
+ }],
322
+ nodes: [{
323
+ key: 't',
324
+ label: 'True',
325
+ }, {
326
+ key: 'f',
327
+ label: 'False',
328
+ }],
329
+ handler: ({ state, keys, t, f }: any) => {
330
+ return keys.some((key) => state.has(key)) ? t : f;
331
+ },
332
+ }, {
333
+ name: 'every',
334
+ label: 'Every',
335
+ width: 10,
336
+ args: [{
337
+ key: 'keys',
338
+ label: 'Keys',
339
+ editor: 'TextArray',
340
+ value: [''],
341
+ }],
342
+ nodes: [{
343
+ key: 't',
344
+ label: 'True',
345
+ }, {
346
+ key: 'f',
347
+ label: 'False',
348
+ }],
349
+ handler: ({ state, keys, t, f }: any) => {
350
+ return keys.every((key) => state.has(key)) ? t : f;
351
+ },
352
+ }, {
353
+ name: 'isTrue',
354
+ label: 'Is True',
355
+ width: 4,
356
+ args: [],
357
+ nodes: [{
358
+ key: 't',
359
+ label: 'True',
360
+ }, {
361
+ key: 'f',
362
+ label: 'False',
363
+ }],
364
+ handler: ({ state, t, f }: any) => {
365
+ if (!state.has('$state')) {
366
+ throw new Error('Missing get before isTrue');
367
+ }
368
+ const key = state.get('$state');
369
+ if (state.has(key) && state.get(key) === true) {
370
+ return t;
371
+ } else {
372
+ return f;
373
+ }
374
+ },
375
+ }, {
376
+ name: 'isFalse',
377
+ label: 'Is False',
378
+ width: 4,
379
+ args: [],
380
+ nodes: [{
381
+ key: 't',
382
+ label: 'True',
383
+ }, {
384
+ key: 'f',
385
+ label: 'False',
386
+ }],
387
+ handler: ({ state, t, f }: any) => {
388
+ if (!state.has('$state')) {
389
+ throw new Error('Missing get before isFalse');
390
+ }
391
+ const key = state.get('$state');
392
+ if (state.has(key) && state.get(key) === true) {
393
+ return t;
394
+ } else {
395
+ return f;
396
+ }
397
+ },
398
+ }, {
399
+ name: 'random',
400
+ label: 'Random',
401
+ width: 6,
402
+ args: [],
403
+ nodes: [{
404
+ key: 'options',
405
+ label: 'Options',
406
+ }],
407
+ handler: ({ state, options }: any) => {
408
+ if (!state.has('$random')) {
409
+ state.set('$random', []);
410
+ return options;
411
+ }
412
+ const values = state.get('$random');
413
+ if (values.length !== options.length) {
414
+ return [];
415
+ }
416
+ function weightedRandom<T extends { weight: string, then: number[] }>(items: T[]): T {
417
+ const totalWeight = items.reduce((sum, item) => sum + Number(item.weight), 0);
418
+ let random = Math.random() * totalWeight;
419
+
420
+ for (const item of items) {
421
+ random -= Number(item.weight);
422
+ if (random <= 0) return item;
423
+ }
424
+
425
+ return items[items.length - 1]; // fallback
426
+ }
427
+ state.delete('$random');
428
+ return weightedRandom(values).then;
429
+ },
430
+ }, {
431
+ name: 'randomOption',
432
+ label: 'Random Option',
433
+ width: 8,
434
+ args: [{
435
+ key: 'weight',
436
+ label: 'Weight',
437
+ editor: 'Number',
438
+ value: 1,
439
+ }],
440
+ nodes: [{
441
+ key: 'then',
442
+ label: 'Then',
443
+ }],
444
+ handler: ({ state, then, node, weight, options }: any) => {
445
+ if (!state.has('$random')) {
446
+ throw new Error('invalid node');
447
+ }
448
+ const values = state.get('$random');
449
+ values.push({
450
+ weight: weight ?? 0,
451
+ then,
452
+ });
453
+ return [node];
454
+ },
455
+ }, {
456
+ name: 'dialog',
457
+ label: 'Dialog',
458
+ width: 12,
459
+ args: [{
460
+ key: 'message',
461
+ label: 'Message',
462
+ editor: 'Text',
463
+ value: 'Hello',
464
+ }],
465
+ nodes: [{
466
+ key: 'then',
467
+ label: 'Then',
468
+ }, {
469
+ key: 'options',
470
+ label: 'Options',
471
+ }],
472
+ handler: ({ nodeId, state, message, then, options }: any) => {
473
+ if (!state.has('$dialog')) {
474
+ state.set('$dialog', []);
475
+ return [...options, nodeId, ...then];
476
+ }
477
+ const values = state.get('$dialog');
478
+ state.delete('$dialog');
479
+ return new Promise((resolve) => {
480
+ if (values.length) {
481
+ const options = values.map((v, i) => `${i}. ${v.message}`).join('\n');
482
+ const result = window.prompt(`${message}\n${options}`);
483
+ const value = values[parseInt(result || '0', 10)];
484
+ resolve(value.then);
485
+ } else {
486
+ window.alert(message);
487
+ resolve([]);
488
+ }
489
+ });
490
+ },
491
+ }, {
492
+ name: 'dialogOption',
493
+ label: 'Dialog Option',
494
+ width: 12,
495
+ args: [{
496
+ key: 'message',
497
+ label: 'Message',
498
+ editor: 'Text',
499
+ value: 'Reply',
500
+ }],
501
+ nodes: [{
502
+ key: 'then',
503
+ label: 'Then',
504
+ }],
505
+ handler: ({ state, then, message }: any) => {
506
+ if (!state.has('$dialog')) {
507
+ throw new Error('invalid node');
508
+ }
509
+ const values = state.get('$dialog');
510
+ values.push({
511
+ message: message ?? '',
512
+ then,
513
+ });
514
+ return [];
515
+ },
516
+ }, {
517
+ name: 'dialogSkip',
518
+ label: 'Dialog Skip',
519
+ width: 6,
520
+ args: [],
521
+ nodes: [],
522
+ handler: ({ state }: any) => {
523
+ if (!state.has('$dialog')) {
524
+ throw new Error('invalid node');
525
+ }
526
+ return [];
527
+ },
528
+ });
529
+ // Items
530
+ this.$script.items.push({
531
+ id: 0,
532
+ x: 2,
533
+ y: 2,
534
+ width: 12,
535
+ height: 4,
536
+ args: {
537
+ description: 'Basic example.',
538
+ },
539
+ nodes: {
540
+ then: [1],
541
+ },
542
+ });
543
+ this.$script.items.push({
544
+ id: 1,
545
+ x: 16,
546
+ y: 2,
547
+ node: 'lessThan',
548
+ args: {
549
+ key: 'health',
550
+ value: 5,
551
+ },
552
+ nodes: {
553
+ t: [2],
554
+ f: [3],
555
+ },
556
+ });
557
+ this.$script.items.push({
558
+ id: 2,
559
+ x: 30,
560
+ y: 2,
561
+ node: 'stateSet',
562
+ args: {
563
+ value: '10',
564
+ },
565
+ nodes: {
566
+ then: [4],
567
+ },
568
+ });
569
+ this.$script.items.push({
570
+ id: 3,
571
+ x: 30,
572
+ y: 10,
573
+ node: 'stateSet',
574
+ args: {
575
+ value: '20',
576
+ },
577
+ nodes: {
578
+ then: [4],
579
+ },
580
+ });
581
+ this.$script.items.push({
582
+ id: 4,
583
+ x: 44,
584
+ y: 8,
585
+ node: 'log',
586
+ args: {
587
+ message: "Health increased to ${state.get('health')}",
588
+ },
589
+ nodes: {
590
+ then: [],
591
+ },
592
+ });
593
+ this.$script.addEventListener('debug', this.#handleDebug.bind(this));
594
+ this.$script.addEventListener('change', this.#handleChange.bind(this));
595
+ this.$script.addEventListener('input', this.#handleInput.bind(this));
596
+ this.$debug.addEventListener('click', this.#handleButtonDebug.bind(this));
597
+ this.$debugNext.addEventListener('click', this.#handleDebugNext.bind(this));
598
+ this.$play.addEventListener('click', this.#handlePlay.bind(this));
599
+ this.$restart.addEventListener('click', this.#handleRestart.bind(this));
600
+ this.$save.addEventListener('click', this.#handleSave.bind(this));
601
+ this.$open.addEventListener('click', this.#handleOpen.bind(this));
602
+ this.$new.addEventListener('click', this.#handleNew.bind(this));
603
+ this.$files.addEventListener('change', this.#handleFilesChange.bind(this));
604
+ this.$fullscreen.addEventListener('click', this.#handleFullscreen.bind(this));
605
+ this.#initFiles();
606
+ }
607
+
608
+ #handleChange(_e: CustomEvent) {}
609
+
610
+ #handleInput(_e: CustomEvent) {}
611
+
612
+ #handleButtonDebug(_e: CustomEvent) {
613
+ this.$script.debug();
614
+ }
615
+
616
+ #handleDebug(e: any) {
617
+ const { state } = e.detail;
618
+ this.$state.replaceChildren(Array.from(state).map((args: string[]) => {
619
+ return `${args[0]} = ${args[1]}`;
620
+ }).join('\n'));
621
+ }
622
+
623
+ #handleDebugNext(_e: CustomEvent) {
624
+ this.$script.debugNext();
625
+ }
626
+
627
+ #handlePlay(_e: CustomEvent) {
628
+ this.$script.play();
629
+ }
630
+
631
+ #handleRestart(_e: CustomEvent) {
632
+ this.$script.restart();
633
+ }
634
+
635
+ #initFiles() {
636
+ const list = this.store.get('list');
637
+ list.forEach((value) => {
638
+ const items = JSON.parse(value);
639
+ const { description } = items[0].args;
640
+ this.$files.options.push({
641
+ label: description,
642
+ value: value,
643
+ });
644
+ });
645
+ if (list.length > 0) {
646
+ this.$files.value = list[0];
647
+ }
648
+ }
649
+
650
+ #handleSave(e: CustomEvent) {
651
+ const list = this.store.get('list');
652
+ const { description: newDescription } = this.$script.items[0].args;
653
+ // Search for index
654
+ const index = list.findIndex((value) => {
655
+ const items = JSON.parse(value);
656
+ const { description } = items[0].args;
657
+ return newDescription === description;
658
+ });
659
+ if (index === -1) {
660
+ list?.push(this.$script.json);
661
+ } else {
662
+ list[index] = this.$script.json;
663
+ }
664
+ this.store.set('list', list);
665
+ // update list
666
+ if (index === -1) {
667
+ this.$files.options.push({
668
+ label: newDescription,
669
+ value: this.$script.json,
670
+ });
671
+ } else {
672
+ this.$files.options.splice(index, 1, {
673
+ label: newDescription,
674
+ value: this.$script.json,
675
+ });
676
+ }
677
+ // select
678
+ this.$files.value = this.$script.json;
679
+ }
680
+
681
+ #handleOpen(e: CustomEvent) {
682
+ this.$script.json = this.$files.value;
683
+ }
684
+
685
+ #handleNew(e: CustomEvent) {
686
+ this.$script.json = '[{"id":0,"x":2,"y":2,"width":12,"height":4,"args":{"description":"New script"},"nodes":{"then":[]}}]'
687
+ }
688
+
689
+ #handleFilesChange(e: CustomEvent) {
690
+ this.$files.value = e.detail.value;
691
+ this.$script.json = e.detail.value;
692
+ }
693
+
694
+ #handleFullscreen() {
695
+
696
+ const handler = () => {
697
+ if (document.fullscreenElement) {
698
+ this.$script.style.setProperty('position', 'fixed');
699
+ this.$script.style.setProperty('top', '0');
700
+ this.$script.style.setProperty('bottom', '0');
701
+ this.$script.style.setProperty('left', '0');
702
+ this.$script.style.setProperty('right', '0');
703
+ } else {
704
+ this.$script.style.removeProperty('position');
705
+ this.$script.style.removeProperty('top');
706
+ this.$script.style.removeProperty('bottom');
707
+ this.$script.style.removeProperty('left');
708
+ this.$script.style.removeProperty('right');
709
+ document.body.removeEventListener("fullscreenchange", handler);
710
+ }
711
+ }
712
+ document.body.addEventListener("fullscreenchange", handler);
713
+
714
+ document.body.requestFullscreen();
715
+ }
716
+ }