rubyosa 0.2.0 → 0.3.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.
@@ -0,0 +1,136 @@
1
+ # Copyright (c) 2006-2007, Apple Inc. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ # 3. Neither the name of Apple Inc. ("Apple") nor the names of
12
+ # its contributors may be used to endorse or promote products derived
13
+ # from this software without specific prior written permission.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
16
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ # ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
19
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
+ # POSSIBILITY OF SUCH DAMAGE.
26
+
27
+ require 'enumerator'
28
+
29
+ module OSA
30
+ @sym_to_code = {}
31
+ @code_to_sym = {}
32
+
33
+ def self.add_property(sym, code)
34
+ return if @sym_to_code.has_key?(sym) or @code_to_sym.has_key?(code)
35
+ @sym_to_code[sym] = code
36
+ @code_to_sym[code] = sym
37
+ end
38
+
39
+ def self.sym_to_code(sym)
40
+ @sym_to_code[sym]
41
+ end
42
+
43
+ def self.code_to_sym(code)
44
+ @code_to_sym[code]
45
+ end
46
+ end
47
+
48
+ [
49
+ # pArcAngle
50
+ :arc_angle, 'parc',
51
+ :background_color, 'pbcl',
52
+ :background_pattern, 'pbpt',
53
+ :best_type, 'pbst',
54
+ :bounds, 'pbnd',
55
+ :class, 'pcls',
56
+ :clipboard, 'pcli',
57
+ :color, 'colr',
58
+ :color_table, 'cltb',
59
+ :contents, 'pcnt',
60
+ :corner_curve_height, 'pchd',
61
+ :corner_curve_width, 'pcwd',
62
+ :dash_style, 'pdst',
63
+ :default_type, 'deft',
64
+ :definition_rect, 'pdrt',
65
+ :enabled, 'enbl',
66
+ :end_point, 'pend',
67
+ :fill_color, 'flcl',
68
+ :fill_pattern, 'flpt',
69
+ :font, 'font',
70
+
71
+ # pFormula
72
+ :formula, 'pfor',
73
+ :graphic_objects, 'gobs',
74
+ :has_close_box, 'hclb',
75
+ :has_title_bar, 'ptit',
76
+ :id, 'ID ',
77
+ :index, 'pidx',
78
+ :insertion_loc, 'pins',
79
+ :is_floating, 'isfl',
80
+ :is_front_process, 'pisf',
81
+ :is_modal, 'pmod',
82
+ :is_modified, 'imod',
83
+ :is_resizable, 'prsz',
84
+ :is_stationery_pad, 'pspd',
85
+ :is_zoomable, 'iszm',
86
+ :is_zoomed, 'pzum',
87
+ :item_number, 'itmn',
88
+ :justification, 'pjst',
89
+ :line_arrow, 'arro',
90
+ :menu_id, 'mnid',
91
+ :name, 'pnam',
92
+
93
+ # pNewElementLoc
94
+ :new_element_loc, 'pnel',
95
+ :pen_color, 'ppcl',
96
+ :pen_pattern, 'pppa',
97
+ :pen_width, 'ppwd',
98
+ :pixel_depth, 'pdpt',
99
+ :point_list, 'ptlt',
100
+ :point_size, 'ptsz',
101
+ :protection, 'ppro',
102
+ :rotation, 'prot',
103
+ :scale, 'pscl',
104
+ :script, 'scpt',
105
+ :script_tag, 'psct',
106
+ :selected, 'selc',
107
+ :selection, 'sele',
108
+ :start_angle, 'pang',
109
+ :start_point, 'pstp',
110
+ :text_color, 'ptxc',
111
+ :text_font, 'ptxf',
112
+ :text_item_delimiters, 'txdl',
113
+ :text_point_size, 'ptps',
114
+
115
+ # pScheme
116
+ :scheme, 'pusc',
117
+ :host, 'HOST',
118
+ :path, 'FTPc',
119
+ :user_name, 'RAun',
120
+ :user_password, 'RApw',
121
+ :dns_form, 'pDNS',
122
+ :url, 'pURL',
123
+ :text_encoding, 'ptxe',
124
+ :ftp_kind, 'kind',
125
+
126
+ # pTextStyles
127
+ :text_styles, 'txst',
128
+ :transfer_mode, 'pptm',
129
+ :translation, 'ptrs',
130
+ :uniform_styles, 'ustl',
131
+ :update_on, 'pupd',
132
+ :user_selection, 'pusl',
133
+ :version, 'vers',
134
+ :visible, 'pvis'
135
+
136
+ ].each_slice(2) { |sym, code| OSA.add_property(sym, code) }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2006, Apple Computer, Inc. All rights reserved.
2
+ * Copyright (c) 2006-2007, Apple Inc. All rights reserved.
3
3
  *
