superchris-rubyjs 0.8.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.
- data/README +131 -0
- data/Rakefile +65 -0
- data/bin/rubyjs +144 -0
- data/rubyjs.gemspec +112 -0
- data/src/rubyjs.rb +3 -0
- data/src/rubyjs/code_generator.rb +474 -0
- data/src/rubyjs/compiler.rb +2061 -0
- data/src/rubyjs/debug_name_generator.rb +95 -0
- data/src/rubyjs/encoder.rb +171 -0
- data/src/rubyjs/eval_into.rb +59 -0
- data/src/rubyjs/lib/core.rb +1016 -0
- data/src/rubyjs/lib/dom_element.rb +66 -0
- data/src/rubyjs/lib/json.rb +101 -0
- data/src/rubyjs/lib/microunit.rb +188 -0
- data/src/rubyjs/model.rb +293 -0
- data/src/rubyjs/name_generator.rb +71 -0
- data/src/rwt/AbsolutePanel.rb +161 -0
- data/src/rwt/DOM.Konqueror.rb +89 -0
- data/src/rwt/DOM.Opera.rb +65 -0
- data/src/rwt/DOM.rb +1044 -0
- data/src/rwt/Event.Opera.rb +35 -0
- data/src/rwt/Event.rb +429 -0
- data/src/rwt/HTTPRequest.IE6.rb +5 -0
- data/src/rwt/HTTPRequest.rb +74 -0
- data/src/rwt/Label.rb +164 -0
- data/src/rwt/Panel.rb +90 -0
- data/src/rwt/RootPanel.rb +16 -0
- data/src/rwt/UIObject.rb +495 -0
- data/src/rwt/Widget.rb +193 -0
- data/src/rwt/ported-from/AbsolutePanel.java +158 -0
- data/src/rwt/ported-from/DOM.java +571 -0
- data/src/rwt/ported-from/DOMImpl.java +426 -0
- data/src/rwt/ported-from/DOMImplOpera.java +82 -0
- data/src/rwt/ported-from/DOMImplStandard.java +234 -0
- data/src/rwt/ported-from/HTTPRequest.java +81 -0
- data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
- data/src/rwt/ported-from/Label.java +163 -0
- data/src/rwt/ported-from/Panel.java +99 -0
- data/src/rwt/ported-from/UIObject.java +614 -0
- data/src/rwt/ported-from/Widget.java +221 -0
- data/test/benchmark/bm_vm1_block.rb +15 -0
- data/test/benchmark/bm_vm1_const.rb +13 -0
- data/test/benchmark/bm_vm1_ensure.rb +15 -0
- data/test/benchmark/common.rb +5 -0
- data/test/benchmark/params.yaml +7 -0
- data/test/common.Browser.rb +13 -0
- data/test/common.rb +8 -0
- data/test/gen_browser_test_suite.rb +129 -0
- data/test/gen_test_suite.rb +41 -0
- data/test/run_benchs.rb +58 -0
- data/test/run_tests.rb +22 -0
- data/test/test_args.rb +24 -0
- data/test/test_array.rb +22 -0
- data/test/test_case.rb +35 -0
- data/test/test_class.rb +55 -0
- data/test/test_eql.rb +9 -0
- data/test/test_exception.rb +61 -0
- data/test/test_expr.rb +12 -0
- data/test/test_hash.rb +29 -0
- data/test/test_hot_ruby.rb +146 -0
- data/test/test_if.rb +28 -0
- data/test/test_insertion_sort.rb +25 -0
- data/test/test_inspect.rb +10 -0
- data/test/test_lebewesen.rb +39 -0
- data/test/test_massign.rb +66 -0
- data/test/test_new.rb +12 -0
- data/test/test_range.rb +70 -0
- data/test/test_regexp.rb +22 -0
- data/test/test_send.rb +65 -0
- data/test/test_simple_output.rb +5 -0
- data/test/test_splat.rb +21 -0
- data/test/test_string.rb +51 -0
- data/test/test_test.rb +17 -0
- data/test/test_yield.rb +154 -0
- data/utils/js/Makefile +9 -0
- data/utils/js/RunScript.class +0 -0
- data/utils/js/RunScript.java +73 -0
- data/utils/js/js.jar +0 -0
- data/utils/js/run.sh +3 -0
- data/utils/jsc/Makefile +7 -0
- data/utils/jsc/README +3 -0
- data/utils/jsc/RunScript.c +93 -0
- data/utils/jsc/run.sh +15 -0
- data/utils/yuicompressor/README +1 -0
- data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
- metadata +157 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de)
|
3
|
+
#
|
4
|
+
# Copyright 2007 Google Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
7
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
# License for the specific language governing permissions and limitations under
|
16
|
+
# the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
#
|
20
|
+
# Opera specific overrides.
|
21
|
+
#
|
22
|
+
class Event
|
23
|
+
|
24
|
+
def self.eventGetButton(evt)
|
25
|
+
# Opera and IE disagree on what the button codes for left button should be.
|
26
|
+
# Translating to match IE standard.
|
27
|
+
`var button = #<evt>.button;
|
28
|
+
return (button == 0) ? 1 : button`
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.eventGetMouseWheelVelocityY(evt)
|
32
|
+
`return #<evt>.detail * 4`
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/src/rwt/Event.rb
ADDED
@@ -0,0 +1,429 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de)
|
3
|
+
#
|
4
|
+
# Copyright 2007 Google Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
7
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
# License for the specific language governing permissions and limitations under
|
16
|
+
# the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
class Event
|
20
|
+
|
21
|
+
#-------------------------------------------------------------------
|
22
|
+
# Constants
|
23
|
+
#-------------------------------------------------------------------
|
24
|
+
|
25
|
+
#
|
26
|
+
# The left mouse button
|
27
|
+
#
|
28
|
+
BUTTON_LEFT = 1
|
29
|
+
|
30
|
+
#
|
31
|
+
# The middle mouse button
|
32
|
+
#
|
33
|
+
BUTTON_MIDDLE = 4
|
34
|
+
|
35
|
+
#
|
36
|
+
# The right mouse button
|
37
|
+
#
|
38
|
+
BUTTON_RIGHT = 2
|
39
|
+
|
40
|
+
#
|
41
|
+
# Fired when an element loses keyboard focus.
|
42
|
+
#
|
43
|
+
ONBLUR = 0x01000
|
44
|
+
|
45
|
+
#
|
46
|
+
# Fired when the value of an input element changes.
|
47
|
+
#
|
48
|
+
ONCHANGE = 0x00400
|
49
|
+
|
50
|
+
#
|
51
|
+
# Fired when the user clicks on an element.
|
52
|
+
#
|
53
|
+
ONCLICK = 0x00001
|
54
|
+
|
55
|
+
#
|
56
|
+
# Fired when the user double-clicks on an element.
|
57
|
+
#
|
58
|
+
ONDBLCLICK = 0x00002
|
59
|
+
|
60
|
+
#
|
61
|
+
# Fired when an image encounters an error.
|
62
|
+
#
|
63
|
+
ONERROR = 0x10000
|
64
|
+
|
65
|
+
#
|
66
|
+
# Fired when an element receives keyboard focus.
|
67
|
+
#
|
68
|
+
ONFOCUS = 0x00800
|
69
|
+
|
70
|
+
#
|
71
|
+
# Fired when the user depresses a key.
|
72
|
+
#
|
73
|
+
ONKEYDOWN = 0x00080
|
74
|
+
|
75
|
+
#
|
76
|
+
# Fired when the a character is generated from a keypress (either directly or
|
77
|
+
# through auto-repeat).
|
78
|
+
#
|
79
|
+
ONKEYPRESS = 0x00100
|
80
|
+
|
81
|
+
#
|
82
|
+
# Fired when the user releases a key.
|
83
|
+
#
|
84
|
+
ONKEYUP = 0x00200
|
85
|
+
|
86
|
+
#
|
87
|
+
# Fired when an element (normally an IMG) finishes loading.
|
88
|
+
#
|
89
|
+
ONLOAD = 0x08000
|
90
|
+
|
91
|
+
#
|
92
|
+
# Fired when an element that has mouse capture loses it.
|
93
|
+
#
|
94
|
+
ONLOSECAPTURE = 0x02000
|
95
|
+
|
96
|
+
#
|
97
|
+
# Fired when the user depresses a mouse button over an element.
|
98
|
+
#
|
99
|
+
ONMOUSEDOWN = 0x00004
|
100
|
+
|
101
|
+
#
|
102
|
+
# Fired when the mouse is moved within an element's area.
|
103
|
+
#
|
104
|
+
ONMOUSEMOVE = 0x00040
|
105
|
+
|
106
|
+
#
|
107
|
+
# Fired when the mouse is moved out of an element's area.
|
108
|
+
#
|
109
|
+
ONMOUSEOUT = 0x00020
|
110
|
+
|
111
|
+
#
|
112
|
+
# Fired when the mouse is moved into an element's area.
|
113
|
+
#
|
114
|
+
ONMOUSEOVER = 0x00010
|
115
|
+
|
116
|
+
#
|
117
|
+
# Fired when the user releases a mouse button over an element.
|
118
|
+
#
|
119
|
+
ONMOUSEUP = 0x00008
|
120
|
+
|
121
|
+
#
|
122
|
+
# Fired when the user scrolls the mouse wheel over an element.
|
123
|
+
#
|
124
|
+
ONMOUSEWHEEL = 0x20000
|
125
|
+
|
126
|
+
#
|
127
|
+
# Fired when a scrollable element's scroll offset changes.
|
128
|
+
#
|
129
|
+
ONSCROLL = 0x04000
|
130
|
+
|
131
|
+
#
|
132
|
+
# A bit-mask covering both focus events (focus and blur).
|
133
|
+
#
|
134
|
+
FOCUSEVENTS = ONFOCUS | ONBLUR
|
135
|
+
|
136
|
+
#
|
137
|
+
# A bit-mask covering all keyboard events (down, up, and press).
|
138
|
+
#
|
139
|
+
KEYEVENTS = ONKEYDOWN | ONKEYPRESS | ONKEYUP
|
140
|
+
|
141
|
+
#
|
142
|
+
# A bit-mask covering all mouse events (down, up, move, over, and out), but
|
143
|
+
# not click, dblclick, or wheel events.
|
144
|
+
#
|
145
|
+
MOUSEEVENTS = ONMOUSEDOWN | ONMOUSEUP | ONMOUSEMOVE | ONMOUSEOVER | ONMOUSEOUT
|
146
|
+
|
147
|
+
#-------------------------------------------------------------------
|
148
|
+
# Keyboard related
|
149
|
+
#-------------------------------------------------------------------
|
150
|
+
|
151
|
+
#
|
152
|
+
# Gets whether the ALT key was depressed when the given event occurred.
|
153
|
+
#
|
154
|
+
# evt:: the event to be tested
|
155
|
+
# return:: +true+ if ALT was depressed when the event occurred
|
156
|
+
#
|
157
|
+
def self.getAltKey(evt)
|
158
|
+
`return #<evt>.altKey`
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Gets whether the CTRL key was depressed when the given event occurred.
|
163
|
+
#
|
164
|
+
# evt:: the event to be tested
|
165
|
+
# return:: +true+ if CTRL was depressed when the event occurred
|
166
|
+
#
|
167
|
+
def self.getCtrlKey(evt)
|
168
|
+
`return #<evt>.ctrlKey`
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# Gets whether the META key was depressed when the given event occurred.
|
173
|
+
#
|
174
|
+
# evt:: the event to be tested
|
175
|
+
# return:: +true+ if META was depressed when the event occurred
|
176
|
+
#
|
177
|
+
def self.getMetaKey(evt)
|
178
|
+
`return !!#<evt>.getMetaKey`
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# Gets whether the shift key was depressed when the given event occurred.
|
183
|
+
#
|
184
|
+
# evt:: the event to be tested
|
185
|
+
# return:: +true+ if shift was depressed when the event occurred
|
186
|
+
#
|
187
|
+
def self.getShiftKey(evt)
|
188
|
+
`return #<evt>.shiftKey`
|
189
|
+
end
|
190
|
+
|
191
|
+
#
|
192
|
+
# Gets the key code associated with this event.
|
193
|
+
#
|
194
|
+
# For +Event::ONKEYPRESS+, this method returns the Unicode value of the
|
195
|
+
# character generated. For +Event::ONKEYDOWN+ and +Event::ONKEYUP+,
|
196
|
+
# it returns the code associated with the physical key.
|
197
|
+
#
|
198
|
+
# evt:: the event to be tested
|
199
|
+
# return:: the Unicode character or key code.
|
200
|
+
#
|
201
|
+
def self.getKeyCode(evt)
|
202
|
+
# 'which' gives the right key value, except when it doesnt -- in which
|
203
|
+
# case, keyCode gives the right value on all browsers.
|
204
|
+
`return #<evt>.which || #<evt>.keyCode`
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# Gets the key-repeat state of this event.
|
209
|
+
#
|
210
|
+
# evt:: the event to be tested
|
211
|
+
# return:: +true+ if this key event was an auto-repeat
|
212
|
+
#
|
213
|
+
def self.getRepeat(evt)
|
214
|
+
`return #<evt>.repeat`
|
215
|
+
end
|
216
|
+
|
217
|
+
#
|
218
|
+
# Sets the key code associated with the given keyboard event.
|
219
|
+
#
|
220
|
+
# evt:: the event whose key code is to be set
|
221
|
+
# key:: the new key code
|
222
|
+
#
|
223
|
+
def self.setKeyCode(evt, key)
|
224
|
+
`#<evt>.keyCode = #<key>; return #<nil>`
|
225
|
+
end
|
226
|
+
|
227
|
+
#-------------------------------------------------------------------
|
228
|
+
# Mouse related
|
229
|
+
#-------------------------------------------------------------------
|
230
|
+
|
231
|
+
#
|
232
|
+
# Gets the mouse buttons that were depressed when the given event occurred.
|
233
|
+
#
|
234
|
+
# evt:: the event to be tested
|
235
|
+
# return:: a bit-field, defined by +Event::BUTTON_LEFT+,
|
236
|
+
# +Event::BUTTON_MIDDLE+ and +Event::BUTTON_RIGHT+
|
237
|
+
#
|
238
|
+
def self.getButton(evt)
|
239
|
+
`return #<evt>.button`
|
240
|
+
end
|
241
|
+
|
242
|
+
#
|
243
|
+
# Gets the mouse x-position within the browser window's client area.
|
244
|
+
#
|
245
|
+
# evt:: the event to be tested
|
246
|
+
# return:: the mouse x-position
|
247
|
+
#
|
248
|
+
def self.getClientX(evt)
|
249
|
+
`return #<evt>.clientX`
|
250
|
+
end
|
251
|
+
|
252
|
+
#
|
253
|
+
# Gets the mouse y-position within the browser window's client area.
|
254
|
+
#
|
255
|
+
# evt:: the event to be tested
|
256
|
+
# return:: the mouse y-position
|
257
|
+
#
|
258
|
+
def self.getClientY(evt)
|
259
|
+
`return #<evt>.clientY`
|
260
|
+
end
|
261
|
+
|
262
|
+
#
|
263
|
+
# Gets the mouse x-position on the user's display.
|
264
|
+
#
|
265
|
+
# evt:: the event to be tested
|
266
|
+
# return:: the mouse x-position
|
267
|
+
#
|
268
|
+
def self.getScreenX(evt)
|
269
|
+
`return #<evt>.screenX`
|
270
|
+
end
|
271
|
+
|
272
|
+
#
|
273
|
+
# Gets the mouse y-position on the user's display.
|
274
|
+
#
|
275
|
+
# evt:: the event to be tested
|
276
|
+
# return:: the mouse y-position
|
277
|
+
#
|
278
|
+
def self.getScreenY(evt)
|
279
|
+
`return #<evt>.screenY`
|
280
|
+
end
|
281
|
+
|
282
|
+
#
|
283
|
+
# Gets the velocity of the mouse wheel associated with the event along the
|
284
|
+
# Y axis.
|
285
|
+
#
|
286
|
+
# The velocity of the event is an artifical measurement for relative
|
287
|
+
# comparisons of wheel activity. It is affected by some non-browser
|
288
|
+
# factors, including choice of input hardware and mouse acceleration
|
289
|
+
# settings. The sign of the velocity measurement agrees with the screen
|
290
|
+
# coordinate system; negative values are towards the origin and positive
|
291
|
+
# values are away from the origin. Standard scrolling speed is approximately
|
292
|
+
# ten units per event.
|
293
|
+
#
|
294
|
+
# evt:: the event to be examined.
|
295
|
+
# return:: The velocity of the mouse wheel.
|
296
|
+
#
|
297
|
+
def self.getMouseWheelVelocityY(evt)
|
298
|
+
raise # FIXME
|
299
|
+
end
|
300
|
+
|
301
|
+
#-------------------------------------------------------------------
|
302
|
+
# Misc
|
303
|
+
#-------------------------------------------------------------------
|
304
|
+
|
305
|
+
#
|
306
|
+
# Returns the element that was the actual target of the given event.
|
307
|
+
#
|
308
|
+
# evt:: the event to be tested
|
309
|
+
# return:: the target element
|
310
|
+
#
|
311
|
+
def self.getTarget(evt)
|
312
|
+
`return #<evt>.target || #<nil>`
|
313
|
+
end
|
314
|
+
|
315
|
+
#
|
316
|
+
# Gets the element from which the mouse pointer was moved (only valid for
|
317
|
+
# +Event::ONMOUSEOVER+).
|
318
|
+
#
|
319
|
+
# evt:: the event to be tested
|
320
|
+
# return:: the element from which the mouse pointer was moved
|
321
|
+
#
|
322
|
+
def self.getFromElement(evt)
|
323
|
+
# Standard browsers use relatedTarget rather than fromElement.
|
324
|
+
`return #<evt>.relatedTarget || #<nil>`
|
325
|
+
end
|
326
|
+
|
327
|
+
#
|
328
|
+
# Gets the element to which the mouse pointer was moved (only valid for
|
329
|
+
# +Event::ONMOUSEOUT+).
|
330
|
+
#
|
331
|
+
# evt:: the event to be tested
|
332
|
+
# return:: the element to which the mouse pointer was moved
|
333
|
+
#
|
334
|
+
def self.getToElement(evt)
|
335
|
+
# Standard browsers use relatedTarget rather than toElement.
|
336
|
+
`return #<evt>.relatedTarget || #<nil>`
|
337
|
+
end
|
338
|
+
|
339
|
+
#
|
340
|
+
# Gets the enumerated type of this event (as defined in +Event+).
|
341
|
+
#
|
342
|
+
# evt:: the event to be tested
|
343
|
+
# return:: the event's enumerated type
|
344
|
+
#
|
345
|
+
def self.getType(evt) `
|
346
|
+
switch (#<evt>.type) {
|
347
|
+
case "blur": return 0x01000;
|
348
|
+
case "change": return 0x00400;
|
349
|
+
case "click": return 0x00001;
|
350
|
+
case "dblclick": return 0x00002;
|
351
|
+
case "focus": return 0x00800;
|
352
|
+
case "keydown": return 0x00080;
|
353
|
+
case "keypress": return 0x00100;
|
354
|
+
case "keyup": return 0x00200;
|
355
|
+
case "load": return 0x08000;
|
356
|
+
case "losecapture": return 0x02000;
|
357
|
+
case "mousedown": return 0x00004;
|
358
|
+
case "mousemove": return 0x00040;
|
359
|
+
case "mouseout": return 0x00020;
|
360
|
+
case "mouseover": return 0x00010;
|
361
|
+
case "mouseup": return 0x00008;
|
362
|
+
case "scroll": return 0x04000;
|
363
|
+
case "error": return 0x10000;
|
364
|
+
case "mousewheel": return 0x20000;
|
365
|
+
case "DOMMouseScroll": return 0x20000;
|
366
|
+
}`
|
367
|
+
end
|
368
|
+
|
369
|
+
#
|
370
|
+
# Gets the type of the given event as a string.
|
371
|
+
#
|
372
|
+
# evt:: the event to be tested
|
373
|
+
# return:: the event's type name
|
374
|
+
#
|
375
|
+
def self.getTypeString(evt)
|
376
|
+
`return #<evt>.type`
|
377
|
+
end
|
378
|
+
|
379
|
+
#
|
380
|
+
# Prevents the browser from taking its default action for the given event.
|
381
|
+
#
|
382
|
+
# evt:: the event whose default action is to be prevented
|
383
|
+
#
|
384
|
+
def self.preventDefault(evt)
|
385
|
+
`#<evt>.preventDefault(); return #<nil>`
|
386
|
+
end
|
387
|
+
|
388
|
+
#
|
389
|
+
# Returns a stringized version of the event. This string is for debugging
|
390
|
+
# purposes and will NOT be consistent on different browsers.
|
391
|
+
#
|
392
|
+
# evt:: the event to stringize
|
393
|
+
# return:: a string form of the event
|
394
|
+
#
|
395
|
+
def self.toString(evt)
|
396
|
+
`return #<evt>.toString()`
|
397
|
+
end
|
398
|
+
|
399
|
+
#-------------------------------------------------------------------
|
400
|
+
# Setup
|
401
|
+
#-------------------------------------------------------------------
|
402
|
+
|
403
|
+
#
|
404
|
+
# This method is called directly by native code when any event is fired.
|
405
|
+
#
|
406
|
+
# evt:: the handle to the event being fired.
|
407
|
+
# elem:: the handle to the element that received the event.
|
408
|
+
# listener:: the listener associated with the element that received the
|
409
|
+
# event.
|
410
|
+
#
|
411
|
+
def self.dispatch(evt, elem, listener)
|
412
|
+
listener.onBrowserEvent(evt) if listener
|
413
|
+
# FIXME
|
414
|
+
#UncaughtExceptionHandler handler = GWT.getUncaughtExceptionHandler();
|
415
|
+
#if (handler != null) {
|
416
|
+
# dispatchEventAndCatch(evt, elem, listener, handler);
|
417
|
+
#} else {
|
418
|
+
# dispatchEventImpl(evt, elem, listener);
|
419
|
+
#}
|
420
|
+
end
|
421
|
+
|
422
|
+
def self.__init() `
|
423
|
+
// assign event dispatcher
|
424
|
+
window.#<attr:dispatch> = function(evt) {
|
425
|
+
#<self>.#<m:dispatch>(#<nil>, evt, this, this.#<attr:listener> || #<nil>);
|
426
|
+
};`
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|