grat 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ #!/bin/sh
2
+
3
+ DESTINATION=opera_userscript.js
4
+
5
+ echo '// ==UserScript==
6
+ // @name Scripts beautifier for Opera
7
+ // @author Rafal Chlodnicki
8
+ // @version 1.0
9
+ // @JSBeautifierversion 16 May 2009
10
+ // @include *
11
+ // ==/UserScript==
12
+
13
+ (function(){
14
+
15
+ var beautify =
16
+ ' > $DESTINATION
17
+ cat ../beautify.js >> $DESTINATION
18
+
19
+ echo '
20
+ var toString = Function.prototype.toString;
21
+ Function.prototype.tidy = function(){ return beautify( toString.call(this) ) };
22
+ String.prototype.tidy = function(){ return beautify(this); };
23
+
24
+ // tidy scripts if special window property set
25
+ if ( window.tidyScripts )
26
+ {
27
+ opera.addEventListener('BeforeScript', tidyScript, false);
28
+ function tidyScript(ev)
29
+ {
30
+ ev.element.text = Function.prototype.tidy.call(ev.element.text);
31
+ }
32
+ }
33
+
34
+ })();
35
+ ' >> $DESTINATION
@@ -0,0 +1,711 @@
1
+ // ==UserScript==
2
+ // @name Scripts beautifier for Opera
3
+ // @author Rafal Chlodnicki
4
+ // @version 1.0
5
+ // @JSBeautifierversion 16 May 2009
6
+ // @include *
7
+ // ==/UserScript==
8
+
9
+ (function(){
10
+
11
+ var beautify =
12
+
13
+ /*
14
+
15
+ JS Beautifier
16
+ ---------------
17
+
18
+
19
+ Written by Einar Lielmanis, <einars@gmail.com>
20
+ http://jsbeautifier.org/
21
+
22
+ Originally converted to javascript by Vital, <vital76@gmail.com>
23
+
24
+ You are free to use this in any way you want, in case you find this useful or working for you.
25
+
26
+ Usage:
27
+ js_beautify(js_source_text);
28
+ js_beautify(js_source_text, options);
29
+
30
+ The options are:
31
+ indent_size (default 4) — indentation size,
32
+ indent_char (default space) — character to indent with,
33
+ preserve_newlines (default true) — whether existing line breaks should be preserved,
34
+ indent_level (default 0) — initial indentation level, you probably won't need this ever,
35
+
36
+ e.g
37
+
38
+ js_beautify(js_source_text, {indent_size: 1, indent_char: '\t'});
39
+
40
+
41
+ */
42
+
43
+
44
+
45
+ function js_beautify(js_source_text, options)
46
+ {
47
+
48
+ var input, output, token_text, last_type, last_text, last_word, current_mode, modes, indent_string;
49
+ var whitespace, wordchar, punct, parser_pos, line_starters, in_case, digits;
50
+ var prefix, token_type, do_block_just_closed, var_line, var_line_tainted, if_line_flag;
51
+ var indent_level;
52
+
53
+
54
+ var options = options || {};
55
+ var opt_indent_size = options['indent_size'] || 4;
56
+ var opt_indent_char = options['indent_char'] || ' ';
57
+ var opt_preserve_newlines =
58
+ typeof options['preserve_newlines'] === 'undefined' ? true : options['preserve_newlines'];
59
+ var opt_indent_level = options['indent_level'] || 0; // starting indentation
60
+
61
+
62
+ function trim_output()
63
+ {
64
+ while (output.length && (output[output.length - 1] === ' ' || output[output.length - 1] === indent_string)) {
65
+ output.pop();
66
+ }
67
+ }
68
+
69
+ function print_newline(ignore_repeated)
70
+ {
71
+
72
+ ignore_repeated = typeof ignore_repeated === 'undefined' ? true: ignore_repeated;
73
+
74
+ if_line_flag = false;
75
+ trim_output();
76
+
77
+ if (!output.length) {
78
+ return; // no newline on start of file
79
+ }
80
+
81
+ if (output[output.length - 1] !== "\n" || !ignore_repeated) {
82
+ output.push("\n");
83
+ }
84
+ for (var i = 0; i < indent_level; i++) {
85
+ output.push(indent_string);
86
+ }
87
+ }
88
+
89
+
90
+
91
+ function print_space()
92
+ {
93
+ var last_output = ' ';
94
+ if (output.length) {
95
+ last_output = output[output.length - 1]
96
+ }
97
+ if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string) { // prevent occassional duplicate space
98
+ output.push(' ');
99
+ }
100
+ }
101
+
102
+
103
+ function print_token()
104
+ {
105
+ output.push(token_text);
106
+ }
107
+
108
+ function indent()
109
+ {
110
+ indent_level++;
111
+ }
112
+
113
+
114
+ function unindent()
115
+ {
116
+ if (indent_level) {
117
+ indent_level--;
118
+ }
119
+ }
120
+
121
+
122
+ function remove_indent()
123
+ {
124
+ if (output.length && output[output.length - 1] === indent_string) {
125
+ output.pop();
126
+ }
127
+ }
128
+
129
+
130
+ function set_mode(mode)
131
+ {
132
+ modes.push(current_mode);
133
+ current_mode = mode;
134
+ }
135
+
136
+
137
+ function restore_mode()
138
+ {
139
+ do_block_just_closed = current_mode === 'DO_BLOCK';
140
+ current_mode = modes.pop();
141
+ }
142
+
143
+
144
+ function in_array(what, arr)
145
+ {
146
+ for (var i = 0; i < arr.length; i++)
147
+ {
148
+ if (arr[i] === what) {
149
+ return true;
150
+ }
151
+ }
152
+ return false;
153
+ }
154
+
155
+
156
+
157
+ function get_next_token()
158
+ {
159
+ var n_newlines = 0;
160
+
161
+ if (parser_pos >= input.length) {
162
+ return ['', 'TK_EOF'];
163
+ }
164
+
165
+ var c = input.charAt(parser_pos);
166
+ parser_pos += 1;
167
+
168
+ while (in_array(c, whitespace)) {
169
+ if (parser_pos >= input.length) {
170
+ return ['', 'TK_EOF'];
171
+ }
172
+
173
+ if (c === "\n") {
174
+ n_newlines += 1;
175
+ }
176
+
177
+ c = input.charAt(parser_pos);
178
+ parser_pos += 1;
179
+
180
+ }
181
+
182
+ var wanted_newline = false;
183
+
184
+ if (opt_preserve_newlines) {
185
+ if (n_newlines > 1) {
186
+ for (var i = 0; i < 2; i++) {
187
+ print_newline(i === 0);
188
+ }
189
+ }
190
+ wanted_newline = (n_newlines === 1);
191
+ }
192
+
193
+
194
+ if (in_array(c, wordchar)) {
195
+ if (parser_pos < input.length) {
196
+ while (in_array(input.charAt(parser_pos), wordchar)) {
197
+ c += input.charAt(parser_pos);
198
+ parser_pos += 1;
199
+ if (parser_pos === input.length) {
200
+ break;
201
+ }
202
+ }
203
+ }
204
+
205
+ // small and surprisingly unugly hack for 1E-10 representation
206
+ if (parser_pos !== input.length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+')) {
207
+
208
+ var sign = input.charAt(parser_pos);
209
+ parser_pos += 1;
210
+
211
+ var t = get_next_token(parser_pos);
212
+ c += sign + t[0];
213
+ return [c, 'TK_WORD'];
214
+ }
215
+
216
+ if (c === 'in') { // hack for 'in' operator
217
+ return [c, 'TK_OPERATOR'];
218
+ }
219
+ if (wanted_newline && last_type !== 'TK_OPERATOR' && !if_line_flag) {
220
+ print_newline();
221
+ }
222
+ return [c, 'TK_WORD'];
223
+ }
224
+
225
+ if (c === '(' || c === '[') {
226
+ return [c, 'TK_START_EXPR'];
227
+ }
228
+
229
+ if (c === ')' || c === ']') {
230
+ return [c, 'TK_END_EXPR'];
231
+ }
232
+
233
+ if (c === '{') {
234
+ return [c, 'TK_START_BLOCK'];
235
+ }
236
+
237
+ if (c === '}') {
238
+ return [c, 'TK_END_BLOCK'];
239
+ }
240
+
241
+ if (c === ';') {
242
+ return [c, 'TK_SEMICOLON'];
243
+ }
244
+
245
+ if (c === '/') {
246
+ var comment = '';
247
+ // peek for comment /* ... */
248
+ if (input.charAt(parser_pos) === '*') {
249
+ parser_pos += 1;
250
+ if (parser_pos < input.length) {
251
+ while (! (input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') && parser_pos < input.length) {
252
+ comment += input.charAt(parser_pos);
253
+ parser_pos += 1;
254
+ if (parser_pos >= input.length) {
255
+ break;
256
+ }
257
+ }
258
+ }
259
+ parser_pos += 2;
260
+ return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT'];
261
+ }
262
+ // peek for comment // ...
263
+ if (input.charAt(parser_pos) === '/') {
264
+ comment = c;
265
+ while (input.charAt(parser_pos) !== "\x0d" && input.charAt(parser_pos) !== "\x0a") {
266
+ comment += input.charAt(parser_pos);
267
+ parser_pos += 1;
268
+ if (parser_pos >= input.length) {
269
+ break;
270
+ }
271
+ }
272
+ parser_pos += 1;
273
+ if (wanted_newline) {
274
+ print_newline();
275
+ }
276
+ return [comment, 'TK_COMMENT'];
277
+ }
278
+
279
+ }
280
+
281
+ if (c === "'" || // string
282
+ c === '"' || // string
283
+ (c === '/' &&
284
+ ((last_type === 'TK_WORD' && last_text === 'return') || (last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON')))) { // regexp
285
+ var sep = c;
286
+ var esc = false;
287
+ var resulting_string = c;
288
+
289
+ if (parser_pos < input.length) {
290
+
291
+ while (esc || input.charAt(parser_pos) !== sep) {
292
+ resulting_string += input.charAt(parser_pos);
293
+ if (!esc) {
294
+ esc = input.charAt(parser_pos) === '\\';
295
+ } else {
296
+ esc = false;
297
+ }
298
+ parser_pos += 1;
299
+ if (parser_pos >= input.length) {
300
+ // incomplete string/rexp when end-of-file reached.
301
+ // bail out with what had been received so far.
302
+ return [resulting_string, 'TK_STRING']
303
+ }
304
+ }
305
+
306
+ }
307
+
308
+ parser_pos += 1;
309
+
310
+ resulting_string += sep;
311
+
312
+ if (sep == '/') {
313
+ // regexps may have modifiers /regexp/MOD , so fetch those, too
314
+ while (parser_pos < input.length && in_array(input.charAt(parser_pos), wordchar)) {
315
+ resulting_string += input.charAt(parser_pos);
316
+ parser_pos += 1;
317
+ }
318
+ }
319
+ return [resulting_string, 'TK_STRING'];
320
+ }
321
+
322
+ if (c == '#') {
323
+ // Spidermonkey-specific sharp variables for circular references
324
+ // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
325
+ // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
326
+ var sharp = '#';
327
+ if (parser_pos < input.length && in_array(input.charAt(parser_pos), digits)) {
328
+ do {
329
+ c = input.charAt(parser_pos);
330
+ sharp += c;
331
+ parser_pos += 1;
332
+ } while (parser_pos < input.length && c != '#' && c != '=');
333
+ if (c === '#') {
334
+ return [sharp, 'TK_WORD'];
335
+ } else {
336
+ return [sharp, 'TK_OPERATOR'];
337
+ }
338
+ }
339
+ }
340
+
341
+ if (c == '<' && input.substring(0, 4) === '<!--') {
342
+ parser_pos += 3;
343
+ return ['<!--', 'TK_COMMENT'];
344
+ }
345
+
346
+ if (in_array(c, punct)) {
347
+ while (parser_pos < input.length && in_array(c + input.charAt(parser_pos), punct)) {
348
+ c += input.charAt(parser_pos);
349
+ parser_pos += 1;
350
+ if (parser_pos >= input.length) {
351
+ break;
352
+ }
353
+ }
354
+
355
+ return [c, 'TK_OPERATOR'];
356
+ }
357
+
358
+ return [c, 'TK_UNKNOWN'];
359
+ }
360
+
361
+
362
+ //----------------------------------
363
+
364
+ indent_string = '';
365
+ while (opt_indent_size--) {
366
+ indent_string += opt_indent_char;
367
+ }
368
+
369
+ indent_level = opt_indent_level;
370
+
371
+ input = js_source_text;
372
+
373
+ last_word = ''; // last 'TK_WORD' passed
374
+ last_type = 'TK_START_EXPR'; // last token type
375
+ last_text = ''; // last token text
376
+ output = [];
377
+
378
+ do_block_just_closed = false;
379
+ var_line = false; // currently drawing var .... ;
380
+ var_line_tainted = false; // false: var a = 5; true: var a = 5, b = 6
381
+
382
+ whitespace = "\n\r\t ".split('');
383
+ wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');
384
+ digits = '0123456789'.split('');
385
+
386
+ // <!-- is a special case (ok, it's a minor hack actually)
387
+ punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::'.split(' ');
388
+
389
+ // words which should always start on new line.
390
+ line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',');
391
+
392
+ // states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'.
393
+ // some formatting depends on that.
394
+ current_mode = 'BLOCK';
395
+ modes = [current_mode];
396
+
397
+ parser_pos = 0;
398
+ in_case = false; // flag for parser that case/default has been processed, and next colon needs special attention
399
+ while (true) {
400
+ var t = get_next_token(parser_pos);
401
+ token_text = t[0];
402
+ token_type = t[1];
403
+ if (token_type === 'TK_EOF') {
404
+ break;
405
+ }
406
+
407
+ switch (token_type) {
408
+
409
+ case 'TK_START_EXPR':
410
+ var_line = false;
411
+ set_mode('EXPRESSION');
412
+ if (last_text === ';') {
413
+ print_newline();
414
+ } else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR') {
415
+ // do nothing on (( and )( and ][ and ]( ..
416
+ } else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') {
417
+ print_space();
418
+ } else if (in_array(last_word, line_starters) && last_word !== 'function') {
419
+ print_space();
420
+ }
421
+ print_token();
422
+ break;
423
+
424
+ case 'TK_END_EXPR':
425
+ print_token();
426
+ restore_mode();
427
+ break;
428
+
429
+ case 'TK_START_BLOCK':
430
+
431
+ if (last_word === 'do') {
432
+ set_mode('DO_BLOCK');
433
+ } else {
434
+ set_mode('BLOCK');
435
+ }
436
+ if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
437
+ if (last_type === 'TK_START_BLOCK') {
438
+ print_newline();
439
+ } else {
440
+ print_space();
441
+ }
442
+ }
443
+ print_token();
444
+ indent();
445
+ break;
446
+
447
+ case 'TK_END_BLOCK':
448
+ if (last_type === 'TK_START_BLOCK') {
449
+ // nothing
450
+ trim_output();
451
+ unindent();
452
+ } else {
453
+ unindent();
454
+ print_newline();
455
+ }
456
+ print_token();
457
+ restore_mode();
458
+ break;
459
+
460
+ case 'TK_WORD':
461
+
462
+ if (do_block_just_closed) {
463
+ // do {} ## while ()
464
+ print_space();
465
+ print_token();
466
+ print_space();
467
+ do_block_just_closed = false;
468
+ break;
469
+ }
470
+
471
+ if (token_text === 'case' || token_text === 'default') {
472
+ if (last_text === ':') {
473
+ // switch cases following one another
474
+ remove_indent();
475
+ } else {
476
+ // case statement starts in the same line where switch
477
+ unindent();
478
+ print_newline();
479
+ indent();
480
+ }
481
+ print_token();
482
+ in_case = true;
483
+ break;
484
+ }
485
+
486
+ prefix = 'NONE';
487
+
488
+ if (last_type === 'TK_END_BLOCK') {
489
+ if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
490
+ prefix = 'NEWLINE';
491
+ } else {
492
+ prefix = 'SPACE';
493
+ print_space();
494
+ }
495
+ } else if (last_type === 'TK_SEMICOLON' && (current_mode === 'BLOCK' || current_mode === 'DO_BLOCK')) {
496
+ prefix = 'NEWLINE';
497
+ } else if (last_type === 'TK_SEMICOLON' && current_mode === 'EXPRESSION') {
498
+ prefix = 'SPACE';
499
+ } else if (last_type === 'TK_STRING') {
500
+ prefix = 'NEWLINE';
501
+ } else if (last_type === 'TK_WORD') {
502
+ prefix = 'SPACE';
503
+ } else if (last_type === 'TK_START_BLOCK') {
504
+ prefix = 'NEWLINE';
505
+ } else if (last_type === 'TK_END_EXPR') {
506
+ print_space();
507
+ prefix = 'NEWLINE';
508
+ }
509
+
510
+ if (last_type !== 'TK_END_BLOCK' && in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
511
+ print_newline();
512
+ } else if (in_array(token_text, line_starters) || prefix === 'NEWLINE') {
513
+ if (last_text === 'else') {
514
+ // no need to force newline on else break
515
+ print_space();
516
+ } else if ((last_type === 'TK_START_EXPR' || last_text === '=' || last_text === ',') && token_text === 'function') {
517
+ // no need to force newline on 'function': (function
518
+ // DONOTHING
519
+ } else if (last_type === 'TK_WORD' && (last_text === 'return' || last_text === 'throw')) {
520
+ // no newline between 'return nnn'
521
+ print_space();
522
+ } else if (last_type !== 'TK_END_EXPR') {
523
+ if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':') {
524
+ // no need to force newline on 'var': for (var x = 0...)
525
+ if (token_text === 'if' && last_type === 'TK_WORD' && last_word === 'else') {
526
+ // no newline for } else if {
527
+ print_space();
528
+ } else {
529
+ print_newline();
530
+ }
531
+ }
532
+ } else {
533
+ if (in_array(token_text, line_starters) && last_text !== ')') {
534
+ print_newline();
535
+ }
536
+ }
537
+ } else if (prefix === 'SPACE') {
538
+ print_space();
539
+ }
540
+ print_token();
541
+ last_word = token_text;
542
+
543
+ if (token_text === 'var') {
544
+ var_line = true;
545
+ var_line_tainted = false;
546
+ }
547
+
548
+ if (token_text === 'if' || token_text === 'else') {
549
+ if_line_flag = true;
550
+ }
551
+
552
+ break;
553
+
554
+ case 'TK_SEMICOLON':
555
+
556
+ print_token();
557
+ var_line = false;
558
+ break;
559
+
560
+ case 'TK_STRING':
561
+
562
+ if (last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type == 'TK_SEMICOLON') {
563
+ print_newline();
564
+ } else if (last_type === 'TK_WORD') {
565
+ print_space();
566
+ }
567
+ print_token();
568
+ break;
569
+
570
+ case 'TK_OPERATOR':
571
+
572
+ var start_delim = true;
573
+ var end_delim = true;
574
+ if (var_line && token_text !== ',') {
575
+ var_line_tainted = true;
576
+ if (token_text === ':') {
577
+ var_line = false;
578
+ }
579
+ }
580
+ if (var_line && token_text === ',' && current_mode === 'EXPRESSION') {
581
+ // do not break on comma, for(var a = 1, b = 2)
582
+ var_line_tainted = false;
583
+ }
584
+
585
+ if (token_text === ':' && in_case) {
586
+ print_token(); // colon really asks for separate treatment
587
+ print_newline();
588
+ break;
589
+ }
590
+
591
+ if (token_text === '::') {
592
+ // no spaces around exotic namespacing syntax operator
593
+ print_token();
594
+ break;
595
+ }
596
+
597
+ in_case = false;
598
+
599
+ if (token_text === ',') {
600
+ if (var_line) {
601
+ if (var_line_tainted) {
602
+ print_token();
603
+ print_newline();
604
+ var_line_tainted = false;
605
+ } else {
606
+ print_token();
607
+ print_space();
608
+ }
609
+ } else if (last_type === 'TK_END_BLOCK') {
610
+ print_token();
611
+ print_newline();
612
+ } else {
613
+ if (current_mode === 'BLOCK') {
614
+ print_token();
615
+ print_newline();
616
+ } else {
617
+ // EXPR od DO_BLOCK
618
+ print_token();
619
+ print_space();
620
+ }
621
+ }
622
+ break;
623
+ } else if (token_text === '--' || token_text === '++') { // unary operators special case
624
+ if (last_text === ';') {
625
+ // space for (;; ++i)
626
+ start_delim = true;
627
+ end_delim = false;
628
+ } else {
629
+ start_delim = false;
630
+ end_delim = false;
631
+ }
632
+ } else if (token_text === '!' && last_type === 'TK_START_EXPR') {
633
+ // special case handling: if (!a)
634
+ start_delim = false;
635
+ end_delim = false;
636
+ } else if (last_type === 'TK_OPERATOR') {
637
+ start_delim = false;
638
+ end_delim = false;
639
+ } else if (last_type === 'TK_END_EXPR') {
640
+ start_delim = true;
641
+ end_delim = true;
642
+ } else if (token_text === '.') {
643
+ // decimal digits or object.property
644
+ start_delim = false;
645
+ end_delim = false;
646
+
647
+ } else if (token_text === ':') {
648
+ // zz: xx
649
+ // can't differentiate ternary op, so for now it's a ? b: c; without space before colon
650
+ if (last_text.match(/^\d+$/)) {
651
+ // a little help for ternary a ? 1 : 0;
652
+ start_delim = true;
653
+ } else {
654
+ start_delim = false;
655
+ }
656
+ }
657
+ if (start_delim) {
658
+ print_space();
659
+ }
660
+
661
+ print_token();
662
+
663
+ if (end_delim) {
664
+ print_space();
665
+ }
666
+ break;
667
+
668
+ case 'TK_BLOCK_COMMENT':
669
+
670
+ print_newline();
671
+ print_token();
672
+ print_newline();
673
+ break;
674
+
675
+ case 'TK_COMMENT':
676
+
677
+ // print_newline();
678
+ print_space();
679
+ print_token();
680
+ print_newline();
681
+ break;
682
+
683
+ case 'TK_UNKNOWN':
684
+ print_token();
685
+ break;
686
+ }
687
+
688
+ last_type = token_type;
689
+ last_text = token_text;
690
+ }
691
+
692
+ return output.join('').replace(/\n+$/, '');
693
+
694
+ }
695
+
696
+ var toString = Function.prototype.toString;
697
+ Function.prototype.tidy = function(){ return beautify( toString.call(this) ) };
698
+ String.prototype.tidy = function(){ return beautify(this); };
699
+
700
+ // tidy scripts if special window property set
701
+ if ( window.tidyScripts )
702
+ {
703
+ opera.addEventListener(BeforeScript, tidyScript, false);
704
+ function tidyScript(ev)
705
+ {
706
+ ev.element.text = Function.prototype.tidy.call(ev.element.text);
707
+ }
708
+ }
709
+
710
+ })();
711
+