4
4
  * Redistribution and use in source and binary forms, with or without
5
5
  * modification, are permitted provided that the following conditions
@@ -9,7 +9,7 @@
9
9
  * 2. Redistributions in binary form must reproduce the above copyright
10
10
  * notice, this list of conditions and the following disclaimer in the
11
11
  * documentation and/or other materials provided with the distribution.
12
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
12
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
13
13
  * its contributors may be used to endorse or promote products derived
14
14
  * from this software without specific prior written permission.
15
15
  *
@@ -38,8 +38,6 @@ static VALUE mOSAEventDispatcher;
38
38
  static ID sClasses;
39
39
  static ID sApp;
40
40
 
41
- #define INSPECT_AEDESC 0
42
-
43
41
  static void
44
42
  rbosa_element_free (void *ptr)
45
43
  {
@@ -170,7 +168,7 @@ rbosa_element_new (VALUE self, VALUE type, VALUE value)
170
168
  error = AECreateDesc (ffc_type, c_value, c_value_size, &desc);
171
169
  if (error != noErr)
172
170
  rb_raise (rb_eArgError, "Cannot create Apple Event descriptor from type '%s' value '%s' : %s (%d)",
173
- RVAL2CSTR (type), c_value, GetMacOSStatusErrorString (error), error);
171
+ RVAL2CSTR (type), c_value, error_code_to_string (error), error);
174
172
 
175
173
  return rbosa_element_make (self, &desc, Qnil);
176
174
  }
@@ -190,11 +188,27 @@ rbosa_element_new_os (VALUE self, VALUE desired_class, VALUE container, VALUE ke
190
188
 
191
189
  if (error != noErr)
192
190
  rb_raise (rb_eArgError, "Cannot create Apple Event object specifier for desired class '%s' : %s (%d)",
193
- RVAL2CSTR (desired_class), GetMacOSStatusErrorString (error), error);
191
+ RVAL2CSTR (desired_class), error_code_to_string (error), error);
194
192
 
195
193
  return rbosa_element_make (self, &obj_specifier, Qnil);
196
194
  }
197
195
 
196
+ static VALUE
197
+ rbosa_element_dup (VALUE self, VALUE element)
198
+ {
199
+ AEDesc * desc;
200
+ AEDesc new_desc;
201
+ OSErr error;
202
+
203
+ desc = rbosa_element_aedesc (element);
204
+ error = AEDuplicateDesc (desc, &new_desc);
205
+ if (error != noErr)
206
+ rb_raise (rb_eArgError, "Cannot duplicate element : %s (%d)",
207
+ error_code_to_string (error), error);
208
+
209
+ return rbosa_element_make (self, &new_desc, Qnil);
210
+ }
211
+
198
212
  static void
199
213
  __rbosa_raise_potential_app_error (AEDesc *reply)
