sdocs-dev 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -10
- package/public/sdocs-styles.js +162 -162
- package/public/brotli-wasm-v1.js +0 -518
- package/public/brotli_wasm_bg.wasm +0 -0
- package/public/css/layout.css +0 -240
- package/public/css/mobile.css +0 -196
- package/public/css/panel.css +0 -393
- package/public/css/rendered.css +0 -478
- package/public/css/tokens.css +0 -116
- package/public/css/write.css +0 -128
- package/public/fonts/inter-400.woff2 +0 -0
- package/public/fonts/inter-500.woff2 +0 -0
- package/public/fonts/inter-600.woff2 +0 -0
- package/public/images/examples.png +0 -0
- package/public/index.html +0 -694
- package/public/sdoc.md +0 -542
- package/public/sdocs-app.js +0 -812
- package/public/sdocs-charts.js +0 -905
- package/public/sdocs-controls.js +0 -354
- package/public/sdocs-export.js +0 -1090
- package/public/sdocs-state.js +0 -73
- package/public/sdocs-theme.js +0 -262
- package/public/sdocs-write.js +0 -740
- package/public/sw.js +0 -110
- package/public/vendor/marked.min.js +0 -6
- package/public/vendor/purify.min.js +0 -3
- package/server.js +0 -176
package/public/sdocs-controls.js
DELETED
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
// sdocs-controls.js — CSS variable management and control wiring
|
|
2
|
-
(function () {
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
var S = SDocs;
|
|
6
|
-
|
|
7
|
-
// ── CSS var updates ──────────────────────────────────
|
|
8
|
-
|
|
9
|
-
function applyControlToCss(id) {
|
|
10
|
-
var el = document.getElementById(id);
|
|
11
|
-
if (!el) return;
|
|
12
|
-
var v = el.value;
|
|
13
|
-
|
|
14
|
-
if (id === 'ctrl-font-family' || id === 'ctrl-h-font-family') {
|
|
15
|
-
var name = v.replace(/['"]/g,'').split(',')[0].trim();
|
|
16
|
-
if (S.GOOGLE_FONTS.includes(name)) S.loadGoogleFont(name);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
var allVals = readAllControlValues();
|
|
20
|
-
SDocStyles.controlToCssVars(id, v, allVals)
|
|
21
|
-
.forEach(function(a) { S.setStyleVar(a.cssVar, a.value); });
|
|
22
|
-
S.syncAll('controls');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function readAllControlValues() {
|
|
26
|
-
var vals = {};
|
|
27
|
-
Object.keys(SDocStyles.CTRL_CSS_MAP).forEach(function(id) {
|
|
28
|
-
var el = document.getElementById(id);
|
|
29
|
-
if (el) vals[id] = el.value;
|
|
30
|
-
});
|
|
31
|
-
Object.keys(SDocStyles.COLOR_VAR_MAP).forEach(function(id) {
|
|
32
|
-
var el = document.getElementById(id);
|
|
33
|
-
if (el) vals[id] = el.value;
|
|
34
|
-
});
|
|
35
|
-
return vals;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function syncRangeAndNumber(rangeId, numId) {
|
|
39
|
-
var r = document.getElementById(rangeId);
|
|
40
|
-
var n = document.getElementById(numId);
|
|
41
|
-
r.addEventListener('input', function() { n.value = r.value; applyControlToCss(numId); });
|
|
42
|
-
n.addEventListener('input', function() { r.value = n.value; applyControlToCss(numId); });
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
SDocStyles.RANGE_NUM_PAIRS.forEach(function(pair) { syncRangeAndNumber(pair[0], pair[1]); });
|
|
46
|
-
|
|
47
|
-
var STANDALONE_COLOR_IDS = new Set(SDocStyles.STANDALONE_COLOR_IDS);
|
|
48
|
-
|
|
49
|
-
[
|
|
50
|
-
'ctrl-font-family','ctrl-h-font-family',
|
|
51
|
-
'ctrl-h1-weight','ctrl-h2-weight','ctrl-h3-weight','ctrl-h4-weight',
|
|
52
|
-
'ctrl-bg-color','ctrl-link-color','ctrl-link-decoration',
|
|
53
|
-
'ctrl-code-font',
|
|
54
|
-
'ctrl-bq-border-color',
|
|
55
|
-
'ctrl-chart-accent','ctrl-chart-palette',
|
|
56
|
-
].forEach(function(id) {
|
|
57
|
-
var handler = function() { if (STANDALONE_COLOR_IDS.has(id)) S.overriddenColors.add(id); applyControlToCss(id); S.syncAll('controls'); };
|
|
58
|
-
document.getElementById(id).addEventListener('input', handler);
|
|
59
|
-
document.getElementById(id).addEventListener('change', handler);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// ── Color cascade ──────────────────────────────────
|
|
63
|
-
|
|
64
|
-
var COLOR_VAR = SDocStyles.COLOR_VAR_MAP;
|
|
65
|
-
var COLOR_CHILDREN = SDocStyles.COLOR_CASCADE;
|
|
66
|
-
|
|
67
|
-
function setColorValue(ctrlId, value, userAction) {
|
|
68
|
-
if (userAction) S.overriddenColors.add(ctrlId);
|
|
69
|
-
var varName = COLOR_VAR[ctrlId];
|
|
70
|
-
if (Array.isArray(varName)) {
|
|
71
|
-
varName.forEach(function(v) { S.setStyleVar(v, value); });
|
|
72
|
-
} else {
|
|
73
|
-
S.setStyleVar(varName, value);
|
|
74
|
-
}
|
|
75
|
-
var ctrl = document.getElementById(ctrlId);
|
|
76
|
-
if (ctrl) ctrl.value = value;
|
|
77
|
-
var children = COLOR_CHILDREN[ctrlId] || [];
|
|
78
|
-
for (var i = 0; i < children.length; i++) {
|
|
79
|
-
if (!S.overriddenColors.has(children[i])) {
|
|
80
|
-
setColorValue(children[i], value, false);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Refresh charts when block/chart colors change
|
|
84
|
-
if (S.refreshChartColors && (ctrlId === 'ctrl-chart-bg' || ctrlId === 'ctrl-chart-text' ||
|
|
85
|
-
ctrlId === 'ctrl-block-bg' || ctrlId === 'ctrl-block-text')) {
|
|
86
|
-
S.refreshChartColors();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function findParent(ctrlId) {
|
|
91
|
-
for (var pid in COLOR_CHILDREN) {
|
|
92
|
-
if (COLOR_CHILDREN[pid].indexOf(ctrlId) !== -1) return pid;
|
|
93
|
-
}
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function resetColorValue(ctrlId) {
|
|
98
|
-
S.overriddenColors.delete(ctrlId);
|
|
99
|
-
var parent = findParent(ctrlId);
|
|
100
|
-
var value;
|
|
101
|
-
if (!parent) {
|
|
102
|
-
// Cascade root: use theme default
|
|
103
|
-
value = ctrlId === 'ctrl-color' ? S.getColorDefault() : S.getStandaloneDefault(ctrlId);
|
|
104
|
-
} else {
|
|
105
|
-
var parentEl = document.getElementById(parent);
|
|
106
|
-
value = parentEl ? parentEl.value : S.getColorDefault();
|
|
107
|
-
}
|
|
108
|
-
setColorValue(ctrlId, value, false);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
Object.keys(COLOR_VAR).forEach(function(ctrlId) {
|
|
112
|
-
var el = document.getElementById(ctrlId);
|
|
113
|
-
if (!el) return;
|
|
114
|
-
var handler = function() { setColorValue(ctrlId, el.value, true); S.syncAll('controls'); };
|
|
115
|
-
el.addEventListener('input', handler);
|
|
116
|
-
el.addEventListener('change', handler);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// Cascade color reset buttons
|
|
120
|
-
document.getElementById('reset-color').addEventListener('click', function() { S.overriddenColors.delete('ctrl-color'); setColorValue('ctrl-color', S.getColorDefault(), false); S.syncAll('controls'); });
|
|
121
|
-
['ctrl-h-color','ctrl-h1-color','ctrl-h2-color','ctrl-h3-color','ctrl-h4-color','ctrl-p-color','ctrl-list-color'].forEach(function(ctrlId) {
|
|
122
|
-
var btn = document.getElementById('reset-' + ctrlId.replace('ctrl-', ''));
|
|
123
|
-
if (btn) btn.addEventListener('click', function() { resetColorValue(ctrlId); S.syncAll('controls'); });
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// Block cascade resets
|
|
127
|
-
['ctrl-block-bg','ctrl-block-text','ctrl-code-bg','ctrl-code-color','ctrl-bq-bg','ctrl-bq-color','ctrl-chart-bg','ctrl-chart-text'].forEach(function(ctrlId) {
|
|
128
|
-
var btnId = 'reset-' + ctrlId.replace('ctrl-', '');
|
|
129
|
-
var btn = document.getElementById(btnId);
|
|
130
|
-
if (btn) btn.addEventListener('click', function() { resetColorValue(ctrlId); S.syncAll('controls'); });
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
['ctrl-bg-color','ctrl-link-color','ctrl-bq-border-color','ctrl-chart-accent'].forEach(function(ctrlId) {
|
|
134
|
-
var btnId = 'reset-' + ctrlId.replace('ctrl-', '');
|
|
135
|
-
document.getElementById(btnId).addEventListener('click', function() {
|
|
136
|
-
var defaultVal = S.getStandaloneDefault(ctrlId);
|
|
137
|
-
var el = document.getElementById(ctrlId);
|
|
138
|
-
S.overriddenColors.delete(ctrlId);
|
|
139
|
-
el.value = defaultVal;
|
|
140
|
-
var assignments = SDocStyles.controlToCssVars(ctrlId, defaultVal, readAllControlValues());
|
|
141
|
-
assignments.forEach(function(a) { S.setStyleVar(a.cssVar, a.value); });
|
|
142
|
-
S.syncAll('controls');
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// ── Apply styles from meta → controls ──────────────────
|
|
147
|
-
|
|
148
|
-
function setControlValue(id, val) {
|
|
149
|
-
if (val === undefined || val === null) return;
|
|
150
|
-
var el = document.getElementById(id);
|
|
151
|
-
if (!el) return;
|
|
152
|
-
el.value = val;
|
|
153
|
-
var rangeId = id.replace(/-num$/, '-range');
|
|
154
|
-
var rng = document.getElementById(rangeId);
|
|
155
|
-
if (rng) rng.value = val;
|
|
156
|
-
applyControlToCss(id);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function applyStylesFromMeta(s) {
|
|
160
|
-
if (!s) return;
|
|
161
|
-
// Suppress syncAll during batch updates to avoid capturing partial state
|
|
162
|
-
var wasSyncing = S._syncing;
|
|
163
|
-
S._syncing = true;
|
|
164
|
-
|
|
165
|
-
var result = SDocStyles.stylesToControls(s);
|
|
166
|
-
var controls = result.controls;
|
|
167
|
-
|
|
168
|
-
// Font family selects need special handling to match bare names against <option> values
|
|
169
|
-
[['fontFamily', 'ctrl-font-family'], ['headers.fontFamily', 'ctrl-h-font-family']].forEach(function(pair) {
|
|
170
|
-
var styleKey = pair[0], ctrlId = pair[1];
|
|
171
|
-
var fontName = styleKey === 'fontFamily' ? s.fontFamily : (s.headers || {}).fontFamily;
|
|
172
|
-
if (fontName) {
|
|
173
|
-
var sel = document.getElementById(ctrlId);
|
|
174
|
-
var match = [].slice.call(sel.options).find(function(o) {
|
|
175
|
-
return o.value.replace(/['"]/g,'').split(',')[0].trim() === fontName ||
|
|
176
|
-
o.textContent === fontName;
|
|
177
|
-
});
|
|
178
|
-
if (match) { sel.value = match.value; applyControlToCss(ctrlId); }
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
Object.keys(controls).forEach(function(id) {
|
|
183
|
-
if (id === 'ctrl-font-family' || id === 'ctrl-h-font-family') return;
|
|
184
|
-
if (SDocStyles.COLOR_VAR_MAP[id]) return;
|
|
185
|
-
setControlValue(id, controls[id]);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Top-level colors = light theme. dark: block = explicit dark overrides.
|
|
189
|
-
var lightOverridden = S.themeOverridden.light;
|
|
190
|
-
var lightColors = S.themeColors.light;
|
|
191
|
-
var newOverridden = result.overriddenColors;
|
|
192
|
-
|
|
193
|
-
lightOverridden.clear();
|
|
194
|
-
S.themeOverridden.dark.clear();
|
|
195
|
-
|
|
196
|
-
newOverridden.forEach(function(id) {
|
|
197
|
-
lightOverridden.add(id);
|
|
198
|
-
lightColors[id] = controls[id];
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// Also store standalone colors from legacy format into light theme
|
|
202
|
-
var legacyStandalone = [];
|
|
203
|
-
if (s.background) legacyStandalone.push(['ctrl-bg-color', s.background]);
|
|
204
|
-
if (s.link && s.link.color) legacyStandalone.push(['ctrl-link-color', s.link.color]);
|
|
205
|
-
if (s.code) {
|
|
206
|
-
if (s.code.background) legacyStandalone.push(['ctrl-code-bg', s.code.background]);
|
|
207
|
-
if (s.code.color) legacyStandalone.push(['ctrl-code-color', s.code.color]);
|
|
208
|
-
}
|
|
209
|
-
if (s.blocks) {
|
|
210
|
-
if (s.blocks.background) legacyStandalone.push(['ctrl-block-bg', s.blocks.background]);
|
|
211
|
-
if (s.blocks.color) legacyStandalone.push(['ctrl-block-text', s.blocks.color]);
|
|
212
|
-
}
|
|
213
|
-
if (s.blockquote) {
|
|
214
|
-
if (s.blockquote.borderColor) legacyStandalone.push(['ctrl-bq-border-color', s.blockquote.borderColor]);
|
|
215
|
-
if (s.blockquote.background) legacyStandalone.push(['ctrl-bq-bg', s.blockquote.background]);
|
|
216
|
-
if (s.blockquote.color) legacyStandalone.push(['ctrl-bq-color', s.blockquote.color]);
|
|
217
|
-
}
|
|
218
|
-
if (s.chart) {
|
|
219
|
-
if (s.chart.background) legacyStandalone.push(['ctrl-chart-bg', s.chart.background]);
|
|
220
|
-
if (s.chart.textColor) legacyStandalone.push(['ctrl-chart-text', s.chart.textColor]);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// File-info card overrides (no UI controls — driven entirely by YAML).
|
|
224
|
-
S.fileinfoStyles = {};
|
|
225
|
-
if (s.fileinfo) {
|
|
226
|
-
if (s.fileinfo.background) {
|
|
227
|
-
S.fileinfoStyles.background = s.fileinfo.background;
|
|
228
|
-
S.setStyleVar('--md-fic-bg', s.fileinfo.background);
|
|
229
|
-
}
|
|
230
|
-
if (s.fileinfo.color) {
|
|
231
|
-
S.fileinfoStyles.color = s.fileinfo.color;
|
|
232
|
-
S.setStyleVar('--md-fic-text', s.fileinfo.color);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
legacyStandalone.forEach(function(pair) {
|
|
236
|
-
lightOverridden.add(pair[0]);
|
|
237
|
-
lightColors[pair[0]] = pair[1];
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// Auto-generate dark theme from light colors via lightness inversion
|
|
241
|
-
var darkOverridden = S.themeOverridden.dark;
|
|
242
|
-
var darkColors = S.themeColors.dark;
|
|
243
|
-
|
|
244
|
-
// Parse explicit dark: overrides from YAML and persist for serialization
|
|
245
|
-
var explicitDark = s.dark ? SDocStyles.parseDarkBlock(s.dark) : {};
|
|
246
|
-
S._explicitDarkOverrides = s.dark || null;
|
|
247
|
-
|
|
248
|
-
// For every light color, auto-generate dark unless explicitly overridden
|
|
249
|
-
lightOverridden.forEach(function(id) {
|
|
250
|
-
if (explicitDark[id]) {
|
|
251
|
-
darkOverridden.add(id);
|
|
252
|
-
darkColors[id] = explicitDark[id];
|
|
253
|
-
} else {
|
|
254
|
-
darkOverridden.add(id);
|
|
255
|
-
darkColors[id] = SDocStyles.invertLightness(lightColors[id]);
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// Also apply any dark: colors that weren't in light (e.g. dark-only overrides)
|
|
260
|
-
Object.keys(explicitDark).forEach(function(id) {
|
|
261
|
-
if (!darkOverridden.has(id)) {
|
|
262
|
-
darkOverridden.add(id);
|
|
263
|
-
darkColors[id] = explicitDark[id];
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// Now apply the active theme's colors
|
|
268
|
-
S._syncing = wasSyncing;
|
|
269
|
-
S.loadThemeColors(S.activeTheme);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function collectStyles() {
|
|
273
|
-
S.saveCurrentThemeColors();
|
|
274
|
-
// Always emit top-level colors (light) via the simple collector
|
|
275
|
-
var styles = SDocStyles.collectStyles(readAllControlValues(), S.overriddenColors);
|
|
276
|
-
|
|
277
|
-
// Emit dark: block for any explicitly set dark overrides
|
|
278
|
-
// (don't emit auto-inverted values — those are generated on load)
|
|
279
|
-
if (S._explicitDarkOverrides && Object.keys(S._explicitDarkOverrides).length > 0) {
|
|
280
|
-
var darkBlock = SDocStyles.parseDarkBlock(S._explicitDarkOverrides);
|
|
281
|
-
// parseDarkBlock expects the YAML format, but _explicitDarkOverrides IS the YAML dark: object
|
|
282
|
-
styles.dark = S._explicitDarkOverrides;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// File-info card overrides (no UI controls; round-trip from YAML)
|
|
286
|
-
if (S.fileinfoStyles && Object.keys(S.fileinfoStyles).length > 0) {
|
|
287
|
-
styles.fileinfo = Object.assign({}, S.fileinfoStyles);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return styles;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// ── Reset all styles ──────────────────────────────────
|
|
294
|
-
|
|
295
|
-
function resetAllStyles() {
|
|
296
|
-
// Clear both theme states
|
|
297
|
-
S.themeOverridden.light.clear();
|
|
298
|
-
S.themeOverridden.dark.clear();
|
|
299
|
-
S.themeColors.light = {};
|
|
300
|
-
S.themeColors.dark = {};
|
|
301
|
-
// Clear file-info-card overrides and the CSS vars they set
|
|
302
|
-
S.fileinfoStyles = {};
|
|
303
|
-
S.setStyleVar('--md-fic-bg', '');
|
|
304
|
-
S.setStyleVar('--md-fic-text', '');
|
|
305
|
-
|
|
306
|
-
setColorValue('ctrl-color', S.getColorDefault(), false);
|
|
307
|
-
// Reset block cascade roots to theme defaults
|
|
308
|
-
setColorValue('ctrl-block-bg', S.getStandaloneDefault('ctrl-block-bg') || '#f4f1ed', false);
|
|
309
|
-
setColorValue('ctrl-block-text', S.getStandaloneDefault('ctrl-block-text') || '#6b6560', false);
|
|
310
|
-
// Set standalone color controls to theme-appropriate defaults
|
|
311
|
-
STANDALONE_COLOR_IDS.forEach(function(ctrlId) {
|
|
312
|
-
var el = document.getElementById(ctrlId);
|
|
313
|
-
if (el) el.value = S.getStandaloneDefault(ctrlId);
|
|
314
|
-
});
|
|
315
|
-
document.querySelectorAll('#right input, #right select').forEach(function(el) {
|
|
316
|
-
if (STANDALONE_COLOR_IDS.has(el.id)) return; // already set above
|
|
317
|
-
if (el.type === 'range' || el.type === 'number') el.value = el.defaultValue;
|
|
318
|
-
else if (el.tagName === 'SELECT') el.selectedIndex = [].slice.call(el.options).findIndex(function(o) { return o.defaultSelected; });
|
|
319
|
-
else if (el.type === 'color') el.value = el.defaultValue;
|
|
320
|
-
});
|
|
321
|
-
['ctrl-bg-color','ctrl-font-family','ctrl-base-size-num','ctrl-line-height-num',
|
|
322
|
-
'ctrl-h-font-family','ctrl-h-scale-num','ctrl-h-mb-num',
|
|
323
|
-
'ctrl-h1-size-num','ctrl-h1-weight','ctrl-h2-size-num','ctrl-h2-weight',
|
|
324
|
-
'ctrl-h3-size-num','ctrl-h3-weight','ctrl-h4-size-num','ctrl-h4-weight',
|
|
325
|
-
'ctrl-p-lh-num','ctrl-p-mb-num',
|
|
326
|
-
'ctrl-link-color','ctrl-link-decoration',
|
|
327
|
-
'ctrl-code-font',
|
|
328
|
-
'ctrl-bq-border-color','ctrl-bq-bw-num','ctrl-bq-size-num',
|
|
329
|
-
'ctrl-list-spacing-num','ctrl-list-indent-num',
|
|
330
|
-
'ctrl-chart-accent','ctrl-chart-palette',
|
|
331
|
-
].forEach(function(id) { applyControlToCss(id); });
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// ── Init: set colors to theme-appropriate defaults ──────
|
|
335
|
-
|
|
336
|
-
if (document.documentElement.dataset.theme === 'dark') {
|
|
337
|
-
STANDALONE_COLOR_IDS.forEach(function(ctrlId) {
|
|
338
|
-
var el = document.getElementById(ctrlId);
|
|
339
|
-
if (el) el.value = S.getStandaloneDefault(ctrlId);
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
setColorValue('ctrl-color', S.getColorDefault(), false);
|
|
344
|
-
|
|
345
|
-
// ── Register on SDocs for cross-module access ──────────
|
|
346
|
-
|
|
347
|
-
S.setColorValue = setColorValue;
|
|
348
|
-
S.readAllControlValues = readAllControlValues;
|
|
349
|
-
S.collectStyles = collectStyles;
|
|
350
|
-
S.applyStylesFromMeta = applyStylesFromMeta;
|
|
351
|
-
S.resetAllStyles = resetAllStyles;
|
|
352
|
-
S.STANDALONE_COLOR_IDS = STANDALONE_COLOR_IDS;
|
|
353
|
-
|
|
354
|
-
})();
|