total5 0.0.1 → 0.0.2

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/cms.js ADDED
@@ -0,0 +1,759 @@
1
+ // Total.js CMS compiler
2
+ // The MIT License
3
+ // Copyright 2021-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ 'use strict';
6
+
7
+ const SKIP_CLASSES = { CMS_hidden: 1, CMS_mv: 1, CMS_mh: 1, CMS_expression: 1, CMS_multiple: 1, CMS_keyword: 1, CMS_monospace: 1 };
8
+ const VERSION = 1;
9
+
10
+ function clean(html) {
11
+ var index = html.indexOf('>');
12
+ var tag = html.substring(5, index);
13
+ tag = tag.replace(/data-cms=".*?"(\s)?|data-cms-id=".*?"(\s)?/, '').trim();
14
+ return '<div' + (tag ? (' ' + tag) : '') + '>' + html.substring(index + 1);
15
+ }
16
+
17
+ function expressions_multiple(body) {
18
+
19
+ var index = 0;
20
+ var arr = [];
21
+
22
+ while (true) {
23
+
24
+ index = body.indexOf('CMS_multiple', index + 12);
25
+ if (index === -1)
26
+ break;
27
+
28
+ var b = findstart(body, index);
29
+ if (b === -1)
30
+ break;
31
+
32
+ var end = body.indexOf(' ', b);
33
+ if (end === -1) {
34
+ index += 13;
35
+ continue;
36
+ }
37
+
38
+ var tag = body.substring(b + 1, end);
39
+
40
+ var e = body.indexOf('</' + tag + '>', index);
41
+ var size = e + 3 + tag.length;
42
+ var obj = {};
43
+
44
+ obj.id = body.substring(b, body.indexOf('>', b + tag.length)).match(/\s(data-cms-|data-)?id=".*?"/);
45
+
46
+ if (obj.id) {
47
+ obj.id = obj.id[0];
48
+ var qi = obj.id.indexOf('"');
49
+ obj.id = obj.id.substring(qi + 1, obj.id.length - 1).trim();
50
+ }
51
+
52
+ obj.html = body.substring(b, size);
53
+ obj.body = obj.html.substring(obj.html.indexOf('>') + 1, obj.html.lastIndexOf('<'));
54
+ obj.expressions = expressions(obj.body);
55
+ obj.replace = '<!--cmsmultiple' + GUID(10) + '-->';
56
+
57
+ arr.push(obj);
58
+ index = e + 3 + tag.length;
59
+ }
60
+
61
+ return arr;
62
+ }
63
+
64
+ function findstart(body, index) {
65
+
66
+ var notallowed = [';', '.', '>', ':', '\n', '\r', '\t'];
67
+
68
+ for (let i = index; i > -1; i--) {
69
+
70
+ let c = body[i];
71
+ if (c === '<')
72
+ return i;
73
+
74
+ if (notallowed.includes(c))
75
+ break;
76
+ }
77
+
78
+ return -1;
79
+ }
80
+
81
+ function expressions(body) {
82
+
83
+ var index = 0;
84
+ var arr = [];
85
+
86
+ while (true) {
87
+
88
+ index = body.indexOf('CMS_expression', index + 10);
89
+
90
+ if (index === -1)
91
+ break;
92
+
93
+ var b = findstart(body, index);
94
+ if (b === -1)
95
+ break;
96
+
97
+ var end = body.indexOf(' ', b);
98
+ if (end === -1) {
99
+ index += 15;
100
+ continue;
101
+ }
102
+
103
+ var tag = body.substring(b + 1, end);
104
+ var e = body.indexOf('</' + tag + '>', index);
105
+ var size = e + 3 + tag.length;
106
+ var obj = {};
107
+ obj.replace = obj.html = body.substring(b, size);
108
+ obj.body = obj.html.substring(obj.html.indexOf('>') + 1, obj.html.lastIndexOf('<'));
109
+ obj.text = obj.body.removeTags();
110
+ arr.push(obj);
111
+ index = e + 3 + tag.length;
112
+ }
113
+
114
+ return arr;
115
+ }
116
+
117
+ function trash(body) {
118
+ var index = 0;
119
+ var tags = ['CMS_trash', 'CMS_editor'];
120
+
121
+ for (var t of tags) {
122
+ while (true) {
123
+
124
+ index = body.indexOf(t, index + t.length);
125
+
126
+ if (index === -1)
127
+ break;
128
+
129
+ var b = findstart(body, index);
130
+ if (b === -1)
131
+ break;
132
+
133
+ var end = body.indexOf(' ', b);
134
+
135
+ if (end === -1) {
136
+ index += t.length + 1;
137
+ continue;
138
+ }
139
+
140
+ var tag = body.substring(b + 1, end);
141
+
142
+ if (tag.length > 10) {
143
+ index += tag.length;
144
+ continue;
145
+ }
146
+
147
+ var e = body.indexOf('</' + tag + '>', index);
148
+ var size = e + 3 + tag.length;
149
+ body = body.replace(body.substring(b, size), '');
150
+ index = b;
151
+ }
152
+ }
153
+
154
+ return body;
155
+ }
156
+
157
+ function layout(body, append) {
158
+
159
+ var index = body.indexOf(' id="CMS"');
160
+ if (index === -1)
161
+ return body;
162
+
163
+ var beg = body.lastIndexOf('<', index);
164
+ if (beg === -1)
165
+ return body;
166
+
167
+ var tag = body.substring(beg + 1, body.indexOf(' ', beg));
168
+ var tagend = '</' + tag + '>';
169
+ var count = 0;
170
+ var end = body.indexOf('>', beg) + 1;
171
+
172
+ tag = '<' + tag;
173
+
174
+ while (true) {
175
+
176
+ var str = body.substring(index, index + tagend.length);
177
+
178
+ if (index >= body.length) {
179
+ beg = body.length;
180
+ break;
181
+ }
182
+
183
+ if (str === tagend) {
184
+ if (count) {
185
+ count--;
186
+ index++;
187
+ continue;
188
+ }
189
+ return body.substring(0, end) + append + body.substring(index);
190
+ }
191
+
192
+ if (str.substring(0, tag.length) === tag)
193
+ count++;
194
+
195
+ index++;
196
+ }
197
+
198
+ return body;
199
+ }
200
+
201
+ // Cleans CMS markup
202
+ function tidy(body) {
203
+
204
+ var beg;
205
+ var end;
206
+ var index = 0;
207
+ var count = 0;
208
+ var c = 'CMS_unwrap';
209
+ var tag;
210
+ var tagend;
211
+
212
+ body = F.TUtils.minify_html(body);
213
+
214
+ while (true) {
215
+
216
+ beg = body.indexOf(c, beg);
217
+
218
+ if (beg === -1)
219
+ break;
220
+
221
+ index = beg;
222
+ while (true) {
223
+ if (body[--index] === '<' || index <= 0)
224
+ break;
225
+ }
226
+
227
+ if (index === beg || index <= 0)
228
+ return;
229
+
230
+ tag = body.substring(index + 1, body.indexOf('>', index + 1));
231
+ end = index + tag.length + 2;
232
+ tag = tag.substring(0, tag.indexOf(' '));
233
+ tagend = '</' + tag;
234
+ tag = '<' + tag;
235
+ count = 0;
236
+ beg = index;
237
+ index = end;
238
+
239
+ while (true) {
240
+ var str = body.substring(index, index + tagend.length);
241
+
242
+ if (index >= body.length) {
243
+ beg = body.length;
244
+ break;
245
+ }
246
+
247
+ if (str === tagend) {
248
+
249
+ if (count) {
250
+ count--;
251
+ index++;
252
+ continue;
253
+ }
254
+
255
+ body = body.substring(0, beg) + body.substring(end, index) + body.substring(index + 1 + tagend.length);
256
+ break;
257
+ }
258
+
259
+ if (str.substring(0, tag.length) === tag)
260
+ count++;
261
+
262
+ index++;
263
+ }
264
+ }
265
+
266
+ return body.replace(/(\s)class=".*?"/g, function(text) {
267
+
268
+ var is = text[0] === ' ';
269
+ var arr = text.substring(is ? 8 : 7, text.length - 1).split(' ');
270
+ var builder = '';
271
+
272
+ for (let cls of arr) {
273
+ if (cls[0] === 'C' && cls[1] === 'M' && cls[2] === 'S' && !SKIP_CLASSES[cls])
274
+ continue;
275
+ builder += (builder ? ' ' : '') + cls;
276
+ }
277
+
278
+ return builder ? ((is ? ' ' : '') + 'class="' + builder + '"') : '';
279
+
280
+ }).replace(/<div\s>/g, '<div>');
281
+ }
282
+
283
+ exports.widgets = function(html) {
284
+
285
+ let arr = html.match(/data-cms=".*?"/g) || EMPTYARRAY;
286
+ let response = [];
287
+ let indexer = 0;
288
+ let index;
289
+ let beg;
290
+ let end;
291
+
292
+ for (let attr of arr) {
293
+
294
+ if (html.indexOf(attr) === -1)
295
+ continue;
296
+
297
+ let w = attr.substring(10);
298
+ index = w.indexOf('__');
299
+ let id = w.substring(0, index);
300
+
301
+ index = html.lastIndexOf('<', html.indexOf(attr));
302
+ beg = '<div';
303
+ end = '</div>';
304
+
305
+ let pos = index + 1;
306
+ let count = 0;
307
+ let counter = 0;
308
+
309
+ while (true) {
310
+
311
+ if (counter++ > 100)
312
+ break;
313
+
314
+ let a = html.indexOf(beg, pos);
315
+ let b = html.indexOf(end, pos);
316
+
317
+ if (a !== -1 && a < b) {
318
+ count++;
319
+ pos = html.indexOf('>', a);
320
+ continue;
321
+ }
322
+
323
+ if (a === -1 || b < a) {
324
+
325
+ pos = b + 6;
326
+
327
+ if (count) {
328
+ count--;
329
+ continue;
330
+ }
331
+
332
+ break;
333
+ }
334
+ }
335
+
336
+ let body = html.substring(index, pos);
337
+ html = html.replace(body, clean(body));
338
+ index = body.indexOf('>');
339
+ body = body.substring(0, index + 1) + '~BEG~' + body.substring(index + 1);
340
+ index = body.lastIndexOf('<');
341
+ body = body.substring(0, index) + '~END~' + body.substring(index);
342
+
343
+ index = w.indexOf('__');
344
+
345
+ let config = decodeURIComponent(w.substring(index + 2, w.length - 1)).parseJSON(true);
346
+ let opt = {};
347
+
348
+ opt.id = id;
349
+ opt.indexer = indexer;
350
+ opt.body = tidy(clean(body));
351
+ opt.html = body.substring(body.lastIndexOf('~BEG~') + 5, body.lastIndexOf('~END~'));
352
+ opt.config = config || EMPTYOBJECT;
353
+ opt.beg = opt.body.substring(0, opt.body.indexOf('>') + 1);
354
+ opt.end = opt.body.substring(opt.body.lastIndexOf('<'));
355
+
356
+ index = opt.beg.indexOf('data-cms-id="');
357
+
358
+ if (index === -1)
359
+ opt.uid = opt.beg.makeid();
360
+ else
361
+ opt.uid = opt.beg.substring(index + 13, opt.beg.indexOf('"', index + 14));
362
+
363
+ response.push(opt);
364
+ indexer++;
365
+ }
366
+
367
+ return response;
368
+ };
369
+
370
+ exports.compile = function(html, widgets, used) {
371
+
372
+ let arr = html.match(/data-cms=".*?"/g) || EMPTYARRAY;
373
+ let response = new CMSRender();
374
+ let indexer = 0;
375
+ let index;
376
+ let beg;
377
+ let end;
378
+
379
+ response.css = [];
380
+ response.js = [];
381
+ response.widgets = [];
382
+ response.cache = {};
383
+ response.tangular = [];
384
+
385
+ if (!used) {
386
+ for (let widget of widgets) {
387
+ if (widget.css)
388
+ response.css.push(F.TUtils.minify_css(widget.css));
389
+ if (widget.js)
390
+ response.js.push(F.TUtils.minify_js(widget.js));
391
+ if (widget.ui) {
392
+ widget.ui.css && response.css.push(F.TUtils.minify_css(widget.ui.css));
393
+ widget.ui.js && response.js.push(F.TUtils.minify_js(widget.ui.js));
394
+ }
395
+ }
396
+ }
397
+
398
+ for (let attr of arr) {
399
+
400
+ if (html.indexOf(attr) === -1)
401
+ continue;
402
+
403
+ let w = attr.substring(10);
404
+ index = w.indexOf('__');
405
+ let id = w.substring(0, index);
406
+
407
+ index = html.lastIndexOf('<', html.indexOf(attr));
408
+ beg = '<div';
409
+ end = '</div>';
410
+
411
+ let pos = index + 1;
412
+ let count = 0;
413
+ let counter = 0;
414
+
415
+ while (true) {
416
+
417
+ if (counter++ > 100)
418
+ break;
419
+
420
+ let a = html.indexOf(beg, pos);
421
+ let b = html.indexOf(end, pos);
422
+
423
+ if (a !== -1 && a < b) {
424
+ count++;
425
+ pos = html.indexOf('>', a);
426
+ continue;
427
+ }
428
+
429
+ if (a === -1 || b < a) {
430
+
431
+ pos = b + 6;
432
+
433
+ if (count) {
434
+ count--;
435
+ continue;
436
+ }
437
+
438
+ break;
439
+ }
440
+ }
441
+
442
+ let widget = widgets instanceof Array ? widgets.findItem('id', id) : widgets[id];
443
+ let body = html.substring(index, pos);
444
+
445
+ // Widget not found
446
+ if (!widget) {
447
+ html = html.replace(body, '');
448
+ continue;
449
+ }
450
+
451
+ if (used) {
452
+
453
+ if (widget.css)
454
+ response.css.push(F.TUtils.minify_css(widget.css));
455
+
456
+ if (widget.js)
457
+ response.js.push(F.TUtils.minify_js(widget.js));
458
+
459
+ if (widget.ui) {
460
+ widget.ui.css && response.css.push(F.TUtils.minify_css(widget.ui.css));
461
+ widget.ui.js && response.js.push(F.TUtils.minify_js(widget.ui.js));
462
+ }
463
+
464
+ }
465
+
466
+ if (!widget.render) {
467
+ html = html.replace(body, clean(body));
468
+ continue;
469
+ }
470
+
471
+ html = html.replace(body, '~WIDGET' + indexer + '~');
472
+ index = body.indexOf('>');
473
+ body = body.substring(0, index + 1) + '~BEG~' + body.substring(index + 1);
474
+ index = body.lastIndexOf('<');
475
+ body = body.substring(0, index) + '~END~' + body.substring(index);
476
+
477
+ index = w.indexOf('__');
478
+
479
+ let config = decodeURIComponent(w.substring(index + 2, w.length - 1)).parseJSON(true);
480
+ let opt = {};
481
+ opt.id = id;
482
+ opt.indexer = indexer;
483
+ opt.body = tidy(clean(body));
484
+ opt.html = body.substring(body.lastIndexOf('~BEG~') + 5, body.lastIndexOf('~END~'));
485
+ opt.config = config || EMPTYOBJECT;
486
+ opt.render = widget.render;
487
+ opt.beg = opt.body.substring(0, opt.body.indexOf('>') + 1);
488
+ opt.end = opt.body.substring(opt.body.lastIndexOf('<'));
489
+
490
+ index = opt.beg.indexOf('data-cms-id="');
491
+
492
+ if (index === -1)
493
+ opt.uid = opt.beg.makeid();
494
+ else
495
+ opt.uid = opt.beg.substring(index + 13, opt.beg.indexOf('"', index + 14));
496
+
497
+ response.widgets.push(opt);
498
+ indexer++;
499
+ }
500
+
501
+ index = 0;
502
+
503
+ while (true) {
504
+
505
+ index = html.indexOf(' type="text/navigation"', index);
506
+
507
+ if (index === -1)
508
+ break;
509
+
510
+ let begindex = html.lastIndexOf('<script', index);
511
+ let endindex = html.indexOf('</script>', index);
512
+ let endhead = html.indexOf('>', index);
513
+ let head = html.substring(begindex, endhead);
514
+ let name = head.match(/name=".*?"/i)[0];
515
+ let template = html.substring(html.indexOf('>', endhead) + 1, endindex);
516
+
517
+ name = name.substring(6, name.length - 1);
518
+ html = html.replace(html.substring(begindex, endindex + 9), '~WIDGET#' + response.tangular.length + '~');
519
+ response.tangular.push({ id: HASH(name).toString(36), name: name, type: 'nav', template: Tangular.compile(template) });
520
+ index = begindex;
521
+
522
+ }
523
+
524
+ index = 0;
525
+
526
+ while (true) {
527
+
528
+ index = html.indexOf(' type="text/breadcrumb"', index);
529
+
530
+ if (index === -1)
531
+ break;
532
+
533
+ let begindex = html.lastIndexOf('<script', index);
534
+ let endindex = html.indexOf('</script>', index);
535
+ let endhead = html.indexOf('>', index);
536
+ let template = html.substring(html.indexOf('>', endhead) + 1, endindex);
537
+ html = html.replace(html.substring(begindex, endindex + 9), '~WIDGET#' + response.tangular.length + '~');
538
+ response.tangular.push({ type: 'breadcrumb', template: Tangular.compile(template) });
539
+ index = begindex;
540
+ }
541
+
542
+ response.html = tidy(trash(layout(html, '~WIDGETLAYOUT~')));
543
+ response.multiple = expressions_multiple(response.html);
544
+
545
+ for (let item of response.multiple)
546
+ response.html = response.html.replace(item.html, item.replace);
547
+
548
+ response.expressions = expressions(response.html);
549
+ response.widgets.reverse();
550
+
551
+ let builder = [];
552
+ let text = [];
553
+
554
+ while (true) {
555
+
556
+ beg = response.html.indexOf('~WIDGET');
557
+
558
+ if (beg !== -1) {
559
+ end = response.html.indexOf('~', beg + 6) + 1;
560
+ let h = response.html.substring(0, beg);
561
+ let windex = response.html.substring(beg + 7, end - 1);
562
+ if (windex[0] === '#') {
563
+ response.html = response.html.substring(end);
564
+ builder.push('text[{0}]+tangular[{1}]'.format(text.push(h) - 1, windex.substring(1)));
565
+ } else if (windex === 'LAYOUT') {
566
+ response.html = response.html.substring(end);
567
+ builder.push('text[{0}]+body'.format(text.push(h) - 1));
568
+ } else {
569
+ indexer = +windex;
570
+ response.html = response.html.substring(end);
571
+ if (h)
572
+ builder.push('text[{0}]+widget[{1}]'.format(text.push(h) - 1, indexer));
573
+ else
574
+ builder.push('widget[{0}]'.format(indexer));
575
+ }
576
+ } else {
577
+ builder.push('text[{0}]'.format(text.push(response.html) - 1));
578
+ break;
579
+ }
580
+ }
581
+
582
+ response.js = response.js.length ? response.js.join('\n') : '';
583
+ response.css = response.css.length ? response.css.join('') : '';
584
+ response.toString = new Function('text', 'widget', 'tangular', 'body', 'return ' + builder.join('+'));
585
+ response.text = text;
586
+
587
+ delete response.html;
588
+ return response;
589
+ };
590
+
591
+ function CMSRender() {}
592
+
593
+ CMSRender.prototype.importmeta = function(val) {
594
+ var self = this;
595
+ for (var i = 0; i < self.text.length; i++) {
596
+ var item = self.text[i];
597
+ var index = item.indexOf('</head');
598
+ if (index !== -1) {
599
+ self.text[i] = item.substring(0, index) + val + item.substring(index);
600
+ return self;
601
+ }
602
+ }
603
+ return self;
604
+ };
605
+
606
+ CMSRender.prototype.importcss = function(val) {
607
+
608
+ var self = this;
609
+
610
+ if (val == null) {
611
+ if (self.css)
612
+ val = '<style>' + self.css + '</style>';
613
+ else
614
+ return self;
615
+ }
616
+
617
+ for (var i = 0; i < self.text.length; i++) {
618
+ var item = self.text[i];
619
+ var index = item.indexOf('</head');
620
+ if (index !== -1) {
621
+ self.text[i] = item.substring(0, index) + val + item.substring(index);
622
+ return self;
623
+ }
624
+ }
625
+
626
+ self.text[0] += val;
627
+ return self;
628
+ };
629
+
630
+ CMSRender.prototype.importjs = function(val) {
631
+ var self = this;
632
+
633
+ if (val == null) {
634
+ if (self.js)
635
+ val = '<script>' + self.js + '</script>';
636
+ else
637
+ return self;
638
+ }
639
+
640
+ for (var i = 0; i < self.text.length; i++) {
641
+ var item = self.text[i];
642
+ var index = item.indexOf('</body>');
643
+ if (index !== -1) {
644
+ self.text[i] = item.substring(0, index) + val + item.substring(index);
645
+ return self;
646
+ }
647
+ }
648
+
649
+ self.text[self.text.length - 1] += val;
650
+ return self;
651
+ };
652
+
653
+ CMSRender.prototype.render = function(meta, layout, callback) {
654
+ var self = this;
655
+ if (callback)
656
+ self._render(meta, layout, callback);
657
+ else
658
+ return new Promise((resolve, reject) => self._render(meta, layout, (err, res) => err ? reject(err) : resolve(res)));
659
+ };
660
+
661
+ CMSRender.prototype._render = function(meta, layout, callback) {
662
+
663
+ // meta.controller {Object}
664
+ // meta.url {String}
665
+ // meta.vars {Object}
666
+ // meta.refs {Object}
667
+ // meta.body {String} targeted for the layout
668
+ // meta.nav {Object Array}
669
+ // meta.breadcrumb {Object Array}
670
+ // meta.widgets {Object Array}
671
+
672
+ if (typeof(layout) === 'function') {
673
+ callback = layout;
674
+ layout = null;
675
+ }
676
+
677
+ var self = this;
678
+ var widgets = [];
679
+ var opt = {};
680
+
681
+ for (var key in meta) {
682
+ if (key !== 'widgets')
683
+ opt[key] = meta[key];
684
+ }
685
+
686
+ self.widgets.wait(function(item, next) {
687
+
688
+ opt.id = item.uid;
689
+ opt.widget = item.id;
690
+ opt.version = VERSION;
691
+ opt.config = item.config;
692
+ opt.body = item.body || '';
693
+ opt.html = item.html || '';
694
+ opt.template = item.template;
695
+ opt.cacheid = opt.id;
696
+
697
+ var render = item.render;
698
+ if (meta.widgets) {
699
+ var w = meta.widgets instanceof Array ? meta.widgets.findItem('id', item.id) : meta.widgets[item.id];
700
+ if (w) {
701
+ render = w.render;
702
+ if (w.cache === 'url' && opt.url)
703
+ opt.cacheid += '_' + HASH(opt.url).toString(36);
704
+ }
705
+ }
706
+
707
+ if (self.cache[opt.cacheid]) {
708
+ widgets[item.indexer] = self.cache[opt.cacheid];
709
+ next();
710
+ return;
711
+ }
712
+
713
+ render(opt, function(response, replace, cache) {
714
+ widgets[item.indexer] = replace === true ? (response == null || response == '' ? '' : (response + '').replace(/~(BEG|END)~/g, '')) : (item.beg + (response || '') + item.end);
715
+ if (cache)
716
+ self.cache[opt.cacheid] = widgets[item.indexer];
717
+ next();
718
+ });
719
+
720
+ }, function() {
721
+
722
+ var tangular = [];
723
+
724
+ // opt.inlinecache {Object} user defined cache
725
+
726
+ for (let i = 0; i < self.tangular.length; i++) {
727
+
728
+ let key = i + '';
729
+ let body = opt.inlinecache ? opt.inlinecache[key] : '';
730
+
731
+ if (!body) {
732
+ let item = self.tangular[i];
733
+ switch (item.type) {
734
+ case 'nav':
735
+ body = item.template({ value: opt.navigation ? opt.navigation(item.id) : null });
736
+ break;
737
+ case 'breadcrumb':
738
+ body = item.template({ value: opt.breadcrumb || EMPTYARRAY });
739
+ break;
740
+ }
741
+
742
+ if (opt.inlinecache) {
743
+ body = body.replace(/\t|\s{2,}/g, '');
744
+ opt.inlinecache[key] = body;
745
+ }
746
+ }
747
+
748
+ tangular.push(body);
749
+ }
750
+
751
+ var html = self.toString(self.text, widgets, tangular, meta.body || '');
752
+ if (layout) {
753
+ meta.body = html;
754
+ layout.render(meta, callback);
755
+ } else
756
+ callback.call(self, null, html, self);
757
+ });
758
+
759
+ };