owl-cli 7.12.0 → 7.14.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 (37) hide show
  1. package/examples/models/owlsys/systemAdmin/app_fields.json +48 -0
  2. package/examples/models/owlsys/systemAdmin/app_plugins.json +44 -0
  3. package/examples/models/owlsys/systemAdmin/app_sections.json +64 -0
  4. package/examples/models/owlsys/systemAdmin/apps/api/src/plugins/refresh_apps.jsx +663 -0
  5. package/examples/models/owlsys/systemAdmin/apps.json +101 -0
  6. package/examples/models/owlsys/systemAdmin/backendSession.json +52 -0
  7. package/examples/models/owlsys/systemAdmin/batchImport.json +54 -0
  8. package/examples/models/owlsys/systemAdmin/batch_import/api/src/plugins/addImport.jsx +75 -0
  9. package/examples/models/owlsys/systemAdmin/batch_import/api/src/tasks/doImportTask.jsx +130 -0
  10. package/examples/models/owlsys/systemAdmin/change_log.json +70 -0
  11. package/examples/models/owlsys/systemAdmin/change_logs/api/src/services/modelService.jsx +1096 -0
  12. package/examples/models/owlsys/systemAdmin/common_views/api/src/views/product_basic_info_default.jsx +280 -0
  13. package/examples/models/owlsys/systemAdmin/common_views/api/src/views/product_basic_info_edit.jsx +380 -0
  14. package/examples/models/owlsys/systemAdmin/common_views.json +32 -0
  15. package/examples/models/owlsys/systemAdmin/download_template.json +45 -0
  16. package/examples/models/owlsys/systemAdmin/error_logs/dispatch_order_errors.json +61 -0
  17. package/examples/models/owlsys/systemAdmin/excel_templates.json +60 -0
  18. package/examples/models/owlsys/systemAdmin/frontendSession.json +44 -0
  19. package/examples/models/owlsys/systemAdmin/obj_permission.json +66 -0
  20. package/examples/models/owlsys/systemAdmin/org_setting.json +188 -0
  21. package/examples/models/owlsys/systemAdmin/param.json +29 -0
  22. package/examples/models/owlsys/systemAdmin/process_job.json +94 -0
  23. package/examples/models/owlsys/systemAdmin/process_job_checklog.json +66 -0
  24. package/examples/models/owlsys/systemAdmin/process_job_log.json +34 -0
  25. package/examples/models/owlsys/systemAdmin/roleOptions.json +36 -0
  26. package/examples/models/owlsys/systemAdmin/sensitive_keywords.json +58 -0
  27. package/examples/models/owlsys/systemAdmin/server_token.json +38 -0
  28. package/examples/models/owlsys/systemAdmin/session.json +51 -0
  29. package/examples/models/owlsys/systemAdmin/task_version.json +60 -0
  30. package/examples/models/owlsys/systemAdmin/taskinfo.json +38 -0
  31. package/examples/models/owlsys/systemAdmin/tasks/api/src/plugins/doRunTask.jsx +32 -0
  32. package/examples/models/owlsys/systemAdmin/tasks.json +43 -0
  33. package/examples/owlsysApps/owlPasswordService/build.xml +4 -3
  34. package/package.json +1 -1
  35. /package/examples/models/owlsys/{permissions → systemAdmin}/permission.json +0 -0
  36. /package/examples/models/owlsys/{permissions → systemAdmin}/roles.json +0 -0
  37. /package/examples/models/owlsys/{permissions → systemAdmin}/tablelevelpermission.json +0 -0