200
214
  {
@@ -202,20 +216,23 @@ __rbosa_raise_potential_app_error (AEDesc *reply)
202
216
  AEDesc errorNumDesc;
203
217
  AEDesc errorStringDesc;
204
218
  int errorNum;
219
+ const char * errorMsg;
205
220
  char exception[128];
206
221
 
207
- if (AEGetParamDesc (reply, keyErrorNumber, typeInteger, &errorNumDesc) != noErr)
222
+ if (AEGetParamDesc (reply, keyErrorNumber, typeSInt32, &errorNumDesc) != noErr)
208
223
  return;
209
224
 
210
- if (AEGetDescData (&errorNumDesc, &errorNum, sizeof errorNum) != noErr
211
- || (errorNum = CFSwapInt32HostToBig (errorNum)) == 0) {
212
-
225
+ if (AEGetDescData (&errorNumDesc, &errorNum, sizeof errorNum) != noErr) {
213
226
  AEDisposeDesc (&errorNumDesc);
214
227
  return;
215
228
  }
216
229
 
217
230
  /* The reply is an application error. */
218
231
 
232
+ errorMsg = error_code_to_string(errorNum);
233
+ if (errorMsg == NULL)
234
+ errorMsg = "Unknown error";
235
+
219
236
  exception[0] = '\0';
220
237
  error = AEGetParamDesc (reply, keyErrorString, typeChar, &errorStringDesc);
221
238
  if (error == noErr) {
@@ -225,10 +242,12 @@ __rbosa_raise_potential_app_error (AEDesc *reply)
225
242
  if (size > 0) {
226
243
  char *msg;
227
244
 
228
- msg = (char *)malloc (size);
245
+ msg = (char *)malloc (size + 1);
229
246
  if (msg != NULL) {
230
- if (AEGetDescData (&errorStringDesc, &msg, size) == noErr)
231
- snprintf (exception, sizeof exception, "application returned error %d with message '%s'", errorNum, msg);
247
+ if (AEGetDescData (&errorStringDesc, msg, size) == noErr) {
248
+ msg[size] = '\0';
249
+ snprintf (exception, sizeof exception, "application returned error: %s (%d), with message: %s", errorMsg, errorNum, msg);
250
+ }
232
251
  free (msg);
233
252
  }
234
253
  }
@@ -236,7 +255,7 @@ __rbosa_raise_potential_app_error (AEDesc *reply)
236
255
  }
237
256
 
238
257
  if (exception[0] == '\0')
239
- snprintf (exception, sizeof exception, "application returned error %d", errorNum);
258
+ snprintf (exception, sizeof exception, "application returned error: %s (%d)", errorMsg, errorNum);
240
259
 
241
260
  AEDisposeDesc (&errorNumDesc);
242
261
 
@@ -251,6 +270,7 @@ rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE param
251
270
  AppleEvent reply;
252
271
  VALUE rb_timeout;
253
272
  SInt32 timeout;
273
+ VALUE rb_reply;
254
274
 
255
275
  error = AECreateAppleEvent (RVAL2FOURCHAR (event_class),
256
276
  RVAL2FOURCHAR (event_id),
@@ -260,7 +280,7 @@ rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE param
260
280
  &ae);
261
281
  if (error != noErr)
262
282
  rb_raise (rb_eArgError, "Cannot create Apple Event '%s%s' : %s (%d)",
263
- RVAL2CSTR (event_class), RVAL2CSTR (event_id), GetMacOSStatusErrorString (error), error);
283
+ RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error);
264
284
 
265
285
  if (!NIL_P (params)) {
266
286
  unsigned i;
@@ -281,7 +301,7 @@ rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE param
281
301
  if (error != noErr) {
282
302
  AEDisposeDesc (&ae);
283
303
  rb_raise (rb_eArgError, "Cannot add Apple Event parameter '%s' : %s (%d)",
284
- RVAL2CSTR (type), GetMacOSStatusErrorString (error), error);
304
+ RVAL2CSTR (type), error_code_to_string (error), error);
285
305
  }
286
306
  }
287
307
  }
@@ -289,28 +309,31 @@ rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE param
289
309
  rb_timeout = rb_iv_get (mOSA, "@timeout");
290
310
  timeout = NIL_P (rb_timeout) ? kAEDefaultTimeout : NUM2INT (rb_timeout);
291
311
 
292
- error = AESend (&ae, &reply, (RVAL2CBOOL(need_retval) ? kAEWaitReply : kAENoReply) | kAENeverInteract | kAECanSwitchLayer,
312
+ error = AESend (&ae, &reply, (RVAL2CBOOL(need_retval) ? kAEWaitReply : kAENoReply) | kAECanInteract | kAECanSwitchLayer,
293
313
  kAENormalPriority, timeout, NULL, NULL);
294
314
 
295
315
  AEDisposeDesc (&ae);
296
316
 
297
317
  if (error != noErr)
298
318
  rb_raise (rb_eRuntimeError, "Cannot send Apple Event '%s%s' : %s (%d)",
299
- RVAL2CSTR (event_class), RVAL2CSTR (event_id), GetMacOSStatusErrorString (error), error);
319
+ RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error);
300
320
 
301
321
  __rbosa_raise_potential_app_error (&reply);
302
322
 
303
323
  if (RTEST (need_retval)) {
304
- VALUE rb_reply;
305
324
  AEDesc replyObject;
306
325
 
307
326
  AEGetParamDesc (&reply, keyDirectObject, typeWildCard, &replyObject);
308
327
 
309
328
  rb_reply = rbosa_element_make (cOSAElement, &replyObject, self);
310
-
311
- return rb_reply;
312
329
  }
313
- return Qnil;
330
+ else {
331
+ rb_reply = Qnil;
332
+ }
333
+
334
+ AEDisposeDesc (&reply);
335
+
336
+ return rb_reply;
314
337
  }
315
338
 
316
339
  static VALUE
@@ -349,7 +372,7 @@ rbosa_element_data (int argc, VALUE *argv, VALUE self)
349
372
  error = AECoerceDesc (desc, code, &coerced_desc);
350
373
  if (error != noErr)
