pict-section-formeditor 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 (178) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/README.md +162 -0
  5. package/docs/_sidebar.md +23 -0
  6. package/docs/_topbar.md +5 -0
  7. package/docs/cover.md +12 -0
  8. package/docs/css/docuserve.css +73 -0
  9. package/docs/index.html +39 -0
  10. package/docs/retold-catalog.json +224 -0
  11. package/docs/retold-keyword-index.json +46846 -0
  12. package/example_applications/form_editor/.quackage.json +10 -0
  13. package/example_applications/form_editor/FormEditor-Example-Application.js +226 -0
  14. package/example_applications/form_editor/html/icon-chooser.html +375 -0
  15. package/example_applications/form_editor/html/index.html +54 -0
  16. package/example_applications/form_editor/package.json +50 -0
  17. package/package.json +55 -0
  18. package/sample_manifests/Complex-Table.json +974 -0
  19. package/sample_manifests/Distill-Example.json +200 -0
  20. package/sample_manifests/Gradebook-Assignment.json +38 -0
  21. package/sample_manifests/Gradebook-Student.json +40 -0
  22. package/sample_manifests/Manyfest-Editor.json +347 -0
  23. package/sample_manifests/Simple-Form.json +232 -0
  24. package/sample_manifests/Simple-Table.json +79 -0
  25. package/source/Pict-Section-FormEditor-DefaultConfiguration.js +3321 -0
  26. package/source/Pict-Section-FormEditor.js +35 -0
  27. package/source/providers/Pict-Provider-ChildPictManager-Application.js +40 -0
  28. package/source/providers/Pict-Provider-ChildPictManager.js +238 -0
  29. package/source/providers/Pict-Provider-FormEditorDocumentation.js +356 -0
  30. package/source/providers/Pict-Provider-FormEditorDragDrop.js +535 -0
  31. package/source/providers/Pict-Provider-FormEditorIconography.js +1002 -0
  32. package/source/providers/Pict-Provider-FormEditorManifestOps.js +1443 -0
  33. package/source/providers/Pict-Provider-FormEditorRendering.js +730 -0
  34. package/source/providers/Pict-Provider-FormEditorUtilities.js +862 -0
  35. package/source/providers/Pict-Provider-PreviewCSS.js +42 -0
  36. package/source/views/PictView-FormEditor-InlineEditing.js +309 -0
  37. package/source/views/PictView-FormEditor-InputTypePicker.js +532 -0
  38. package/source/views/PictView-FormEditor-PropertiesPanel.js +7730 -0
  39. package/source/views/PictView-FormEditor.js +681 -0
  40. package/test/Pict-Section-FormEditor_tests.js +4102 -0
  41. package/user-documentation/.pict_documentation_topics.json +695 -0
  42. package/user-documentation/Getting-Started.md +32 -0
  43. package/user-documentation/Groups.md +52 -0
  44. package/user-documentation/Inputs.md +98 -0
  45. package/user-documentation/Sections.md +36 -0
  46. package/user-documentation/Shortcuts.md +44 -0
  47. package/user-documentation/Solver-Expression-Walkthrough.md +176 -0
  48. package/user-documentation/Solver-Expressions-Advanced.md +344 -0
  49. package/user-documentation/Solver-Functions.md +213 -0
  50. package/user-documentation/Solvers.md +81 -0
  51. package/user-documentation/ToC.md +18 -0
  52. package/user-documentation/solverfunctions/abs.md +84 -0
  53. package/user-documentation/solverfunctions/aggregationhistogram.md +83 -0
  54. package/user-documentation/solverfunctions/aggregationhistogrambyobject.md +64 -0
  55. package/user-documentation/solverfunctions/arrayconcat.md +64 -0
  56. package/user-documentation/solverfunctions/avg.md +81 -0
  57. package/user-documentation/solverfunctions/bucketset.md +69 -0
  58. package/user-documentation/solverfunctions/ceil.md +70 -0
  59. package/user-documentation/solverfunctions/cleanvaluearray.md +66 -0
  60. package/user-documentation/solverfunctions/cleanvalueobject.md +68 -0
  61. package/user-documentation/solverfunctions/colorgroupbackground.md +60 -0
  62. package/user-documentation/solverfunctions/colorinputbackground.md +62 -0
  63. package/user-documentation/solverfunctions/colorinputbackgroundtabular.md +64 -0
  64. package/user-documentation/solverfunctions/colorsectionbackground.md +59 -0
  65. package/user-documentation/solverfunctions/compare.md +72 -0
  66. package/user-documentation/solverfunctions/concat.md +73 -0
  67. package/user-documentation/solverfunctions/concatraw.md +73 -0
  68. package/user-documentation/solverfunctions/cos.md +75 -0
  69. package/user-documentation/solverfunctions/count.md +73 -0
  70. package/user-documentation/solverfunctions/countset.md +65 -0
  71. package/user-documentation/solverfunctions/countsetelements.md +63 -0
  72. package/user-documentation/solverfunctions/createarrayfromabsolutevalues.md +63 -0
  73. package/user-documentation/solverfunctions/createvalueobjectbyhashes.md +69 -0
  74. package/user-documentation/solverfunctions/cumulativesummation.md +96 -0
  75. package/user-documentation/solverfunctions/dateadddays.md +79 -0
  76. package/user-documentation/solverfunctions/dateaddhours.md +74 -0
  77. package/user-documentation/solverfunctions/dateaddmilliseconds.md +65 -0
  78. package/user-documentation/solverfunctions/dateaddminutes.md +72 -0
  79. package/user-documentation/solverfunctions/dateaddmonths.md +74 -0
  80. package/user-documentation/solverfunctions/dateaddseconds.md +66 -0
  81. package/user-documentation/solverfunctions/dateaddweeks.md +73 -0
  82. package/user-documentation/solverfunctions/dateaddyears.md +74 -0
  83. package/user-documentation/solverfunctions/datedaydifference.md +84 -0
  84. package/user-documentation/solverfunctions/datefromparts.md +81 -0
  85. package/user-documentation/solverfunctions/datehourdifference.md +64 -0
  86. package/user-documentation/solverfunctions/datemathadd.md +72 -0
  87. package/user-documentation/solverfunctions/datemilliseconddifference.md +64 -0
  88. package/user-documentation/solverfunctions/dateminutedifference.md +64 -0
  89. package/user-documentation/solverfunctions/datemonthdifference.md +66 -0
  90. package/user-documentation/solverfunctions/dateseconddifference.md +64 -0
  91. package/user-documentation/solverfunctions/dateweekdifference.md +65 -0
  92. package/user-documentation/solverfunctions/dateyeardifference.md +64 -0
  93. package/user-documentation/solverfunctions/differencearrays.md +59 -0
  94. package/user-documentation/solverfunctions/disablesolverordinal.md +58 -0
  95. package/user-documentation/solverfunctions/distributionhistogram.md +96 -0
  96. package/user-documentation/solverfunctions/distributionhistogrambyobject.md +64 -0
  97. package/user-documentation/solverfunctions/enablesolverordinal.md +57 -0
  98. package/user-documentation/solverfunctions/entryinset.md +72 -0
  99. package/user-documentation/solverfunctions/euler.md +77 -0
  100. package/user-documentation/solverfunctions/exp.md +74 -0
  101. package/user-documentation/solverfunctions/findfirstvaluebyexactmatch.md +67 -0
  102. package/user-documentation/solverfunctions/findfirstvaluebystringincludes.md +67 -0
  103. package/user-documentation/solverfunctions/flatten.md +76 -0
  104. package/user-documentation/solverfunctions/floor.md +70 -0
  105. package/user-documentation/solverfunctions/gaussianelimination.md +75 -0
  106. package/user-documentation/solverfunctions/generatearrayofobjectsfromsets.md +70 -0
  107. package/user-documentation/solverfunctions/generatehtmlhexcolor.md +67 -0
  108. package/user-documentation/solverfunctions/getvalue.md +90 -0
  109. package/user-documentation/solverfunctions/getvaluearray.md +64 -0
  110. package/user-documentation/solverfunctions/getvalueobject.md +67 -0
  111. package/user-documentation/solverfunctions/hidesections.md +58 -0
  112. package/user-documentation/solverfunctions/if.md +109 -0
  113. package/user-documentation/solverfunctions/iterativeseries.md +107 -0
  114. package/user-documentation/solverfunctions/join.md +75 -0
  115. package/user-documentation/solverfunctions/joinraw.md +64 -0
  116. package/user-documentation/solverfunctions/largestinset.md +63 -0
  117. package/user-documentation/solverfunctions/leastsquares.md +66 -0
  118. package/user-documentation/solverfunctions/linest.md +58 -0
  119. package/user-documentation/solverfunctions/log.md +74 -0
  120. package/user-documentation/solverfunctions/logvalues.md +65 -0
  121. package/user-documentation/solverfunctions/match.md +71 -0
  122. package/user-documentation/solverfunctions/matrixinverse.md +67 -0
  123. package/user-documentation/solverfunctions/matrixmultiply.md +71 -0
  124. package/user-documentation/solverfunctions/matrixtranspose.md +72 -0
  125. package/user-documentation/solverfunctions/matrixvectormultiply.md +69 -0
  126. package/user-documentation/solverfunctions/max.md +73 -0
  127. package/user-documentation/solverfunctions/mean.md +63 -0
  128. package/user-documentation/solverfunctions/median.md +79 -0
  129. package/user-documentation/solverfunctions/min.md +73 -0
  130. package/user-documentation/solverfunctions/mode.md +66 -0
  131. package/user-documentation/solverfunctions/objectkeystoarray.md +66 -0
  132. package/user-documentation/solverfunctions/objectvaluessortbyexternalobjectarray.md +65 -0
  133. package/user-documentation/solverfunctions/objectvaluestoarray.md +67 -0
  134. package/user-documentation/solverfunctions/percent.md +75 -0
  135. package/user-documentation/solverfunctions/pi.md +77 -0
  136. package/user-documentation/solverfunctions/polynomialregression.md +69 -0
  137. package/user-documentation/solverfunctions/predict.md +71 -0
  138. package/user-documentation/solverfunctions/rad.md +85 -0
  139. package/user-documentation/solverfunctions/randomfloat.md +63 -0
  140. package/user-documentation/solverfunctions/randomfloatbetween.md +72 -0
  141. package/user-documentation/solverfunctions/randomfloatupto.md +65 -0
  142. package/user-documentation/solverfunctions/randominteger.md +56 -0
  143. package/user-documentation/solverfunctions/randomintegerbetween.md +72 -0
  144. package/user-documentation/solverfunctions/randomintegerupto.md +64 -0
  145. package/user-documentation/solverfunctions/refreshtabularsection.md +57 -0
  146. package/user-documentation/solverfunctions/resolvehtmlentities.md +64 -0
  147. package/user-documentation/solverfunctions/round.md +111 -0
  148. package/user-documentation/solverfunctions/runsolvers.md +49 -0
  149. package/user-documentation/solverfunctions/setconcatenate.md +64 -0
  150. package/user-documentation/solverfunctions/setgroupvisibility.md +60 -0
  151. package/user-documentation/solverfunctions/setsectionvisibility.md +59 -0
  152. package/user-documentation/solverfunctions/setsolverordinalenabled.md +59 -0
  153. package/user-documentation/solverfunctions/settabularrowlength.md +57 -0
  154. package/user-documentation/solverfunctions/setvalue.md +65 -0
  155. package/user-documentation/solverfunctions/showsections.md +58 -0
  156. package/user-documentation/solverfunctions/sin.md +83 -0
  157. package/user-documentation/solverfunctions/slice.md +80 -0
  158. package/user-documentation/solverfunctions/smallestinset.md +63 -0
  159. package/user-documentation/solverfunctions/sortarray.md +58 -0
  160. package/user-documentation/solverfunctions/sorthistogram.md +70 -0
  161. package/user-documentation/solverfunctions/sorthistogrambykeys.md +69 -0
  162. package/user-documentation/solverfunctions/sortset.md +75 -0
  163. package/user-documentation/solverfunctions/sqrt.md +85 -0
  164. package/user-documentation/solverfunctions/stdev.md +81 -0
  165. package/user-documentation/solverfunctions/stdeva.md +58 -0
  166. package/user-documentation/solverfunctions/stdevp.md +83 -0
  167. package/user-documentation/solverfunctions/stringcountsegments.md +66 -0
  168. package/user-documentation/solverfunctions/stringgetsegments.md +74 -0
  169. package/user-documentation/solverfunctions/subtractingsummation.md +66 -0
  170. package/user-documentation/solverfunctions/sum.md +78 -0
  171. package/user-documentation/solverfunctions/tan.md +78 -0
  172. package/user-documentation/solverfunctions/tofixed.md +75 -0
  173. package/user-documentation/solverfunctions/unionarrays.md +59 -0
  174. package/user-documentation/solverfunctions/uniquearray.md +58 -0
  175. package/user-documentation/solverfunctions/var.md +67 -0
  176. package/user-documentation/solverfunctions/vara.md +58 -0
  177. package/user-documentation/solverfunctions/varp.md +66 -0
  178. package/user-documentation/solverfunctions/when.md +98 -0