@@ -0,0 +1,663 @@
1
+ //#import app.js
2
+ //#import $owl_apps:services/modelService.jsx
3
+ //#import $owl_app_sections:services/modelService.jsx
4
+ //#import $owl_app_fields:services/modelService.jsx
5
+ //#import $owl_app_plugins:services/modelService.jsx
6
+ //#import Util.js
7
+
8
+ function parseFieldType(fieldType) {
9
+ if (fieldType.indexOf('string') >= 0 || fieldType.indexOf('number') >= 0) {
10
+ var idx = fieldType.indexOf('(')
11
+ var idx1 = fieldType.indexOf(')')
12
+ var sNum = fieldType.substring(idx + 1, idx1)
13
+ var fieldSize = parseInt(sNum)
14
+ if (fieldType.indexOf('string') >= 0) {
15
+ var t = 'string'
16
+ } else {
17
+ var t = 'number'
18
+ }
19
+ return {
20
+ fieldType: t,
21
+ fieldSize: fieldSize,
22
+ }
23
+ } else {
24
+ return {
25
+ fieldType: fieldType,
26
+ }
27
+ }
28
+ }
29
+
30
+
31
+ function parseFieldAttrs(fieldAttrs) {
32
+ var attrs = fieldAttrs.split(',')
33
+ var fieldType = attrs[0]
34
+ var attrObj = parseFieldType(fieldType)
35
+ for (var i = 1; i < attrs.length; i++) {
36
+ var attr = attrs[i]
37
+ var pair = attr.split(':')
38
+ if (pair.length == 2) {
39
+ attrObj[pair[0].trim()] = pair[1].trim()
40
+ } else {
41
+ attrObj[pair[0].trim()] = 'false'
42
+ }
43
+ }
44
+
45
+ if (attrObj.fieldType == 'choice') {
46
+ var values = attrObj.values
47
+ var va = values.split('/')
48
+ var options = va.map((v) => v.split('_'))
49
+ attrObj.options = options
50
+ }
51
+ return attrObj
52
+ }
53
+
54
+ function parseSpec(specString) {
55
+ var parts = specString.split(';')
56
+ var fieldLabel = ''
57
+ if (parts.length >= 2) {
58
+ fieldLabel = parts[1]
59
+ var specObj = parseFieldAttrs(parts[0])
60
+ specObj['fieldLabel'] = fieldLabel
61
+
62
+ /*if(specObj["defaultValue"]){
63
+ let v = specObj["defaultValue"];
64
+ v = getEnvValue(v);
65
+ specObj.defaultValue = v;
66
+ }*/
67
+ return specObj
68
+ }
69
+ return null
70
+ }
71
+
72
+ function getFields(subForm, sectionKey, appId) {
73
+ if (!subForm) {
74
+ return [];
75
+ }
76
+ var fields = [];
77
+ var meta = subForm["#meta"];
78
+ if(!meta){
79
+ meta = {};
80
+ }
81
+ var includeKey = meta.includeKey;
82
+ $.log("meta.includeKey=" + includeKey + ",sectionKey=" + sectionKey);
83
+ if (!includeKey) {
84
+ includeKey = 'yes';
85
+ }
86
+ for (var key in subForm) {
87
+
88
+ if (key === '#meta') {
89
+ continue;
90
+ }
91
+ if (key === '_t') {
92
+ continue;
93
+ }
94
+ if (key === '') {
95
+ continue;
96
+ }
97
+ v = subForm[key];
98
+ if (typeof v === 'object') {
99
+ if (Array.isArray(v)) {
100
+ var subFields = getFields(v[0], key, appId);
101
+ if (subFields) {
102
+ subFields.forEach(function (f) {
103
+ fields.push(f);
104
+ })
105
+ }
106
+ } else {
107
+ var subFields = getFields(v, key, appId);
108
+ if (subFields) {
109
+ subFields.forEach(function (f) {
110
+ fields.push(f);
111
+ })
112
+ }
113
+ }
114
+ } else if (typeof v === 'string') {
115
+ var f = parseSpec(v);
116
+ if (f) {
117
+ f.fieldKey = key;
118
+ f.origKey = key;
119
+ f.sectionKey = sectionKey;
120
+ f.tableId = appId;
121
+ f.includeKey = includeKey
122
+ fields.push(f);
123
+ } else {
124
+ }
125
+
126
+ }
127
+ }
128
+ return fields;
129
+
130
+ }
131
+
132
+ function getPlugins(specObj, tableId, tableName) {
133
+ var meta = specObj["#meta"];
134
+ if (!meta) {
135
+ return [];
136
+ }
137
+
138
+ var plugins = meta.formPlugins;
139
+ if (!plugins) {
140
+ return [];
141
+ }
142
+ return plugins.map(function (plugin) {
143
+ return {
144
+ tableId: tableId,
145
+ tableName: tableName,
146
+ label: plugin.label,
147
+ action: plugin.action,
148
+ pluginId: plugin.id || plugin.action,
149
+ position: plugin.position,
150
+ help: plugin.help
151
+ }
152
+ });
153
+ }
154
+
155
+ function getOldPlugins(appId) {
156
+ var searchArgs = {
157
+ tableId: appId
158
+ }
159
+ var sr = owl_app_pluginsService.search(null, searchArgs, null, 0, 10000, null);
160
+ if (sr.state === 'ok') {
161
+ return sr.list;
162
+ }
163
+ return [];
164
+
165
+ }
166
+
167
+ function getSections(specObj, appId) {
168
+
169
+ var sections = [];
170
+
171
+ for (var key in specObj) {
172
+ if (key === '#meta') {
173
+ continue;
174
+ }
175
+ var field = specObj[key];
176
+ if (typeof field === 'string') {
177
+ continue;
178
+ } else if (Array.isArray(field)) {
179
+ var meta = field[0]["#meta"]
180
+ if (!meta) {
181
+ continue;
182
+ }
183
+ var section = meta;
184
+ section.sectionKey = key;
185
+ section.isArray = 'true';
186
+ section.tableId = appId;
187
+ sections.push(section);
188
+ } else if (typeof field === 'object') {
189
+ var meta = field["#meta"];
190
+ if (!meta) {
191
+ continue;
192
+ }
193
+ var section = meta;
194
+ section.sectionKey = key;
195
+ section.isArray = 'false';
196
+ section.tableId = appId;
197
+ sections.push(section);
198
+
199
+ }
200
+ }
201
+ return sections;
202
+ }
203
+
204
+ function getOldSections(appId) {
205
+ var searchArgs = {
206
+ tableId: appId
207
+ }
208
+
209
+ var sr = owl_app_sectionsService.search("0", searchArgs, null, 0, 10000, null);
210
+ if (sr.state === 'ok') {
211
+ return sr.list;
212
+ }
213
+ return [];
214
+ }
215
+
216
+ function getOldFields(appId) {
217
+ var searchArgs = {
218
+ tableId: appId
219
+ }
220
+ var sr = owl_app_fieldsService.search(null, searchArgs, null, 0, 10000, null);
221
+ if (sr.state === 'ok') {
222
+ return sr.list;
223
+ }
224
+ return [];
225
+
226
+ }
227
+
228
+
229
+ function addNewSections(added) {
230
+ for (var i = 0; i < added.length; i++) {
231
+ var s = added[i];
232
+ if(s){
233
+ owl_app_sectionsService.add(s);
234
+ }
235
+
236
+ }
237
+ }
238
+
239
+ function addNewFields(added) {
240
+ for (var i = 0; i < added.length; i++) {
241
+ var f = added[i];
242
+ if(f){
243
+ owl_app_fieldsService.add(f);
244
+ }
245
+
246
+ }
247
+ }
248
+
249
+ function removeDeletedSections(deleted) {
250
+ for (var i = 0; i < deleted.length; i++) {
251
+ var d = deleted[i];
252
+ if(d){
253
+ owl_app_sectionsService.del(d.id);
254
+ }
255
+
256
+ }
257
+ }
258
+
259
+ function removeDeletedFields(deleted) {
260
+ for (var i = 0; i < deleted.length; i++) {
261
+ var d = deleted[i];
262
+ if(d){
263
+ owl_app_fieldsService.del(d.id);
264
+ }
265
+
266
+ }
267
+ }
268
+
269
+ function updateSections(oldSections, sections) {
270
+ for (var i = 0; i < oldSections.length; i++) {
271
+ var o = oldSections[i];
272
+ for (var j = 0; j < sections.length; j++) {
273
+ var n = sections[j];
274
+ if (n.sectionKey == o.sectionKey) {
275
+ var oo = owl_app_sectionsService.get(o.id);
276
+ Object.assign(oo, n);
277
+ owl_app_sectionsService.update(oo);
278
+ }
279
+ }
280
+ }
281
+ }
282
+
283
+ function isScalar(o) {
284
+ if (o === null) {
285
+ return false;
286
+ }
287
+ return typeof o === 'string';
288
+ }
289
+
290
+
291
+ function isEqual(r1, r2) {
292
+ var ignoreKeys = ['_type', '_matched', '_v', "owl_createTime", "owl_modifyTime", "_t", "id", "_m"];
293
+ if (r1 == null && r2 == null) {
294
+ return true;
295
+ }
296
+ if (r1 == null || r2 == null) {
297
+ return false;
298
+ }
299
+ if (isScalar(r1) || isScalar(r2)) {
300
+ return r1 === r2;
301
+ }
302
+ //now assert a1!=null && r2!=null
303
+ var ks1 = Object.keys(r1);
304
+ var ks2 = Object.keys(r2);
305
+
306
+ ks1 = ks1.filter(function (k) {
307
+ return ignoreKeys.indexOf(k) === -1;
308
+ });
309
+
310
+ ks2 = ks2.filter(function (k) {
311
+ return ignoreKeys.indexOf(k) === -1;
312
+ });
313
+
314
+ if (ks1.length !== ks2.length) {
315
+ $.log("ks1.length!==ks2.length,ks1=" + JSON.stringify(ks1) + ",ks2=" + JSON.stringify(ks2));
316
+ return false;
317
+ }
318
+ for (var i = 0; i < ks1.length; i++) {
319
+ var k = ks1[i];
320
+ if (Array.isArray(r1[k])) {
321
+ 0.
322
+ if (r1[k].length !== r2[k].length) {
323
+ return false;
324
+ }
325
+ if (JSON.stringify(r1[k]) !== JSON.stringify(r2[k])) {
326
+ $.log("r1!=r2,r1=" + JSON.stringify(r1[k]) + ",r2=" + JSON.stringify(r2[k]));
327
+ return false;
328
+ }
329
+
330
+ } else {
331
+ if (r1[k] !== r2[k]) {
332
+ $.log("r1!=r2,r1=" + JSON.stringify(r1[k]) + ",r2=" + JSON.stringify(r2[k]));
333
+ return false;
334
+ }
335
+ }
336
+ }
337
+ return true;
338
+
339
+ }
340
+
341
+ function getDeletedPlugins(plugins, oldPlugins) {
342
+ var deleted = [];
343
+ for (var i = 0; i < oldPlugins.length; i++) {
344
+ var old = oldPlugins[i];
345
+ var found = false;
346
+ for (var j = 0; j < plugins.length; j++) {
347
+ var s = plugins[j];
348
+ if (s.label === old.label &&
349
+ s.action === old.action &&
350
+ s.pluginId === old.pluginId &&
351
+ s.position === old.position &&
352
+ s.tableId === old.tableId &&
353
+ s.tableName === old.tableName &&
354
+ s.help === old.help) {
355
+ found = true;
356
+ }
357
+
358
+ }
359
+ if (!found) {
360
+ deleted.push(old);
361
+ }
362
+ }
363
+ return deleted;
364
+ }
365
+
366
+ function getNewPlugins(plugins, oldPlugins) {
367
+ var newPlugins = [];
368
+ for (var i = 0; i < plugins.length; i++) {
369
+ var plugin = plugins[i];
370
+ var found = false;
371
+ for (var j = 0; j < oldPlugins.length; j++) {
372
+ var old = oldPlugins[j];
373
+ if (plugin.label === old.label &&
374
+ plugin.action === old.action &&
375
+ plugin.pluginId === old.pluginId &&
376
+ plugin.position === old.position &&
377
+ plugin.tableId === old.tableId &&
378
+ plugin.tableName === old.tableName &&
379
+ plugin.help === old.help) {
380
+ found = true;
381
+ }
382
+
383
+ }
384
+ if (!found) {
385
+ newPlugins.push(plugin);
386
+ }
387
+ }
388
+ return newPlugins;
389
+ }
390
+
391
+ function removeDeletedPlugins(deleted) {
392
+ if (!deleted) {
393
+ return;
394
+ }
395
+ for (var i = 0; i < deleted.length; i++) {
396
+ var d = deleted[i];
397
+ owl_app_pluginsService.del(d.id);
398
+ }
399
+ }
400
+
401
+ function addNewPlugins(newPlugins) {
402
+ if (!newPlugins) {
403
+ return;
404
+ }
405
+ for (var i = 0; i < newPlugins.length; i++) {
406
+ var s = newPlugins[i];
407
+ try{
408
+ if(s){
409
+ owl_app_pluginsService.add(s);
410
+ }
411
+
412
+ }
413
+ catch(e){
414
+ $.log("error add plugin:" + JSON.stringify(s) + ",e=" + e);
415
+ }
416
+
417
+ }
418
+
419
+ }
420
+
421
+
422
+ function updateFields(oldFields, fields) {
423
+ var ignoreKeys = ['_type', '_matched', '_v', "owl_createTime", "owl_modifyTime", "_t", "id"];
424
+ for (var i = 0; i < oldFields.length; i++) {
425
+ var o = oldFields[i];
426
+ for (var j = 0; j < fields.length; j++) {
427
+ var n = fields[j];
428
+ if (n.sectionKey === o.sectionKey && n.fieldKey === o.fieldKey) {
429
+ var oo = owl_app_fieldsService.get(o.id);
430
+ if(!oo){
431
+ $.log("old obj = null")
432
+ oo = {};
433
+ }
434
+ if (!isEqual(oo, n)) {
435
+ // $.log("update field......new=" + JSON.stringify(n) + ", old=" + JSON.stringify(oo) + ",o=" + JSON.stringify(o));
436
+ Object.assign(oo, n);
437
+ for (var okey in oo) {
438
+ if (ignoreKeys.indexOf(okey) === -1) {
439
+ if (!n[okey]) {
440
+ $.log("delete " + okey)
441
+ delete oo[okey];
442
+ }
443
+ }
444
+ }
445
+ // $.log("update:" + JSON.stringify(oo));
446
+ try {
447
+ owl_app_fieldsService.update(oo);
448
+ } catch (e) {
449
+ owl_app_fieldsService.del(o.id);
450
+ owl_app_fieldsService.add(oo);
451
+ }
452
+
453
+
454
+ }
455
+
456
+ }
457
+ }
458
+ }
459
+ }
460
+
461
+ function getDeletedSections(sections, oldSections) {
462
+ //在老sections但是不再新sections里面的数据,就是被删除的
463
+ var deleted = [];
464
+ for (var i = 0; i < oldSections.length; i++) {
465
+ var old = oldSections[i];
466
+ var found = false;
467
+ for (var j = 0; j < sections.length; j++) {
468
+ var s = sections[j];
469
+ if (s.sectionKey === old.sectionKey) {
470
+ found = true;
471
+ }
472
+ }
473
+ if (!found) {
474
+ deleted.push(old);
475
+ }
476
+ }
477
+ return deleted;
478
+ }
479
+
480
+ function getDeletedFields(fields, oldFields) {
481
+ //在老sections但是不再新sections里面的数据,就是被删除的
482
+ var deleted = [];
483
+ for (var i = 0; i < oldFields.length; i++) {
484
+ var old = oldFields[i];
485
+ var found = false;
486
+ for (var j = 0; j < fields.length; j++) {
487
+ var f = fields[j];
488
+ if (f.sectionKey === f.sectionKey && f.fieldKey === old.fieldKey) {
489
+ found = true;
490
+ }
491
+ }
492
+ if (!found) {
493
+ deleted.push(old);
494
+ }
495
+ }
496
+ return deleted;
497
+ }
498
+
499
+ function getAddedSections(sections, oldSections) {
500
+ var added = [];
501
+ for (var i = 0; i < sections.length; i++) {
502
+ var s = sections[i];
503
+ var found = false;
504
+ for (var j = 0; j < oldSections.length; j++) {
505
+ var old = oldSections[j];
506
+ if (s.sectionKey === old.sectionKey) {
507
+ found = true;
508
+ }
509
+ }
510
+ if (!found) {
511
+ added.push(s);
512
+ }
513
+ }
514
+ return added;
515
+ }
516
+
517
+
518
+ function getAddedFields(fields, oldFields) {
519
+ var added = [];
520
+ for (var i = 0; i < fields.length; i++) {
521
+ var s = fields[i];
522
+ var found = false;
523
+ for (var j = 0; j < oldFields.length; j++) {
524
+ var old = oldFields[j];
525
+ if (s.sectionKey === old.sectionKey && s.fieldKey === old.fieldKey) {
526
+ found = true;
527
+ }
528
+ }
529
+ if (!found) {
530
+ added.push(s);
531
+ }
532
+ }
533
+ return added;
534
+ }
535
+
536
+ function main() {
537
+ var allapps = AppService.getIndependentApps('head_merchant', 0, -1);
538
+ for (var i = 0; i < allapps.length; i++) {
539
+ var app = allapps[i];
540
+ var appId = app.id;
541
+ var name = null;
542
+ var isWidget = null;
543
+ var isHide = null;
544
+ var project = null;
545
+ var group = null;
546
+ var groupId = null;
547
+ var groupName = null;
548
+ var pos = null;
549
+ // try {
550
+ var meta = AppService.getAppMeta(app.id);
551
+ if (meta) {
552
+ var subMeta = meta["#meta"];
553
+ isWidget = meta.isWidget ? 'yes' : 'no';
554
+ if (subMeta) {
555
+ isHide = subMeta.hide == 'true' ? 'yes' : 'no';
556
+ project = subMeta.project;
557
+ group = subMeta.group;
558
+ pos = subMeta.pos;
559
+ name = subMeta.rem;
560
+ }
561
+ }
562
+
563
+ var app = {
564
+ tableId: appId,
565
+ name: name,
566
+ isWidget: isWidget,
567
+ isHide: isHide,
568
+ project: project,
569
+ pos: pos
570
+ }
571
+
572
+ if (group) {
573
+ if (typeof group == 'string') {
574
+ app.groupId = group;
575
+ app.groupName = group;
576
+ } else {
577
+ app.groupId = group.id;
578
+ app.groupName = group.name;
579
+ app.groupPos = group.pos;
580
+ }
581
+
582
+ }
583
+ var id = "owl_apps_" + appId;
584
+ var owlapp = owl_appsService.get(id);
585
+ if (owlapp) {
586
+ if (owlapp.name != app.name
587
+ || owlapp.isWidget != app.isWidget
588
+ || owlapp.isHide != app.isHide ||
589
+ owlapp.project != app.project ||
590
+ owlapp.pos != app.pos ||
591
+ owlapp.groupId != app.groupId ||
592
+ owlapp.groupName != app.groupName
593
+ || owlapp.groupPos != app.groupPos) {
594
+ Object.assign(owlapp, app);
595
+ owl_appsService.update(owlapp);
596
+ }
597
+
598
+ } else {
599
+ owl_appsService.add(app);
600
+ }
601
+
602
+ var spec = $.getAppProgram(appId, "spec.json");
603
+ if (!spec) {
604
+ continue;
605
+ }
606
+ var specObj = JSON.parse(spec);
607
+
608
+
609
+ var sections = getSections(specObj, appId);
610
+
611
+
612
+ //找到需要删除的
613
+ var oldSections = getOldSections(appId);
614
+ var deleted = getDeletedSections(sections, oldSections);
615
+ var added = getAddedSections(sections, oldSections);
616
+
617
+ // $.log("appId=" + appId + ",sections.length=" + sections.length + ", added.length=" + added.length + ",deleted.length=" + deleted.length);
618
+ // $.log("appId=" + appId + ",oldSections.length=" + oldSections.length);
619
+
620
+ removeDeletedSections(deleted);
621
+
622
+ //添加
623
+ addNewSections(added);
624
+
625
+
626
+ // 更新
627
+ updateSections(oldSections, sections);
628
+
629
+
630
+ var fields = getFields(specObj, 'main', appId);
631
+ var oldFields = getOldFields(appId);
632
+ var deletedFields = getDeletedFields(fields, oldFields);
633
+ var addedFields = getAddedFields(fields, oldFields);
634
+ removeDeletedFields(deletedFields);
635
+ addNewFields(addedFields);
636
+ updateFields(oldFields, fields);
637
+
638
+
639
+ //plugins
640
+
641
+ var plugins = getPlugins(specObj, appId, app.name);
642
+ var oldPlugins = getOldPlugins(appId);
643
+ var newPlugins = getNewPlugins(plugins, oldPlugins);
644
+ var deletedPlugins = getDeletedPlugins(plugins, oldPlugins);
645
+
646
+ removeDeletedPlugins(deletedPlugins);
647
+ addNewPlugins(newPlugins);
648
+
649
+
650
+
651
+
652
+ }
653
+
654
+ var ret = {
655
+ state: "ok",
656
+ msg: "更新成功"
657
+ }
658
+ out.print(JSON.stringify(ret));
659
+
660
+
661
+ }
662
+
663
+ main();