351
374
  rb_raise (rb_eRuntimeError, "Cannot coerce desc to type %s : %s (%d)",
352
- RVAL2CSTR (coerce_type), GetMacOSStatusErrorString (error), error);
375
+ RVAL2CSTR (coerce_type), error_code_to_string (error), error);
353
376
 
354
377
  desc = &coerced_desc;
355
378
  to_4cc = code == 'type';
@@ -376,11 +399,42 @@ rbosa_element_data (int argc, VALUE *argv, VALUE self)
376
399
 
377
400
  if (error != noErr)
378
401
  rb_raise (rb_eRuntimeError, "Cannot get desc data : %s (%d)",
379
- GetMacOSStatusErrorString (error), error);
402
+ error_code_to_string (error), error);
380
403
 
381
404
  return retval;
382
405
  }
383
406
 
407
+ static VALUE
408
+ __rbosa_insertion_loc_new (VALUE rcv, FourCharCode code)
409
+ {
410
+ AEDesc * self_desc;
411
+ AEDesc rec;
412
+ AEDesc pos_desc;
413
+ AEDesc new_desc;
414
+
415
+ self_desc = rbosa_element_aedesc (rcv);
416
+ AECreateList (NULL, 0, true, &rec);
417
+ AEPutParamDesc (&rec, keyAEObject, self_desc);
418
+ AECreateDesc (code, NULL, 0, &pos_desc);
419
+ AEPutParamPtr (&rec, keyAEPosition, typeEnumerated, &pos_desc, 4);
420
+ AECoerceDesc (&rec, typeInsertionLoc, &new_desc);
421
+ AEDisposeDesc (&rec);
422
+
423
+ return rbosa_element_make (cOSAElement, &new_desc, Qnil);
424
+ }
425
+
426
+ static VALUE
427
+ rbosa_element_after (VALUE self)
428
+ {
429
+ return __rbosa_insertion_loc_new (self, kAEAfter);
430
+ }
431
+
432
+ static VALUE
433
+ rbosa_element_before (VALUE self)
434
+ {
435
+ return __rbosa_insertion_loc_new (self, kAEBefore);
436
+ }
437
+
384
438
  static VALUE
385
439
  rbosa_element_eql (VALUE self, VALUE other)
386
440
  {
@@ -432,25 +486,22 @@ bails:
432
486
  return CBOOL2RVAL (ok);
433
487
  }
434
488
 
435
- #if INSPECT_AEDESC
436
489
  static VALUE
437
490
  rbosa_element_inspect (VALUE self)
438
491
  {
439
492
  Handle h;
440
- VALUE s;
441
493
  char buf[1024];
442
494
 
443
- s = rb_call_super (0, NULL);
444
- if (AEPrintDescToHandle (rbosa_element_aedesc (self), &h) != noErr)
445
- return s;
495
+ if (AEPrintDescToHandle (rbosa_element_aedesc (self), &h) != noErr) {
496
+ snprintf (buf, sizeof buf, "<%s:%p>", rb_obj_classname (self), (void *)self);
497
+ }
498
+ else {
499
+ snprintf (buf, sizeof buf, "<%s:%p desc=\"%s\">", rb_obj_classname (self), (void *)self, *h);
500
+ DisposeHandle (h);
501
+ }
446
502
 
447
- RSTRING(s)->ptr[RSTRING(s)->len - 1] = '\0';
448
- snprintf (buf, sizeof buf, "%s aedesc=\"%s\">", RSTRING(s)->ptr, *h);
449
- DisposeHandle (h);
450
-
451
503
  return CSTR2RVAL (buf);
452
504
  }
453
- #endif
454
505
 
455
506
  static long
456
507
  __rbosa_elementlist_count (AEDescList *list)
@@ -461,7 +512,7 @@ __rbosa_elementlist_count (AEDescList *list)
461
512
  error = AECountItems (list, &count);
462
513
  if (error != noErr)
463
514
  rb_raise (rb_eRuntimeError, "Cannot count items : %s (%d)",
464
- GetMacOSStatusErrorString (error), error);
515
+ error_code_to_string (error), error);
465
516
 
466
517
  return count;
467
518
  }
@@ -474,7 +525,7 @@ __rbosa_elementlist_add (AEDescList *list, VALUE element, long pos)
474
525
  error = AEPutDesc (list, pos, rbosa_element_aedesc (element));
475
526
  if (error != noErr)
476
527
  rb_raise (rb_eRuntimeError, "Cannot add given descriptor : %s (%d)",
477
- GetMacOSStatusErrorString (error), error);
528
+ error_code_to_string (error), error);
478
529
  }
479
530
 
480
531
  static VALUE