@@ -0,0 +1,1002 @@
1
+ /**
2
+ * Pict Provider: Form Editor Iconography
3
+ *
4
+ * Provides cohesive SVG icons for the Form Editor UI, organized by category:
5
+ * - Section — structural grouping of the form
6
+ * - Group — a logical container within a section
7
+ * - Row — a horizontal row of inputs
8
+ * - Input — a single form input/field
9
+ * - InputType — icons for specific InputType definitions
10
+ *
11
+ * Each category supports multiple named variants. Every variant is an SVG
12
+ * string template that can be rendered directly into HTML.
13
+ *
14
+ * Embedders can override or add icons via the constructor options or the
15
+ * setIcon() / setInputTypeIcon() methods.
16
+ *
17
+ * @license MIT
18
+ * @author Steven Velozo <steven@velozo.com>
19
+ */
20
+
21
+ const _DefaultProviderConfiguration = (
22
+ {
23
+ ProviderIdentifier: 'Pict-FormEditor-Iconography',
24
+ AutoInitialize: true,
25
+ AutoInitializeOrdinal: 0,
26
+ AutoSolveWithApp: false,
27
+
28
+ // The default size for icons (pixels).
29
+ // Consumers can override per-call via the pSize parameter.
30
+ DefaultIconSize: 24,
31
+
32
+ // Stroke width for all line-based icons (relative to a 24x24 viewbox)
33
+ StrokeWidth: 1.5,
34
+
35
+ // Color tokens (consumers can override to match their theme)
36
+ Colors:
37
+ {
38
+ // Primary stroke/fill for structural icons
39
+ Primary: '#3D3229',
40
+ // Secondary stroke for accents
41
+ Accent: '#9E6B47',
42
+ // Muted color for subtle elements
43
+ Muted: '#B0A89E',
44
+ // Lighter fill for backgrounds inside icons
45
+ Fill: '#F5F0E8'
46
+ }
47
+ });
48
+
49
+ class PictProviderFormEditorIconography
50
+ {
51
+ constructor(pOptions)
52
+ {
53
+ // Merge default config with passed options
54
+ this.options = Object.assign({},
55
+ JSON.parse(JSON.stringify(_DefaultProviderConfiguration)),
56
+ pOptions);
57
+
58
+ // Internal icon registries, keyed by category then variant name
59
+ // Each entry is a function(pSize, pColors) that returns an SVG string
60
+ this._Icons =
61
+ {
62
+ Section: {},
63
+ Group: {},
64
+ Row: {},
65
+ Input: {},
66
+ Action: {}
67
+ };
68
+
69
+ // InputType icons, keyed by InputType Hash
70
+ this._InputTypeIcons = {};
71
+
72
+ // DataType icons, keyed by Manyfest DataType name
73
+ this._DataTypeIcons = {};
74
+
75
+ // Populate built-in icons
76
+ this._registerBuiltInIcons();
77
+ this._registerBuiltInInputTypeIcons();
78
+ this._registerBuiltInDataTypeIcons();
79
+
80
+ // Apply any icon overrides from options
81
+ if (pOptions && pOptions.IconOverrides && typeof pOptions.IconOverrides === 'object')
82
+ {
83
+ let tmpCategories = Object.keys(pOptions.IconOverrides);
84
+ for (let i = 0; i < tmpCategories.length; i++)
85
+ {
86
+ let tmpCategory = tmpCategories[i];
87
+ let tmpVariants = pOptions.IconOverrides[tmpCategory];
88
+ if (tmpVariants && typeof tmpVariants === 'object')
89
+ {
90
+ let tmpVariantNames = Object.keys(tmpVariants);
91
+ for (let j = 0; j < tmpVariantNames.length; j++)
92
+ {
93
+ this.setIcon(tmpCategory, tmpVariantNames[j], tmpVariants[tmpVariantNames[j]]);
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ // Apply InputType icon overrides from options
100
+ if (pOptions && pOptions.InputTypeIconOverrides && typeof pOptions.InputTypeIconOverrides === 'object')
101
+ {
102
+ let tmpHashes = Object.keys(pOptions.InputTypeIconOverrides);
103
+ for (let i = 0; i < tmpHashes.length; i++)
104
+ {
105
+ this.setInputTypeIcon(tmpHashes[i], pOptions.InputTypeIconOverrides[tmpHashes[i]]);
106
+ }
107
+ }
108
+
109
+ // Apply DataType icon overrides from options
110
+ if (pOptions && pOptions.DataTypeIconOverrides && typeof pOptions.DataTypeIconOverrides === 'object')
111
+ {
112
+ let tmpHashes = Object.keys(pOptions.DataTypeIconOverrides);
113
+ for (let i = 0; i < tmpHashes.length; i++)
114
+ {
115
+ this.setDataTypeIcon(tmpHashes[i], pOptions.DataTypeIconOverrides[tmpHashes[i]]);
116
+ }
117
+ }
118
+ }
119
+
120
+ /* ======================================================================== */
121
+ /* Public API */
122
+ /* ======================================================================== */
123
+
124
+ /**
125
+ * Get an SVG icon string for a structural element.
126
+ *
127
+ * @param {string} pCategory - 'Section', 'Group', 'Row', or 'Input'
128
+ * @param {string} pVariant - The named variant (e.g. 'Default', 'Folder', 'Stack')
129
+ * @param {number} [pSize] - Icon width/height in pixels (default: options.DefaultIconSize)
130
+ * @return {string} An SVG string, or an empty string if not found
131
+ */
132
+ getIcon(pCategory, pVariant, pSize)
133
+ {
134
+ let tmpSize = (typeof pSize === 'number' && pSize > 0) ? pSize : this.options.DefaultIconSize;
135
+
136
+ if (!this._Icons[pCategory])
137
+ {
138
+ return '';
139
+ }
140
+
141
+ let tmpFactory = this._Icons[pCategory][pVariant];
142
+ if (typeof tmpFactory !== 'function')
143
+ {
144
+ // Fall back to 'Default' variant
145
+ tmpFactory = this._Icons[pCategory]['Default'];
146
+ }
147
+
148
+ if (typeof tmpFactory !== 'function')
149
+ {
150
+ return '';
151
+ }
152
+
153
+ return tmpFactory(tmpSize, this.options.Colors, this.options.StrokeWidth);
154
+ }
155
+
156
+ /**
157
+ * Get an SVG icon string for a specific InputType.
158
+ *
159
+ * @param {string} pInputTypeHash - The InputType Hash (e.g. 'TextArea', 'Boolean')
160
+ * @param {number} [pSize] - Icon width/height in pixels
161
+ * @return {string} An SVG string, or an empty string if not found
162
+ */
163
+ getInputTypeIcon(pInputTypeHash, pSize)
164
+ {
165
+ let tmpSize = (typeof pSize === 'number' && pSize > 0) ? pSize : this.options.DefaultIconSize;
166
+
167
+ let tmpFactory = this._InputTypeIcons[pInputTypeHash];
168
+ if (typeof tmpFactory !== 'function')
169
+ {
170
+ return '';
171
+ }
172
+
173
+ return tmpFactory(tmpSize, this.options.Colors, this.options.StrokeWidth);
174
+ }
175
+
176
+ /**
177
+ * Register or override a structural icon variant.
178
+ *
179
+ * @param {string} pCategory - 'Section', 'Group', 'Row', or 'Input'
180
+ * @param {string} pVariant - The variant name
181
+ * @param {function} pFactory - A function(pSize, pColors, pStrokeWidth) returning an SVG string
182
+ */
183
+ setIcon(pCategory, pVariant, pFactory)
184
+ {
185
+ if (!this._Icons[pCategory])
186
+ {
187
+ this._Icons[pCategory] = {};
188
+ }
189
+ this._Icons[pCategory][pVariant] = pFactory;
190
+ }
191
+
192
+ /**
193
+ * Register or override an InputType icon.
194
+ *
195
+ * @param {string} pInputTypeHash - The InputType Hash
196
+ * @param {function} pFactory - A function(pSize, pColors, pStrokeWidth) returning an SVG string
197
+ */
198
+ setInputTypeIcon(pInputTypeHash, pFactory)
199
+ {
200
+ this._InputTypeIcons[pInputTypeHash] = pFactory;
201
+ }
202
+
203
+ /**
204
+ * Get an array of all registered variant names for a category.
205
+ *
206
+ * @param {string} pCategory - 'Section', 'Group', 'Row', or 'Input'
207
+ * @return {Array} Variant name strings
208
+ */
209
+ getVariants(pCategory)
210
+ {
211
+ if (!this._Icons[pCategory])
212
+ {
213
+ return [];
214
+ }
215
+ return Object.keys(this._Icons[pCategory]);
216
+ }
217
+
218
+ /**
219
+ * Get an array of all registered InputType icon hashes.
220
+ *
221
+ * @return {Array} InputType Hash strings
222
+ */
223
+ getInputTypeIconHashes()
224
+ {
225
+ return Object.keys(this._InputTypeIcons);
226
+ }
227
+
228
+ /**
229
+ * Check whether a given category + variant is registered.
230
+ *
231
+ * @param {string} pCategory - 'Section', 'Group', 'Row', or 'Input'
232
+ * @param {string} pVariant - The variant name
233
+ * @return {boolean}
234
+ */
235
+ hasIcon(pCategory, pVariant)
236
+ {
237
+ return !!(this._Icons[pCategory] && typeof this._Icons[pCategory][pVariant] === 'function');
238
+ }
239
+
240
+ /**
241
+ * Check whether a given InputType has a registered icon.
242
+ *
243
+ * @param {string} pInputTypeHash - The InputType Hash
244
+ * @return {boolean}
245
+ */
246
+ hasInputTypeIcon(pInputTypeHash)
247
+ {
248
+ return typeof this._InputTypeIcons[pInputTypeHash] === 'function';
249
+ }
250
+
251
+ /**
252
+ * Get an SVG icon string for a specific Manyfest DataType.
253
+ *
254
+ * @param {string} pDataTypeHash - The DataType name (e.g. 'String', 'Number', 'Boolean')
255
+ * @param {number} [pSize] - Icon width/height in pixels
256
+ * @return {string} An SVG string, or an empty string if not found
257
+ */
258
+ getDataTypeIcon(pDataTypeHash, pSize)
259
+ {
260
+ let tmpSize = (typeof pSize === 'number' && pSize > 0) ? pSize : this.options.DefaultIconSize;
261
+
262
+ let tmpFactory = this._DataTypeIcons[pDataTypeHash];
263
+ if (typeof tmpFactory !== 'function')
264
+ {
265
+ return '';
266
+ }
267
+
268
+ return tmpFactory(tmpSize, this.options.Colors, this.options.StrokeWidth);
269
+ }
270
+
271
+ /**
272
+ * Register or override a DataType icon.
273
+ *
274
+ * @param {string} pDataTypeHash - The DataType name
275
+ * @param {function} pFactory - A function(pSize, pColors, pStrokeWidth) returning an SVG string
276
+ */
277
+ setDataTypeIcon(pDataTypeHash, pFactory)
278
+ {
279
+ this._DataTypeIcons[pDataTypeHash] = pFactory;
280
+ }
281
+
282
+ /**
283
+ * Get an array of all registered DataType icon names.
284
+ *
285
+ * @return {Array} DataType name strings
286
+ */
287
+ getDataTypeIconHashes()
288
+ {
289
+ return Object.keys(this._DataTypeIcons);
290
+ }
291
+
292
+ /**
293
+ * Check whether a given DataType has a registered icon.
294
+ *
295
+ * @param {string} pDataTypeHash - The DataType name
296
+ * @return {boolean}
297
+ */
298
+ hasDataTypeIcon(pDataTypeHash)
299
+ {
300
+ return typeof this._DataTypeIcons[pDataTypeHash] === 'function';
301
+ }
302
+
303
+ /* ======================================================================== */
304
+ /* Built-in Structural Icons */
305
+ /* ======================================================================== */
306
+
307
+ /**
308
+ * All built-in icons use a 24x24 viewBox, rendered as line-art SVGs with
309
+ * configurable size, colors, and stroke width. The design language is
310
+ * cohesive: rounded strokes, consistent weight, geometric shapes with
311
+ * subtle fills to distinguish hierarchy levels.
312
+ *
313
+ * Section = page/document metaphor (largest container)
314
+ * Group = folder/panel metaphor (container within section)
315
+ * Row = horizontal bar/layer metaphor
316
+ * Input = field/data entry metaphor (smallest unit)
317
+ */
318
+ _registerBuiltInIcons()
319
+ {
320
+ let tmpSelf = this;
321
+
322
+ // Helper to create an SVG wrapper
323
+ function _svg(pSize, pInner)
324
+ {
325
+ return '<svg xmlns="http://www.w3.org/2000/svg" width="' + pSize + '" height="' + pSize + '" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">' + pInner + '</svg>';
326
+ }
327
+
328
+ // ===== SECTION ICONS (11 variants) =====
329
+
330
+ // 1. Default — stacked cards (visual metaphor: sections stack vertically)
331
+ this._Icons.Section['Default'] = function(pSize, pColors, pSW)
332
+ {
333
+ return _svg(pSize,
334
+ '<rect x="4" y="2" width="16" height="6" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
335
+ '<rect x="4" y="10" width="16" height="6" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
336
+ '<rect x="4" y="18" width="16" height="4" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
337
+ };
338
+
339
+ // 2. Document — page with corner fold
340
+ this._Icons.Section['Document'] = function(pSize, pColors, pSW)
341
+ {
342
+ return _svg(pSize,
343
+ '<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
344
+ '<polyline points="14 2 14 8 20 8" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
345
+ };
346
+
347
+ // 3. Layers — stacked pages
348
+ this._Icons.Section['Layers'] = function(pSize, pColors, pSW)
349
+ {
350
+ return _svg(pSize,
351
+ '<rect x="6" y="6" width="14" height="14" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
352
+ '<path d="M4 16V6a2 2 0 012-2h10" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
353
+ };
354
+
355
+ // 4. Clipboard — form on a clipboard
356
+ this._Icons.Section['Clipboard'] = function(pSize, pColors, pSW)
357
+ {
358
+ return _svg(pSize,
359
+ '<rect x="5" y="4" width="14" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
360
+ '<rect x="9" y="2" width="6" height="4" rx="1" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
361
+ '<line x1="9" y1="11" x2="15" y2="11" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
362
+ '<line x1="9" y1="15" x2="13" y2="15" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
363
+ };
364
+
365
+ // 5. Layout — page with section divisions
366
+ this._Icons.Section['Layout'] = function(pSize, pColors, pSW)
367
+ {
368
+ return _svg(pSize,
369
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
370
+ '<line x1="3" y1="9" x2="21" y2="9" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
371
+ '<line x1="3" y1="15" x2="21" y2="15" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
372
+ };
373
+
374
+ // 6. Book — open book pages
375
+ this._Icons.Section['Book'] = function(pSize, pColors, pSW)
376
+ {
377
+ return _svg(pSize,
378
+ '<path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
379
+ '<path d="M22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
380
+ };
381
+
382
+ // 7. Window — application window frame
383
+ this._Icons.Section['Window'] = function(pSize, pColors, pSW)
384
+ {
385
+ return _svg(pSize,
386
+ '<rect x="2" y="3" width="20" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
387
+ '<line x1="2" y1="8" x2="22" y2="8" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
388
+ '<circle cx="5.5" cy="5.5" r="0.8" fill="' + pColors.Accent + '"/>' +
389
+ '<circle cx="8.5" cy="5.5" r="0.8" fill="' + pColors.Accent + '"/>');
390
+ };
391
+
392
+ // 8. FileText — page with text lines
393
+ this._Icons.Section['FileText'] = function(pSize, pColors, pSW)
394
+ {
395
+ return _svg(pSize,
396
+ '<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
397
+ '<polyline points="14 2 14 8 20 8" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
398
+ '<line x1="8" y1="13" x2="16" y2="13" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
399
+ '<line x1="8" y1="17" x2="14" y2="17" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
400
+ };
401
+
402
+ // 9. Columns — vertical column layout
403
+ this._Icons.Section['Columns'] = function(pSize, pColors, pSW)
404
+ {
405
+ return _svg(pSize,
406
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
407
+ '<line x1="12" y1="3" x2="12" y2="21" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
408
+ };
409
+
410
+ // 10. Bookmark — bookmark/flag marker
411
+ this._Icons.Section['Bookmark'] = function(pSize, pColors, pSW)
412
+ {
413
+ return _svg(pSize,
414
+ '<path d="M5 3a2 2 0 012-2h10a2 2 0 012 2v18l-7-4-7 4V3z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
415
+ '<line x1="9" y1="7" x2="15" y2="7" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
416
+ };
417
+
418
+ // 11. Shield — protected section
419
+ this._Icons.Section['Shield'] = function(pSize, pColors, pSW)
420
+ {
421
+ return _svg(pSize,
422
+ '<path d="M12 2l8 4v6c0 5.25-3.5 8.25-8 10-4.5-1.75-8-4.75-8-10V6l8-4z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
423
+ '<line x1="9" y1="11" x2="15" y2="11" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
424
+ };
425
+
426
+ // ===== GROUP ICONS (11 variants) =====
427
+
428
+ // 1. Default — page with section divisions (visual metaphor: groups divide a section)
429
+ this._Icons.Group['Default'] = function(pSize, pColors, pSW)
430
+ {
431
+ return _svg(pSize,
432
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
433
+ '<line x1="3" y1="9" x2="21" y2="9" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
434
+ '<line x1="3" y1="15" x2="21" y2="15" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
435
+ };
436
+
437
+ // 2. Folder — folder shape
438
+ this._Icons.Group['Folder'] = function(pSize, pColors, pSW)
439
+ {
440
+ return _svg(pSize,
441
+ '<path d="M2 6a2 2 0 012-2h5l2 2h9a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
442
+ };
443
+
444
+ // 3. Panel — rounded panel container
445
+ this._Icons.Group['Panel'] = function(pSize, pColors, pSW)
446
+ {
447
+ return _svg(pSize,
448
+ '<rect x="2" y="4" width="20" height="16" rx="3" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
449
+ '<line x1="2" y1="9" x2="22" y2="9" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
450
+ };
451
+
452
+ // 4. Stack — vertically stacked cards
453
+ this._Icons.Group['Stack'] = function(pSize, pColors, pSW)
454
+ {
455
+ return _svg(pSize,
456
+ '<rect x="4" y="2" width="16" height="6" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
457
+ '<rect x="4" y="10" width="16" height="6" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
458
+ '<rect x="4" y="18" width="16" height="4" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
459
+ };
460
+
461
+ // 5. Grid — 2x2 grid boxes
462
+ this._Icons.Group['Grid'] = function(pSize, pColors, pSW)
463
+ {
464
+ return _svg(pSize,
465
+ '<rect x="3" y="3" width="8" height="8" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
466
+ '<rect x="13" y="3" width="8" height="8" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
467
+ '<rect x="3" y="13" width="8" height="8" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
468
+ '<rect x="13" y="13" width="8" height="8" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
469
+ };
470
+
471
+ // 6. Box — simple box container
472
+ this._Icons.Group['Box'] = function(pSize, pColors, pSW)
473
+ {
474
+ return _svg(pSize,
475
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
476
+ '<circle cx="12" cy="12" r="1.5" fill="' + pColors.Accent + '"/>');
477
+ };
478
+
479
+ // 7. Package — wrapped package
480
+ this._Icons.Group['Package'] = function(pSize, pColors, pSW)
481
+ {
482
+ return _svg(pSize,
483
+ '<path d="M12 2L2 7v10l10 5 10-5V7L12 2z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
484
+ '<line x1="12" y1="12" x2="12" y2="22" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
485
+ '<polyline points="2 7 12 12 22 7" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
486
+ };
487
+
488
+ // 8. Bracket — code bracket grouping
489
+ this._Icons.Group['Bracket'] = function(pSize, pColors, pSW)
490
+ {
491
+ return _svg(pSize,
492
+ '<path d="M8 3H6a2 2 0 00-2 2v4.5a1.5 1.5 0 01-1.5 1.5 1.5 1.5 0 011.5 1.5V17a2 2 0 002 2h2" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
493
+ '<path d="M16 3h2a2 2 0 012 2v4.5a1.5 1.5 0 001.5 1.5 1.5 1.5 0 00-1.5 1.5V17a2 2 0 01-2 2h-2" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>');
494
+ };
495
+
496
+ // 9. Tab — tabbed panel
497
+ this._Icons.Group['Tab'] = function(pSize, pColors, pSW)
498
+ {
499
+ return _svg(pSize,
500
+ '<rect x="2" y="7" width="20" height="14" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
501
+ '<rect x="3" y="3" width="8" height="5" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
502
+ '<line x1="13" y1="5" x2="17" y2="5" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
503
+ };
504
+
505
+ // 10. Sidebar — panel with sidebar
506
+ this._Icons.Group['Sidebar'] = function(pSize, pColors, pSW)
507
+ {
508
+ return _svg(pSize,
509
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
510
+ '<line x1="9" y1="3" x2="9" y2="21" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
511
+ '<line x1="13" y1="8" x2="17" y2="8" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
512
+ '<line x1="13" y1="12" x2="17" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
513
+ };
514
+
515
+ // 11. Puzzle — interlocking piece
516
+ this._Icons.Group['Puzzle'] = function(pSize, pColors, pSW)
517
+ {
518
+ return _svg(pSize,
519
+ '<path d="M4 7h3a2 2 0 100-4h0a2 2 0 100 4h3v3a2 2 0 104 0V7h3a2 2 0 012 2v3a2 2 0 10 0 4v3a2 2 0 01-2 2h-3a2 2 0 100-4H10a2 2 0 100 4H7a2 2 0 01-2-2v-3a2 2 0 100-4V9a2 2 0 01-1-2z" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
520
+ };
521
+
522
+ // ===== ROW ICONS (11 variants) =====
523
+
524
+ // 1. Default — side-by-side columns (visual metaphor: row of columns)
525
+ this._Icons.Row['Default'] = function(pSize, pColors, pSW)
526
+ {
527
+ return _svg(pSize,
528
+ '<rect x="2" y="6" width="5.5" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
529
+ '<rect x="9.25" y="6" width="5.5" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
530
+ '<rect x="16.5" y="6" width="5.5" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
531
+ };
532
+
533
+ // 2. Bars — horizontal bars/lines
534
+ this._Icons.Row['Bars'] = function(pSize, pColors, pSW)
535
+ {
536
+ return _svg(pSize,
537
+ '<line x1="3" y1="8" x2="21" y2="8" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
538
+ '<line x1="3" y1="12" x2="21" y2="12" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
539
+ '<line x1="3" y1="16" x2="21" y2="16" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
540
+ };
541
+
542
+ // 3. Stripe — single horizontal stripe band
543
+ this._Icons.Row['Stripe'] = function(pSize, pColors, pSW)
544
+ {
545
+ return _svg(pSize,
546
+ '<rect x="2" y="8" width="20" height="8" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
547
+ };
548
+
549
+ // 4. Columns — row of columns side-by-side
550
+ this._Icons.Row['Columns'] = function(pSize, pColors, pSW)
551
+ {
552
+ return _svg(pSize,
553
+ '<rect x="2" y="6" width="5.5" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
554
+ '<rect x="9.25" y="6" width="5.5" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
555
+ '<rect x="16.5" y="6" width="5.5" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
556
+ };
557
+
558
+ // 5. ArrowRight — horizontal flow direction
559
+ this._Icons.Row['ArrowRight'] = function(pSize, pColors, pSW)
560
+ {
561
+ return _svg(pSize,
562
+ '<line x1="3" y1="12" x2="21" y2="12" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
563
+ '<polyline points="17 8 21 12 17 16" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
564
+ };
565
+
566
+ // 6. Divider — horizontal rule with dots
567
+ this._Icons.Row['Divider'] = function(pSize, pColors, pSW)
568
+ {
569
+ return _svg(pSize,
570
+ '<line x1="2" y1="12" x2="8" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
571
+ '<circle cx="12" cy="12" r="1.2" fill="' + pColors.Primary + '"/>' +
572
+ '<line x1="16" y1="12" x2="22" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
573
+ };
574
+
575
+ // 7. Layer — flat layer with depth
576
+ this._Icons.Row['Layer'] = function(pSize, pColors, pSW)
577
+ {
578
+ return _svg(pSize,
579
+ '<polygon points="12 2 22 8.5 12 15 2 8.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
580
+ '<polyline points="2 15.5 12 22 22 15.5" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '" fill="none"/>');
581
+ };
582
+
583
+ // 8. Grip — draggable grip handle (6 dots)
584
+ this._Icons.Row['Grip'] = function(pSize, pColors, pSW)
585
+ {
586
+ return _svg(pSize,
587
+ '<circle cx="8" cy="6" r="1.3" fill="' + pColors.Primary + '"/>' +
588
+ '<circle cx="16" cy="6" r="1.3" fill="' + pColors.Primary + '"/>' +
589
+ '<circle cx="8" cy="12" r="1.3" fill="' + pColors.Primary + '"/>' +
590
+ '<circle cx="16" cy="12" r="1.3" fill="' + pColors.Primary + '"/>' +
591
+ '<circle cx="8" cy="18" r="1.3" fill="' + pColors.Primary + '"/>' +
592
+ '<circle cx="16" cy="18" r="1.3" fill="' + pColors.Primary + '"/>');
593
+ };
594
+
595
+ // 9. Table — table row representation
596
+ this._Icons.Row['Table'] = function(pSize, pColors, pSW)
597
+ {
598
+ return _svg(pSize,
599
+ '<rect x="2" y="4" width="20" height="16" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
600
+ '<line x1="2" y1="10" x2="22" y2="10" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
601
+ '<line x1="2" y1="16" x2="22" y2="16" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
602
+ '<line x1="9" y1="4" x2="9" y2="20" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
603
+ };
604
+
605
+ // 10. Split — two-column split row
606
+ this._Icons.Row['Split'] = function(pSize, pColors, pSW)
607
+ {
608
+ return _svg(pSize,
609
+ '<rect x="2" y="6" width="9" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
610
+ '<rect x="13" y="6" width="9" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
611
+ };
612
+
613
+ // 11. Slider — horizontal slider track
614
+ this._Icons.Row['Slider'] = function(pSize, pColors, pSW)
615
+ {
616
+ return _svg(pSize,
617
+ '<line x1="3" y1="12" x2="21" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
618
+ '<circle cx="9" cy="12" r="3" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
619
+ };
620
+
621
+ // ===== INPUT ICONS (10 variants) =====
622
+
623
+ // 1. Default — text field with cursor
624
+ this._Icons.Input['Default'] = function(pSize, pColors, pSW)
625
+ {
626
+ return _svg(pSize,
627
+ '<rect x="3" y="6" width="18" height="12" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
628
+ '<line x1="7" y1="10" x2="7" y2="14" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
629
+ };
630
+
631
+ // 2. Checkbox — checked checkbox
632
+ this._Icons.Input['Checkbox'] = function(pSize, pColors, pSW)
633
+ {
634
+ return _svg(pSize,
635
+ '<rect x="4" y="4" width="16" height="16" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
636
+ '<polyline points="8 12 11 15 16 9" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
637
+ };
638
+
639
+ // 3. Toggle — on/off switch
640
+ this._Icons.Input['Toggle'] = function(pSize, pColors, pSW)
641
+ {
642
+ return _svg(pSize,
643
+ '<rect x="2" y="7" width="20" height="10" rx="5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
644
+ '<circle cx="16" cy="12" r="3.5" fill="' + pColors.Accent + '"/>');
645
+ };
646
+
647
+ // 4. Dropdown — select dropdown
648
+ this._Icons.Input['Dropdown'] = function(pSize, pColors, pSW)
649
+ {
650
+ return _svg(pSize,
651
+ '<rect x="3" y="6" width="18" height="12" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
652
+ '<polyline points="15 10 18 13 15 16" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
653
+ };
654
+
655
+ // 5. TextArea — multi-line text input
656
+ this._Icons.Input['TextArea'] = function(pSize, pColors, pSW)
657
+ {
658
+ return _svg(pSize,
659
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
660
+ '<line x1="7" y1="8" x2="17" y2="8" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
661
+ '<line x1="7" y1="12" x2="17" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
662
+ '<line x1="7" y1="16" x2="13" y2="16" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
663
+ };
664
+
665
+ // 6. Number — numeric input with arrows
666
+ this._Icons.Input['Number'] = function(pSize, pColors, pSW)
667
+ {
668
+ return _svg(pSize,
669
+ '<rect x="3" y="6" width="18" height="12" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
670
+ '<text x="8" y="15.5" font-size="9" font-family="sans-serif" fill="' + pColors.Primary + '">#</text>' +
671
+ '<polyline points="16 10 18 8 20 10" stroke="' + pColors.Muted + '" stroke-width="1.2" fill="none"/>' +
672
+ '<polyline points="16 14 18 16 20 14" stroke="' + pColors.Muted + '" stroke-width="1.2" fill="none"/>');
673
+ };
674
+
675
+ // 7. Radio — radio button
676
+ this._Icons.Input['Radio'] = function(pSize, pColors, pSW)
677
+ {
678
+ return _svg(pSize,
679
+ '<circle cx="12" cy="12" r="8" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
680
+ '<circle cx="12" cy="12" r="3.5" fill="' + pColors.Accent + '"/>');
681
+ };
682
+
683
+ // 8. Calendar — date picker
684
+ this._Icons.Input['Calendar'] = function(pSize, pColors, pSW)
685
+ {
686
+ return _svg(pSize,
687
+ '<rect x="3" y="4" width="18" height="17" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
688
+ '<line x1="3" y1="10" x2="21" y2="10" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
689
+ '<line x1="8" y1="2" x2="8" y2="6" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
690
+ '<line x1="16" y1="2" x2="16" y2="6" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
691
+ };
692
+
693
+ // 9. Lock — password/secure input
694
+ this._Icons.Input['Lock'] = function(pSize, pColors, pSW)
695
+ {
696
+ return _svg(pSize,
697
+ '<rect x="5" y="11" width="14" height="10" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
698
+ '<path d="M8 11V7a4 4 0 018 0v4" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>' +
699
+ '<circle cx="12" cy="16" r="1.2" fill="' + pColors.Primary + '"/>');
700
+ };
701
+
702
+ // 10. Search — search field with magnifying glass
703
+ this._Icons.Input['Search'] = function(pSize, pColors, pSW)
704
+ {
705
+ return _svg(pSize,
706
+ '<circle cx="10.5" cy="10.5" r="6.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
707
+ '<line x1="15.5" y1="15.5" x2="21" y2="21" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
708
+ };
709
+
710
+ // ===== ACTION ICONS =====
711
+
712
+ // Add — centered plus sign (uses currentColor to inherit button text color)
713
+ this._Icons.Action['Add'] = function(pSize, pColors, pSW)
714
+ {
715
+ return _svg(pSize,
716
+ '<line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" stroke-width="' + (pSW + 0.5) + '"/>' +
717
+ '<line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" stroke-width="' + (pSW + 0.5) + '"/>');
718
+ };
719
+
720
+ // DragHandle — six-dot grip pattern (two columns of three dots, uses currentColor)
721
+ this._Icons.Action['DragHandle'] = function(pSize, pColors, pSW)
722
+ {
723
+ let tmpR = Math.max(1.2, pSW * 0.6);
724
+ return _svg(pSize,
725
+ '<circle cx="9" cy="6" r="' + tmpR + '" fill="currentColor"/>' +
726
+ '<circle cx="15" cy="6" r="' + tmpR + '" fill="currentColor"/>' +
727
+ '<circle cx="9" cy="12" r="' + tmpR + '" fill="currentColor"/>' +
728
+ '<circle cx="15" cy="12" r="' + tmpR + '" fill="currentColor"/>' +
729
+ '<circle cx="9" cy="18" r="' + tmpR + '" fill="currentColor"/>' +
730
+ '<circle cx="15" cy="18" r="' + tmpR + '" fill="currentColor"/>');
731
+ };
732
+ }
733
+
734
+ /* ======================================================================== */
735
+ /* Built-in InputType Icons */
736
+ /* ======================================================================== */
737
+
738
+ _registerBuiltInInputTypeIcons()
739
+ {
740
+ // Helper to create an SVG wrapper
741
+ function _svg(pSize, pInner)
742
+ {
743
+ return '<svg xmlns="http://www.w3.org/2000/svg" width="' + pSize + '" height="' + pSize + '" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">' + pInner + '</svg>';
744
+ }
745
+
746
+ // TextArea — multi-line text
747
+ this._InputTypeIcons['TextArea'] = function(pSize, pColors, pSW)
748
+ {
749
+ return _svg(pSize,
750
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
751
+ '<line x1="7" y1="8" x2="17" y2="8" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
752
+ '<line x1="7" y1="12" x2="17" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
753
+ '<line x1="7" y1="16" x2="13" y2="16" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
754
+ };
755
+
756
+ // Markdown — text with formatting marks
757
+ this._InputTypeIcons['Markdown'] = function(pSize, pColors, pSW)
758
+ {
759
+ return _svg(pSize,
760
+ '<rect x="2" y="4" width="20" height="16" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
761
+ '<path d="M6 15V9l3 3.5L12 9v6" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>' +
762
+ '<polyline points="16 12 18 15 20 12" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
763
+ };
764
+
765
+ // HTML — code angle brackets
766
+ this._InputTypeIcons['HTML'] = function(pSize, pColors, pSW)
767
+ {
768
+ return _svg(pSize,
769
+ '<polyline points="8 7 3 12 8 17" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
770
+ '<polyline points="16 7 21 12 16 17" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
771
+ '<line x1="14" y1="4" x2="10" y2="20" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
772
+ };
773
+
774
+ // Option — dropdown chevron
775
+ this._InputTypeIcons['Option'] = function(pSize, pColors, pSW)
776
+ {
777
+ return _svg(pSize,
778
+ '<rect x="3" y="6" width="18" height="12" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
779
+ '<polyline points="9 10 12 14 15 10" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
780
+ };
781
+
782
+ // Boolean — toggle switch
783
+ this._InputTypeIcons['Boolean'] = function(pSize, pColors, pSW)
784
+ {
785
+ return _svg(pSize,
786
+ '<rect x="2" y="7" width="20" height="10" rx="5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
787
+ '<circle cx="16" cy="12" r="3.5" fill="' + pColors.Accent + '"/>');
788
+ };
789
+
790
+ // Color — color swatch circle
791
+ this._InputTypeIcons['Color'] = function(pSize, pColors, pSW)
792
+ {
793
+ return _svg(pSize,
794
+ '<circle cx="12" cy="12" r="9" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
795
+ '<circle cx="12" cy="8" r="2.5" fill="' + pColors.Accent + '"/>' +
796
+ '<circle cx="8.5" cy="14" r="2.5" fill="#6B7F5A"/>' +
797
+ '<circle cx="15.5" cy="14" r="2.5" fill="#5A6B7F"/>');
798
+ };
799
+
800
+ // DisplayOnly — eye icon
801
+ this._InputTypeIcons['DisplayOnly'] = function(pSize, pColors, pSW)
802
+ {
803
+ return _svg(pSize,
804
+ '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
805
+ '<circle cx="12" cy="12" r="3" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
806
+ };
807
+
808
+ // ReadOnly — lock icon
809
+ this._InputTypeIcons['ReadOnly'] = function(pSize, pColors, pSW)
810
+ {
811
+ return _svg(pSize,
812
+ '<rect x="5" y="11" width="14" height="10" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
813
+ '<path d="M8 11V7a4 4 0 018 0v4" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
814
+ };
815
+
816
+ // PreciseNumberReadOnly — number with decimal point
817
+ this._InputTypeIcons['PreciseNumberReadOnly'] = function(pSize, pColors, pSW)
818
+ {
819
+ return _svg(pSize,
820
+ '<rect x="3" y="5" width="18" height="14" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
821
+ '<text x="7" y="16" font-size="10" font-family="sans-serif" fill="' + pColors.Accent + '">.00</text>');
822
+ };
823
+
824
+ // Hidden — eye-off icon
825
+ this._InputTypeIcons['Hidden'] = function(pSize, pColors, pSW)
826
+ {
827
+ return _svg(pSize,
828
+ '<path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '" fill="none"/>' +
829
+ '<path d="M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '" fill="none"/>' +
830
+ '<line x1="1" y1="1" x2="23" y2="23" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
831
+ };
832
+
833
+ // Chart — bar chart
834
+ this._InputTypeIcons['Chart'] = function(pSize, pColors, pSW)
835
+ {
836
+ return _svg(pSize,
837
+ '<rect x="3" y="12" width="4" height="9" rx="1" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
838
+ '<rect x="10" y="6" width="4" height="15" rx="1" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
839
+ '<rect x="17" y="3" width="4" height="18" rx="1" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>');
840
+ };
841
+
842
+ // Link — chain link
843
+ this._InputTypeIcons['Link'] = function(pSize, pColors, pSW)
844
+ {
845
+ return _svg(pSize,
846
+ '<path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
847
+ '<path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
848
+ };
849
+
850
+ // TabSectionSelector — horizontal tabs
851
+ this._InputTypeIcons['TabSectionSelector'] = function(pSize, pColors, pSW)
852
+ {
853
+ return _svg(pSize,
854
+ '<rect x="2" y="8" width="20" height="13" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
855
+ '<rect x="3" y="3" width="6" height="6" rx="1" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
856
+ '<rect x="10" y="3" width="6" height="6" rx="1" fill="none" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
857
+ };
858
+
859
+ // TabGroupSelector — group tab switcher
860
+ this._InputTypeIcons['TabGroupSelector'] = function(pSize, pColors, pSW)
861
+ {
862
+ return _svg(pSize,
863
+ '<rect x="2" y="8" width="20" height="13" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
864
+ '<rect x="3" y="3" width="5" height="6" rx="1" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
865
+ '<rect x="9" y="3" width="5" height="6" rx="1" fill="none" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
866
+ '<rect x="15" y="3" width="5" height="6" rx="1" fill="none" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
867
+ };
868
+
869
+ // Templated — puzzle piece
870
+ this._InputTypeIcons['Templated'] = function(pSize, pColors, pSW)
871
+ {
872
+ return _svg(pSize,
873
+ '<rect x="3" y="3" width="18" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
874
+ '<path d="M8 12h3a1.5 1.5 0 100-3 1.5 1.5 0 100 3h3" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>' +
875
+ '<line x1="8" y1="16" x2="16" y2="16" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
876
+ };
877
+
878
+ // TemplatedEntityLookup — magnifying glass on template
879
+ this._InputTypeIcons['TemplatedEntityLookup'] = function(pSize, pColors, pSW)
880
+ {
881
+ return _svg(pSize,
882
+ '<rect x="2" y="3" width="14" height="18" rx="2" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
883
+ '<circle cx="17" cy="15" r="4" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
884
+ '<line x1="20" y1="18" x2="22" y2="20" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
885
+ };
886
+ }
887
+
888
+ /* ======================================================================== */
889
+ /* Built-in DataType Icons */
890
+ /* ======================================================================== */
891
+
892
+ _registerBuiltInDataTypeIcons()
893
+ {
894
+ // Helper to create an SVG wrapper
895
+ function _svg(pSize, pInner)
896
+ {
897
+ return '<svg xmlns="http://www.w3.org/2000/svg" width="' + pSize + '" height="' + pSize + '" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">' + pInner + '</svg>';
898
+ }
899
+
900
+ // String — horizontal text lines
901
+ this._DataTypeIcons['String'] = function(pSize, pColors, pSW)
902
+ {
903
+ return _svg(pSize,
904
+ '<line x1="4" y1="7" x2="20" y2="7" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
905
+ '<line x1="4" y1="12" x2="17" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>' +
906
+ '<line x1="4" y1="17" x2="13" y2="17" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
907
+ };
908
+
909
+ // Number — hash/pound sign
910
+ this._DataTypeIcons['Number'] = function(pSize, pColors, pSW)
911
+ {
912
+ return _svg(pSize,
913
+ '<line x1="10" y1="3" x2="8" y2="21" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
914
+ '<line x1="16" y1="3" x2="14" y2="21" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
915
+ '<line x1="4" y1="9" x2="20" y2="9" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
916
+ '<line x1="4" y1="15" x2="20" y2="15" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>');
917
+ };
918
+
919
+ // Float — decimal point with digits
920
+ this._DataTypeIcons['Float'] = function(pSize, pColors, pSW)
921
+ {
922
+ return _svg(pSize,
923
+ '<text x="3" y="17" font-size="14" font-family="sans-serif" font-weight="600" fill="' + pColors.Primary + '">1</text>' +
924
+ '<circle cx="13" cy="16" r="1.5" fill="' + pColors.Accent + '"/>' +
925
+ '<text x="15" y="17" font-size="14" font-family="sans-serif" font-weight="600" fill="' + pColors.Primary + '">5</text>');
926
+ };
927
+
928
+ // Integer — whole number block
929
+ this._DataTypeIcons['Integer'] = function(pSize, pColors, pSW)
930
+ {
931
+ return _svg(pSize,
932
+ '<rect x="4" y="4" width="16" height="16" rx="3" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
933
+ '<text x="8" y="16.5" font-size="11" font-family="sans-serif" font-weight="700" fill="' + pColors.Accent + '">42</text>');
934
+ };
935
+
936
+ // PreciseNumber — decimal with precision dots
937
+ this._DataTypeIcons['PreciseNumber'] = function(pSize, pColors, pSW)
938
+ {
939
+ return _svg(pSize,
940
+ '<text x="2" y="16" font-size="13" font-family="sans-serif" font-weight="600" fill="' + pColors.Primary + '">.00</text>' +
941
+ '<circle cx="19" cy="6" r="1.2" fill="' + pColors.Accent + '"/>' +
942
+ '<circle cx="19" cy="10" r="1.2" fill="' + pColors.Accent + '"/>' +
943
+ '<circle cx="19" cy="14" r="1.2" fill="' + pColors.Accent + '"/>');
944
+ };
945
+
946
+ // Boolean — toggle switch
947
+ this._DataTypeIcons['Boolean'] = function(pSize, pColors, pSW)
948
+ {
949
+ return _svg(pSize,
950
+ '<rect x="2" y="7" width="20" height="10" rx="5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
951
+ '<circle cx="16" cy="12" r="3.5" fill="' + pColors.Accent + '"/>');
952
+ };
953
+
954
+ // Binary — two squares (0/1)
955
+ this._DataTypeIcons['Binary'] = function(pSize, pColors, pSW)
956
+ {
957
+ return _svg(pSize,
958
+ '<rect x="3" y="6" width="8" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
959
+ '<text x="5.5" y="15.5" font-size="9" font-family="monospace" fill="' + pColors.Primary + '">0</text>' +
960
+ '<rect x="13" y="6" width="8" height="12" rx="1.5" fill="' + pColors.Fill + '" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '"/>' +
961
+ '<text x="15.5" y="15.5" font-size="9" font-family="monospace" fill="' + pColors.Accent + '">1</text>');
962
+ };
963
+
964
+ // DateTime — clock
965
+ this._DataTypeIcons['DateTime'] = function(pSize, pColors, pSW)
966
+ {
967
+ return _svg(pSize,
968
+ '<circle cx="12" cy="12" r="9" fill="' + pColors.Fill + '" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '"/>' +
969
+ '<polyline points="12 7 12 12 16 14" stroke="' + pColors.Accent + '" stroke-width="' + pSW + '" fill="none"/>');
970
+ };
971
+
972
+ // Array — stacked brackets
973
+ this._DataTypeIcons['Array'] = function(pSize, pColors, pSW)
974
+ {
975
+ return _svg(pSize,
976
+ '<path d="M8 4H5v16h3" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
977
+ '<path d="M16 4h3v16h-3" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
978
+ '<circle cx="9" cy="12" r="1.2" fill="' + pColors.Accent + '"/>' +
979
+ '<circle cx="12" cy="12" r="1.2" fill="' + pColors.Accent + '"/>' +
980
+ '<circle cx="15" cy="12" r="1.2" fill="' + pColors.Accent + '"/>');
981
+ };
982
+
983
+ // Object — curly braces
984
+ this._DataTypeIcons['Object'] = function(pSize, pColors, pSW)
985
+ {
986
+ return _svg(pSize,
987
+ '<path d="M8 3H6a2 2 0 00-2 2v4.5a1.5 1.5 0 01-1.5 1.5 1.5 1.5 0 011.5 1.5V17a2 2 0 002 2h2" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>' +
988
+ '<path d="M16 3h2a2 2 0 012 2v4.5a1.5 1.5 0 001.5 1.5 1.5 1.5 0 00-1.5 1.5V17a2 2 0 01-2 2h-2" stroke="' + pColors.Primary + '" stroke-width="' + pSW + '" fill="none"/>');
989
+ };
990
+
991
+ // Null — empty circle with dash
992
+ this._DataTypeIcons['Null'] = function(pSize, pColors, pSW)
993
+ {
994
+ return _svg(pSize,
995
+ '<circle cx="12" cy="12" r="8" fill="none" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '" stroke-dasharray="3 2"/>' +
996
+ '<line x1="8" y1="12" x2="16" y2="12" stroke="' + pColors.Muted + '" stroke-width="' + pSW + '"/>');
997
+ };
998
+ }
999
+ }
1000
+
1001
+ module.exports = PictProviderFormEditorIconography;
1002
+ module.exports.default_configuration = _DefaultProviderConfiguration;