reflexion 0.1.13 → 0.1.19
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.
- checksums.yaml +4 -4
- data/.doc/ext/reflex/capture_event.cpp +4 -5
- data/.doc/ext/reflex/contact_event.cpp +4 -7
- data/.doc/ext/reflex/draw_event.cpp +3 -4
- data/.doc/ext/reflex/frame_event.cpp +7 -8
- data/.doc/ext/reflex/key_event.cpp +7 -8
- data/.doc/ext/reflex/motion_event.cpp +3 -5
- data/.doc/ext/reflex/pointer_event.cpp +23 -15
- data/.doc/ext/reflex/reflex.cpp +3 -1
- data/.doc/ext/reflex/scroll_event.cpp +8 -9
- data/.doc/ext/reflex/update_event.cpp +4 -5
- data/.doc/ext/reflex/wheel_event.cpp +5 -6
- data/LICENSE +21 -0
- data/VERSION +1 -1
- data/ext/reflex/capture_event.cpp +3 -4
- data/ext/reflex/contact_event.cpp +3 -6
- data/ext/reflex/draw_event.cpp +2 -3
- data/ext/reflex/frame_event.cpp +6 -7
- data/ext/reflex/key_event.cpp +6 -7
- data/ext/reflex/motion_event.cpp +2 -4
- data/ext/reflex/pointer_event.cpp +22 -14
- data/ext/reflex/reflex.cpp +3 -1
- data/ext/reflex/scroll_event.cpp +8 -9
- data/ext/reflex/update_event.cpp +3 -4
- data/ext/reflex/wheel_event.cpp +4 -5
- data/include/reflex/defs.h +0 -2
- data/include/reflex/event.h +15 -15
- data/include/reflex/exception.h +9 -3
- data/include/reflex/ruby/event.h +11 -11
- data/include/reflex/ruby/reflex.h +1 -0
- data/include/reflex/style.h +30 -4
- data/lib/reflex.rb +2 -1
- data/lib/reflex/camera.rb +13 -0
- data/lib/reflex/pointer_event.rb +4 -0
- data/reflex.gemspec +4 -4
- data/samples/camera.rb +45 -0
- data/samples/shapes.rb +16 -0
- data/src/event.cpp +7 -7
- data/src/ios/view_controller.h +4 -0
- data/src/ios/view_controller.mm +22 -34
- data/src/osx/native_window.mm +10 -26
- data/src/shape.cpp +4 -4
- data/src/style.cpp +4 -4
- data/src/timer.cpp +3 -6
- data/src/view.cpp +2 -2
- data/src/window.cpp +27 -0
- data/src/window.h +2 -0
- data/test/test_pointer_event.rb +79 -34
- metadata +16 -13
data/reflex.gemspec
CHANGED
@@ -28,10 +28,10 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.platform = Gem::Platform::RUBY
|
29
29
|
s.required_ruby_version = '~> 2'
|
30
30
|
|
31
|
-
s.add_runtime_dependency 'xot', '~> 0.1'
|
32
|
-
s.add_runtime_dependency 'rucy', '~> 0.1'
|
33
|
-
s.add_runtime_dependency 'beeps', '~> 0.1'
|
34
|
-
s.add_runtime_dependency 'rays', '~> 0.1'
|
31
|
+
s.add_runtime_dependency 'xot', '~> 0.1.19'
|
32
|
+
s.add_runtime_dependency 'rucy', '~> 0.1.18'
|
33
|
+
s.add_runtime_dependency 'beeps', '~> 0.1.18'
|
34
|
+
s.add_runtime_dependency 'rays', '~> 0.1.19'
|
35
35
|
|
36
36
|
s.files = `git ls-files`.split $/
|
37
37
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
data/samples/camera.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
%w[xot rays reflex]
|
5
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __FILE__}
|
6
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
7
|
+
|
8
|
+
require 'reflex'
|
9
|
+
|
10
|
+
|
11
|
+
class Win < Reflex::Window
|
12
|
+
def initialize ()
|
13
|
+
super title: "Camera Example", frame: [100, 100, 800, 600]
|
14
|
+
|
15
|
+
@w = 100
|
16
|
+
@h = 200
|
17
|
+
@resize_crop = Rays::Camera.new(@w, @h, resize: true, crop: true) {start}
|
18
|
+
@crop = Rays::Camera.new(@w, @h, resize: false, crop: true) {start}
|
19
|
+
@resize = Rays::Camera.new(@w, @h, resize: true, crop: false) {start}
|
20
|
+
@original = Rays::Camera.new(@w, @h, resize: false, crop: false) {start}
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_draw (e)
|
24
|
+
p = e.painter
|
25
|
+
|
26
|
+
p.image @resize_crop.image, @w * 0, 0 if @resize_crop.image
|
27
|
+
p.image @crop.image, @w * 1, 0 if @crop.image
|
28
|
+
p.image @resize.image, @w * 2, 0 if @resize.image
|
29
|
+
p.image @original.image, 0, @h if @original.image
|
30
|
+
|
31
|
+
p.text "#{e.fps.to_i} FPS", 10, 10
|
32
|
+
|
33
|
+
p.fill nil
|
34
|
+
p.stroke 1
|
35
|
+
p.rect 0, 0, @w, @h
|
36
|
+
end
|
37
|
+
|
38
|
+
def on_update (e)
|
39
|
+
redraw
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Reflex.start do
|
44
|
+
Win.new.show
|
45
|
+
end
|
data/samples/shapes.rb
CHANGED
@@ -47,6 +47,22 @@ Reflex::Window.new do
|
|
47
47
|
translate 100, 0
|
48
48
|
ellipse x, y, w, h, hole: 10, from: 200, to: 300
|
49
49
|
polygon Rays::Polygon.ellipse x, y2, w, h, hole: 10, from: 200, to: 300
|
50
|
+
|
51
|
+
translate 100, 0
|
52
|
+
curve x, y, x + w, y, x + w, y + h, x, y + h
|
53
|
+
polygon Rays::Polygon.curve x, y2, x + w, y2, x + w, y2 + h, x, y2 + h
|
54
|
+
|
55
|
+
translate 100, 0
|
56
|
+
curve x, y, x + w, y, x + w, y + h, x, y + h, loop: true
|
57
|
+
polygon Rays::Polygon.curve x, y2, x + w, y2, x + w, y2 + h, x, y2 + h, loop: true
|
58
|
+
|
59
|
+
translate 100, 0
|
60
|
+
bezier x, y, x + w, y, x + w, y + h, x, y + h
|
61
|
+
polygon Rays::Polygon.bezier x, y2, x + w, y2, x + w, y2 + h, x, y2 + h
|
62
|
+
|
63
|
+
translate 100, 0
|
64
|
+
bezier x, y, x + w, y, x + w, y + h, x, y + h, loop: true
|
65
|
+
polygon Rays::Polygon.bezier x, y2, x + w, y2, x + w, y2 + h, x, y2 + h, loop: true
|
50
66
|
end
|
51
67
|
|
52
68
|
translate 0, 200
|
data/src/event.cpp
CHANGED
@@ -28,12 +28,6 @@ namespace Reflex
|
|
28
28
|
}
|
29
29
|
|
30
30
|
|
31
|
-
MotionEvent::MotionEvent (const Point& gravity)
|
32
|
-
: gravity(gravity)
|
33
|
-
{
|
34
|
-
}
|
35
|
-
|
36
|
-
|
37
31
|
UpdateEvent::UpdateEvent (double now, float dt)
|
38
32
|
: now(now), dt(dt)
|
39
33
|
{
|
@@ -170,7 +164,7 @@ namespace Reflex
|
|
170
164
|
if (positions_)
|
171
165
|
{
|
172
166
|
for (size_t i = 0; i < size; ++i)
|
173
|
-
positions[i] = *(
|
167
|
+
positions[i] = *(Coord3*) &positions_[i];
|
174
168
|
}
|
175
169
|
}
|
176
170
|
|
@@ -302,4 +296,10 @@ namespace Reflex
|
|
302
296
|
}
|
303
297
|
|
304
298
|
|
299
|
+
MotionEvent::MotionEvent (const Point& gravity)
|
300
|
+
: gravity(gravity)
|
301
|
+
{
|
302
|
+
}
|
303
|
+
|
304
|
+
|
305
305
|
}// Reflex
|
data/src/ios/view_controller.h
CHANGED
data/src/ios/view_controller.mm
CHANGED
@@ -144,11 +144,15 @@ ReflexViewController_get_show_fun ()
|
|
144
144
|
}
|
145
145
|
|
146
146
|
- (void) dealloc
|
147
|
+
{
|
148
|
+
[self cleanup];
|
149
|
+
[super dealloc];
|
150
|
+
}
|
151
|
+
|
152
|
+
- (void) cleanup
|
147
153
|
{
|
148
154
|
[self cleanupReflexView];
|
149
155
|
[self unbind];
|
150
|
-
|
151
|
-
[super dealloc];
|
152
156
|
}
|
153
157
|
|
154
158
|
- (void) bind: (Reflex::Window*) window
|
@@ -160,7 +164,8 @@ ReflexViewController_get_show_fun ()
|
|
160
164
|
if (data.view_controller)
|
161
165
|
Reflex::invalid_state_error(__FILE__, __LINE__);
|
162
166
|
|
163
|
-
|
167
|
+
// ruby value references view controller weakly.
|
168
|
+
data.view_controller = self;
|
164
169
|
|
165
170
|
// Reflex::Window is not constructed completely,
|
166
171
|
// so can not call ClassWrapper::retain().
|
@@ -180,8 +185,6 @@ ReflexViewController_get_show_fun ()
|
|
180
185
|
ptr_for_rebind->Xot::template RefCountable<>::release();
|
181
186
|
ptr_for_rebind = NULL;
|
182
187
|
}
|
183
|
-
|
184
|
-
assert(pwindow && !ptr_for_rebind);
|
185
188
|
}
|
186
189
|
|
187
190
|
- (void) unbind
|
@@ -189,12 +192,7 @@ ReflexViewController_get_show_fun ()
|
|
189
192
|
[self rebind];
|
190
193
|
if (!pwindow) return;
|
191
194
|
|
192
|
-
|
193
|
-
if (data.view_controller)
|
194
|
-
{
|
195
|
-
[data.view_controller release];
|
196
|
-
data.view_controller = nil;
|
197
|
-
}
|
195
|
+
Window_get_data(pwindow).view_controller = nil;
|
198
196
|
|
199
197
|
pwindow->release();
|
200
198
|
pwindow = NULL;
|
@@ -211,7 +209,7 @@ ReflexViewController_get_show_fun ()
|
|
211
209
|
[super didReceiveMemoryWarning];
|
212
210
|
|
213
211
|
if ([self isViewLoaded] && !self.view.window)
|
214
|
-
[self
|
212
|
+
[self cleanup];
|
215
213
|
}
|
216
214
|
|
217
215
|
- (void) viewDidLoad
|
@@ -262,7 +260,7 @@ ReflexViewController_get_show_fun ()
|
|
262
260
|
|
263
261
|
EAGLContext* context = view.context;
|
264
262
|
if (context && context == [EAGLContext currentContext])
|
265
|
-
[EAGLContext setCurrentContext:
|
263
|
+
[EAGLContext setCurrentContext: (EAGLContext*) Rays::get_offscreen_context()];
|
266
264
|
|
267
265
|
[view removeFromSuperview];
|
268
266
|
|
@@ -272,7 +270,7 @@ ReflexViewController_get_show_fun ()
|
|
272
270
|
- (void) viewDidAppear: (BOOL) animated
|
273
271
|
{
|
274
272
|
[super viewDidAppear: animated];
|
275
|
-
[self startTimer
|
273
|
+
[self startTimer];
|
276
274
|
}
|
277
275
|
|
278
276
|
- (void) viewDidDisappear: (BOOL) animated
|
@@ -281,6 +279,11 @@ ReflexViewController_get_show_fun ()
|
|
281
279
|
[super viewDidDisappear: animated];
|
282
280
|
}
|
283
281
|
|
282
|
+
- (void) startTimer
|
283
|
+
{
|
284
|
+
[self startTimer: 60];
|
285
|
+
}
|
286
|
+
|
284
287
|
- (void) startTimer: (int) fps
|
285
288
|
{
|
286
289
|
[self stopTimer];
|
@@ -344,22 +347,7 @@ ReflexViewController_get_show_fun ()
|
|
344
347
|
win->self->prev_fps = fps;
|
345
348
|
|
346
349
|
Reflex::DrawEvent e(dt, fps);
|
347
|
-
|
348
|
-
e.painter = win->painter();
|
349
|
-
if (!e.painter)
|
350
|
-
Xot::invalid_state_error(__FILE__, __LINE__);
|
351
|
-
|
352
|
-
Rays::Bounds frame = win->frame();
|
353
|
-
e.bounds.reset(0, 0, frame.width, frame.height);
|
354
|
-
|
355
|
-
e.painter->begin();
|
356
|
-
e.painter->clear();
|
357
|
-
|
358
|
-
win->on_draw(&e);
|
359
|
-
if (!e.is_blocked())
|
360
|
-
Reflex::View_draw_tree(win->root(), e, 0, frame.move_to(0));
|
361
|
-
|
362
|
-
e.painter->end();
|
350
|
+
Window_call_draw_event(win, &e);
|
363
351
|
}
|
364
352
|
|
365
353
|
- (void) viewDidResize
|
@@ -399,7 +387,7 @@ ReflexViewController_get_show_fun ()
|
|
399
387
|
if (!win) return;
|
400
388
|
|
401
389
|
Reflex::NativePointerEvent e(
|
402
|
-
touches, event, self.
|
390
|
+
touches, event, self.reflexView, Reflex::PointerEvent::DOWN);
|
403
391
|
win->on_pointer(&e);
|
404
392
|
}
|
405
393
|
|
@@ -409,7 +397,7 @@ ReflexViewController_get_show_fun ()
|
|
409
397
|
if (!win) return;
|
410
398
|
|
411
399
|
Reflex::NativePointerEvent e(
|
412
|
-
touches, event, self.
|
400
|
+
touches, event, self.reflexView, Reflex::PointerEvent::UP);
|
413
401
|
win->on_pointer(&e);
|
414
402
|
}
|
415
403
|
|
@@ -419,7 +407,7 @@ ReflexViewController_get_show_fun ()
|
|
419
407
|
if (!win) return;
|
420
408
|
|
421
409
|
Reflex::NativePointerEvent e(
|
422
|
-
touches, event, self.
|
410
|
+
touches, event, self.reflexView, Reflex::PointerEvent::UP);
|
423
411
|
win->on_pointer(&e);
|
424
412
|
}
|
425
413
|
|
@@ -429,7 +417,7 @@ ReflexViewController_get_show_fun ()
|
|
429
417
|
if (!win) return;
|
430
418
|
|
431
419
|
Reflex::NativePointerEvent e(
|
432
|
-
touches, event, self.
|
420
|
+
touches, event, self.reflexView, Reflex::PointerEvent::MOVE);
|
433
421
|
win->on_pointer(&e);
|
434
422
|
}
|
435
423
|
|
data/src/osx/native_window.mm
CHANGED
@@ -43,7 +43,7 @@ static const NSUInteger WINDOW_STYLE_MASK =
|
|
43
43
|
|
44
44
|
[self setDelegate: self];
|
45
45
|
[self setupContentView];
|
46
|
-
[self startTimer
|
46
|
+
[self startTimer];
|
47
47
|
|
48
48
|
return self;
|
49
49
|
}
|
@@ -66,7 +66,8 @@ static const NSUInteger WINDOW_STYLE_MASK =
|
|
66
66
|
if (data.native)
|
67
67
|
Reflex::invalid_state_error(__FILE__, __LINE__);
|
68
68
|
|
69
|
-
|
69
|
+
// ruby value references native window weakly.
|
70
|
+
data.native = self;
|
70
71
|
|
71
72
|
// Reflex::Window is not constructed completely,
|
72
73
|
// so can not call ClassWrapper::retain().
|
@@ -86,8 +87,6 @@ static const NSUInteger WINDOW_STYLE_MASK =
|
|
86
87
|
ptr_for_rebind->Xot::template RefCountable<>::release();
|
87
88
|
ptr_for_rebind = NULL;
|
88
89
|
}
|
89
|
-
|
90
|
-
assert(pwindow && !ptr_for_rebind);
|
91
90
|
}
|
92
91
|
|
93
92
|
- (void) unbind
|
@@ -95,12 +94,7 @@ static const NSUInteger WINDOW_STYLE_MASK =
|
|
95
94
|
[self rebind];
|
96
95
|
if (!pwindow) return;
|
97
96
|
|
98
|
-
|
99
|
-
if (data.native)
|
100
|
-
{
|
101
|
-
[data.native release];
|
102
|
-
data.native = nil;
|
103
|
-
}
|
97
|
+
Window_get_data(pwindow).native = nil;
|
104
98
|
|
105
99
|
pwindow->release();
|
106
100
|
pwindow = NULL;
|
@@ -120,6 +114,11 @@ static const NSUInteger WINDOW_STYLE_MASK =
|
|
120
114
|
[self setContentView: view];
|
121
115
|
}
|
122
116
|
|
117
|
+
- (void) startTimer
|
118
|
+
{
|
119
|
+
[self startTimer: 60];
|
120
|
+
}
|
121
|
+
|
123
122
|
- (void) startTimer: (int) fps
|
124
123
|
{
|
125
124
|
[self stopTimer];
|
@@ -183,22 +182,7 @@ static const NSUInteger WINDOW_STYLE_MASK =
|
|
183
182
|
win->self->prev_fps = fps;
|
184
183
|
|
185
184
|
Reflex::DrawEvent e(dt, fps);
|
186
|
-
|
187
|
-
e.painter = win->painter();
|
188
|
-
if (!e.painter)
|
189
|
-
Xot::invalid_state_error(__FILE__, __LINE__);
|
190
|
-
|
191
|
-
Rays::Bounds frame = win->frame();
|
192
|
-
e.bounds.reset(0, 0, frame.width, frame.height);
|
193
|
-
|
194
|
-
e.painter->begin();
|
195
|
-
e.painter->clear();
|
196
|
-
|
197
|
-
win->on_draw(&e);
|
198
|
-
if (!e.is_blocked())
|
199
|
-
Reflex::View_draw_tree(win->root(), e, 0, frame.move_to(0));
|
200
|
-
|
201
|
-
e.painter->end();
|
185
|
+
Window_call_draw_event(win, &e);
|
202
186
|
}
|
203
187
|
|
204
188
|
- (BOOL) windowShouldClose: (id) sender
|
data/src/shape.cpp
CHANGED
@@ -52,8 +52,8 @@ namespace Reflex
|
|
52
52
|
if (!style) return NULL;
|
53
53
|
|
54
54
|
return is_default_shape(shape)
|
55
|
-
?
|
56
|
-
:
|
55
|
+
? &style->background_fill()
|
56
|
+
: &style->foreground_fill();
|
57
57
|
}
|
58
58
|
|
59
59
|
static coord
|
@@ -65,8 +65,8 @@ namespace Reflex
|
|
65
65
|
if (!style) return 0;
|
66
66
|
|
67
67
|
return is_default_shape(shape)
|
68
|
-
?
|
69
|
-
:
|
68
|
+
? style->background_stroke_width()
|
69
|
+
: style->foreground_stroke_width();
|
70
70
|
}
|
71
71
|
|
72
72
|
static bool
|
data/src/style.cpp
CHANGED
@@ -201,7 +201,7 @@ namespace Reflex
|
|
201
201
|
void
|
202
202
|
StyleLength::reset (Type type, Value value)
|
203
203
|
{
|
204
|
-
if (type < NONE ||
|
204
|
+
if (type < NONE || TYPE_MAX <= type)
|
205
205
|
argument_error(__FILE__, __LINE__);
|
206
206
|
|
207
207
|
if (type == FIT && value != 1)
|
@@ -225,7 +225,7 @@ namespace Reflex
|
|
225
225
|
|
226
226
|
StyleLength::operator bool () const
|
227
227
|
{
|
228
|
-
return NONE < self->type && self->type <
|
228
|
+
return NONE < self->type && self->type < TYPE_MAX;
|
229
229
|
}
|
230
230
|
|
231
231
|
bool
|
@@ -615,8 +615,8 @@ namespace Reflex
|
|
615
615
|
Style::set_flow (Flow main, Flow sub)
|
616
616
|
{
|
617
617
|
if (
|
618
|
-
main < FLOW_NONE ||
|
619
|
-
sub < FLOW_NONE ||
|
618
|
+
main < FLOW_NONE || FLOW_MAX <= main ||
|
619
|
+
sub < FLOW_NONE || FLOW_MAX <= sub ||
|
620
620
|
(main != FLOW_NONE && (get_flow_dir(main) == get_flow_dir(sub))) ||
|
621
621
|
(main == FLOW_NONE && sub != FLOW_NONE))
|
622
622
|
{
|
data/src/timer.cpp
CHANGED
@@ -162,8 +162,7 @@ namespace Reflex
|
|
162
162
|
{
|
163
163
|
assert(timer && *timer);
|
164
164
|
|
165
|
-
|
166
|
-
for (List::iterator it = timers.begin(); it != end; ++it)
|
165
|
+
for (auto it = timers.begin(), end = timers.end(); it != end; ++it)
|
167
166
|
{
|
168
167
|
if (timer->self->next_time < (*it)->self->next_time)
|
169
168
|
{
|
@@ -219,8 +218,7 @@ namespace Reflex
|
|
219
218
|
if (!timer)
|
220
219
|
argument_error(__FILE__, __LINE__);
|
221
220
|
|
222
|
-
|
223
|
-
for (List::iterator it = timers.begin(); it != end; ++it)
|
221
|
+
for (auto it = timers.begin(), end = timers.end(); it != end; ++it)
|
224
222
|
{
|
225
223
|
if (timer->id() == (*it)->id())
|
226
224
|
timers.erase(it);
|
@@ -261,8 +259,7 @@ namespace Reflex
|
|
261
259
|
void
|
262
260
|
Timers::fire (double now)
|
263
261
|
{
|
264
|
-
|
265
|
-
for (List::iterator it = timers.begin(); it != end; ++it)
|
262
|
+
for (auto it = timers.begin(), end = timers.end(); it != end; ++it)
|
266
263
|
{
|
267
264
|
Timer* timer = it->get();
|
268
265
|
if (!is_time_to_fire(timer, now))
|
data/src/view.cpp
CHANGED
@@ -189,8 +189,8 @@ namespace Reflex
|
|
189
189
|
{
|
190
190
|
World* world = parent_world();
|
191
191
|
Body* b = world
|
192
|
-
?
|
193
|
-
:
|
192
|
+
? new Body(world, frame.position(), angle)
|
193
|
+
: Body_create_temporary();
|
194
194
|
assert(b);
|
195
195
|
|
196
196
|
pbody.reset(b);
|
data/src/window.cpp
CHANGED
@@ -36,6 +36,33 @@ namespace Reflex
|
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
39
|
+
void
|
40
|
+
Window_call_draw_event (Window* window, DrawEvent* event)
|
41
|
+
{
|
42
|
+
if (!window || !event)
|
43
|
+
argument_error(__FILE__, __LINE__);
|
44
|
+
|
45
|
+
Painter* painter = window->painter();
|
46
|
+
if (!painter)
|
47
|
+
Xot::invalid_state_error(__FILE__, __LINE__);
|
48
|
+
|
49
|
+
Rays::Bounds frame = window->frame();
|
50
|
+
|
51
|
+
event->painter = painter;
|
52
|
+
event->bounds.reset(0, 0, frame.width, frame.height);
|
53
|
+
|
54
|
+
painter->begin();
|
55
|
+
painter->push_state();
|
56
|
+
painter->clear();
|
57
|
+
|
58
|
+
window->on_draw(event);
|
59
|
+
if (!event->is_blocked())
|
60
|
+
Reflex::View_draw_tree(window->root(), *event, 0, frame.move_to(0));
|
61
|
+
|
62
|
+
painter->pop_state();
|
63
|
+
painter->end();
|
64
|
+
}
|
65
|
+
|
39
66
|
namespace global
|
40
67
|
{
|
41
68
|
|