@@ -493,7 +544,7 @@ rbosa_elementlist_new (int argc, VALUE *argv, VALUE self)
493
544
  error = AECreateList (NULL, 0, false, &list);
494
545
  if (error != noErr)
495
546
  rb_raise (rb_eRuntimeError, "Cannot create Apple Event descriptor list : %s (%d)",
496
- GetMacOSStatusErrorString (error), error);
547
+ error_code_to_string (error), error);
497
548
 
498
549
  if (!NIL_P (ary)) {
499
550
  for (i = 0; i < RARRAY (ary)->len; i++)
@@ -528,7 +579,7 @@ __rbosa_elementlist_get (VALUE self, long index, AEKeyword *keyword)
528
579
 
529
580
  if (error != noErr)
530
581
  rb_raise (rb_eRuntimeError, "Cannot get desc at index %d : %s (%d)",
531
- index, GetMacOSStatusErrorString (error), error);
582
+ index, error_code_to_string (error), error);
532
583
 
533
584
  return rbosa_element_make (cOSAElement, &desc, rb_ivar_get (self, sApp));
534
585
  }
@@ -554,7 +605,7 @@ __rbosa_elementrecord_set (VALUE key, VALUE value, AEDescList *list)
554
605
  error = AEPutKeyDesc (list, RVAL2FOURCHAR (key), rbosa_element_aedesc (value));
555
606
  if (error != noErr)
556
607
  rb_raise (rb_eRuntimeError, "Cannot set value %p for key %p of record %p: %s (%d)",
557
- value, key, list, GetMacOSStatusErrorString (error), error);
608
+ value, key, list, error_code_to_string (error), error);
558
609
 
559
610
  return ST_CONTINUE;
560
611
  }
@@ -574,7 +625,7 @@ rbosa_elementrecord_new (int argc, VALUE *argv, VALUE self)
574
625
  error = AECreateList (NULL, 0, true, &list);
575
626
  if (error != noErr)
576
627
  rb_raise (rb_eRuntimeError, "Cannot create Apple Event descriptor list : %s (%d)",
577
- GetMacOSStatusErrorString (error), error);
628
+ error_code_to_string (error), error);
578
629
 
579
630
  if (!NIL_P (hash))
580
631
  rb_hash_foreach (hash, __rbosa_elementrecord_set, (VALUE)&list);
@@ -620,18 +671,20 @@ Init_osa (void)
620
671
  sApp = rb_intern ("@app");
621
672
 
622
673
  mOSA = rb_define_module ("OSA");
623
- rb_define_module_function (mOSA, "__scripting_info__", rbosa_scripting_info, 2);
674
+ rb_define_module_function (mOSA, "__scripting_info__", rbosa_scripting_info, 1);
675
+ rb_define_module_function (mOSA, "__remote_processes__", rbosa_remote_processes, 1);
624
676
  rb_define_module_function (mOSA, "__four_char_code__", rbosa_four_char_code, 1);
625
677
 
626
678
  cOSAElement = rb_define_class_under (mOSA, "Element", rb_cObject);
627
679
  rb_define_singleton_method (cOSAElement, "__new__", rbosa_element_new, 2);
628
680
  rb_define_singleton_method (cOSAElement, "__new_object_specifier__", rbosa_element_new_os, 4);
681
+ rb_define_singleton_method (cOSAElement, "__duplicate__", rbosa_element_dup, 1);
629
682
  rb_define_method (cOSAElement, "__type__", rbosa_element_type, 0);
630
683
  rb_define_method (cOSAElement, "__data__", rbosa_element_data, -1);
684
+ rb_define_method (cOSAElement, "before", rbosa_element_before, 0);
685
+ rb_define_method (cOSAElement, "after", rbosa_element_after, 0);
631
686
  rb_define_method (cOSAElement, "==", rbosa_element_eql, 1);
632
- #if INSPECT_AEDESC
633
687
  rb_define_method (cOSAElement, "inspect", rbosa_element_inspect, 0);
634
- #endif
635
688
 
636
689
  cOSAElementList = rb_define_class_under (mOSA, "ElementList", cOSAElement);
637
690
  rb_define_singleton_method (cOSAElementList, "__new__", rbosa_elementlist_new, -1);
@@ -650,4 +703,5 @@ Init_osa (void)
650
703
  rbosa_define_param ("timeout", INT2NUM (kAEDefaultTimeout));
651
704
  rbosa_define_param ("lazy_events", Qtrue);
652
705
  rbosa_define_param ("utf8_strings", Qfalse);
706
+ rbosa_define_param ("wait_reply", Qnil);
653
707
  }