motion-xray 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +28 -0
- data/README.md +426 -0
- data/Rakefile +11 -0
- data/app/app_delegate.rb +44 -0
- data/lib/motion-xray.rb +37 -0
- data/lib/motion-xray/plugins/accessibility_plugin.rb +129 -0
- data/lib/motion-xray/plugins/log_plugin.rb +301 -0
- data/lib/motion-xray/plugins/save_ui_plugin.rb +142 -0
- data/lib/motion-xray/plugins/ui_plugin.rb +41 -0
- data/lib/motion-xray/version.rb +5 -0
- data/lib/motion-xray/views/xray_color_swatch.rb +234 -0
- data/lib/motion-xray/views/xray_dpad.rb +142 -0
- data/lib/motion-xray/views/xray_gradient_view.rb +23 -0
- data/lib/motion-xray/views/xray_headers.rb +101 -0
- data/lib/motion-xray/views/xray_lock_button.rb +50 -0
- data/lib/motion-xray/views/xray_scroll_view.rb +12 -0
- data/lib/motion-xray/views/xray_toolbar.rb +173 -0
- data/lib/motion-xray/views/xray_window.rb +13 -0
- data/lib/motion-xray/xray.rb +56 -0
- data/lib/motion-xray/xray_constants.rb +5 -0
- data/lib/motion-xray/xray_dummy.rb +8 -0
- data/lib/motion-xray/xray_editors.rb +62 -0
- data/lib/motion-xray/xray_ext.rb +125 -0
- data/lib/motion-xray/xray_plugin.rb +40 -0
- data/lib/motion-xray/xray_typewriter.rb +217 -0
- data/lib/motion-xray/xray_ui.rb +723 -0
- data/lib/motion-xray/z_editors/xray_boolean_editor.rb +24 -0
- data/lib/motion-xray/z_editors/xray_color_editor.rb +119 -0
- data/lib/motion-xray/z_editors/xray_frame_editor.rb +108 -0
- data/lib/motion-xray/z_editors/xray_image_editor.rb +78 -0
- data/lib/motion-xray/z_editors/xray_text_editor.rb +94 -0
- data/lib/resources/xray_button_bg@2x.png +0 -0
- data/lib/resources/xray_choose_button@2x.png +0 -0
- data/lib/resources/xray_clear_button@2x.png +0 -0
- data/lib/resources/xray_detail_button@2x.png +0 -0
- data/lib/resources/xray_dpad@2x.png +0 -0
- data/lib/resources/xray_dpad_center@2x.png +0 -0
- data/lib/resources/xray_dpad_down@2x.png +0 -0
- data/lib/resources/xray_dpad_left@2x.png +0 -0
- data/lib/resources/xray_dpad_right@2x.png +0 -0
- data/lib/resources/xray_dpad_up@2x.png +0 -0
- data/lib/resources/xray_drawer_left@2x.png +0 -0
- data/lib/resources/xray_drawer_right@2x.png +0 -0
- data/lib/resources/xray_edit_button@2x.png +0 -0
- data/lib/resources/xray_email_button@2x.png +0 -0
- data/lib/resources/xray_lock_button_horizontal@2x.png +0 -0
- data/lib/resources/xray_lock_button_locked@2x.png +0 -0
- data/lib/resources/xray_lock_button_unlocked@2x.png +0 -0
- data/lib/resources/xray_lock_button_vertical@2x.png +0 -0
- data/motion-xray.gemspec +40 -0
- data/resources/Default-568h@2x.png +0 -0
- data/spec/xray_view_spec.rb +43 -0
- data/vendor/Podfile.lock +11 -0
- metadata +177 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Motion ; module Xray
|
2
|
+
|
3
|
+
class BooleanEditor < PropertyEditor
|
4
|
+
|
5
|
+
def edit_view(container_width)
|
6
|
+
return UIView.alloc.initWithFrame([[0, 0], [container_width, 27]]).tap do |view|
|
7
|
+
view << UILabel.alloc.initWithFrame([[0, 4.5], view.bounds.size]).tap do |lbl|
|
8
|
+
lbl.backgroundColor = :clear.uicolor
|
9
|
+
lbl.text = "#{@property}?"
|
10
|
+
lbl.font = :small.uifont
|
11
|
+
end
|
12
|
+
view << UISwitch.alloc.init.tap do |switch|
|
13
|
+
switch.frame = switch.frame.x(view.bounds.max_x - switch.frame.width)
|
14
|
+
switch.on = !!get_value
|
15
|
+
switch.on(:change) {
|
16
|
+
set_value(switch.on?)
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Motion ; module Xray
|
2
|
+
|
3
|
+
class ColorEditor < PropertyEditor
|
4
|
+
ColorEditorMargin = 20
|
5
|
+
|
6
|
+
def edit_view(container_width)
|
7
|
+
canvas_bounds = Xray.ui.bottom_half.frame
|
8
|
+
@color_editor_modal = UIView.alloc.initWithFrame(Xray.window.bounds).tap do |color_editor_modal|
|
9
|
+
close_editor_control = UIControl.alloc.initWithFrame(color_editor_modal.bounds)
|
10
|
+
close_editor_control.on :touch do
|
11
|
+
# touching outside
|
12
|
+
self.close_color_editor
|
13
|
+
end
|
14
|
+
color_editor_modal << close_editor_control
|
15
|
+
|
16
|
+
toolbar = XrayToolbar.alloc.initWithFrame(canvas_bounds.shrink(ColorEditorMargin).height(25).up(25))
|
17
|
+
toolbar.layer.cornerRadius = 3
|
18
|
+
color_editor_modal << toolbar
|
19
|
+
background = UIView.alloc.initWithFrame(canvas_bounds.shrink(ColorEditorMargin)).tap do |background|
|
20
|
+
background.layer.cornerRadius = 5
|
21
|
+
background.layer.borderWidth = 1
|
22
|
+
background.layer.borderColor = :dimgray.uicolor.cgcolor
|
23
|
+
background.backgroundColor = :black.uicolor
|
24
|
+
end
|
25
|
+
color_editor_modal << background
|
26
|
+
|
27
|
+
@color_names = UIScrollView.alloc.initWithFrame(background.bounds.shrink(10)).tap do |scroll|
|
28
|
+
typewriter = XrayTypewriterView.alloc.initWithFrame([[0, 0], scroll.frame.size])
|
29
|
+
typewriter.centered = true
|
30
|
+
typewriter.scroll_view = scroll
|
31
|
+
typewriter.spacing = [2, 2]
|
32
|
+
typewriter.margin = [2, 2, 2, 2]
|
33
|
+
typewriter.backgroundColor = :black.uicolor
|
34
|
+
Symbol.css_colors.each do |css_name, color|
|
35
|
+
button = UIButton.rounded
|
36
|
+
button.tintColor = color.uicolor
|
37
|
+
button.setTitle(css_name, forState: :normal.uicontrolstate)
|
38
|
+
button.setTitleColor(color.uicolor, forState: :normal.uicontrolstate)
|
39
|
+
button.sizeToFit
|
40
|
+
button.on :touch {
|
41
|
+
color = css_name.uicolor
|
42
|
+
color_did_change(color)
|
43
|
+
@color_sliders.color = color
|
44
|
+
}
|
45
|
+
typewriter << button
|
46
|
+
end
|
47
|
+
scroll << typewriter
|
48
|
+
end
|
49
|
+
|
50
|
+
@color_sliders = XrayColorSliders.alloc.initWithFrame(background.bounds.shrink(10))
|
51
|
+
@color_sliders.on :change {
|
52
|
+
color_did_change(@color_sliders.color)
|
53
|
+
}
|
54
|
+
|
55
|
+
toolbar.canvas = background
|
56
|
+
toolbar.add('RGB', @color_sliders)
|
57
|
+
toolbar.add('Named', @color_names)
|
58
|
+
end
|
59
|
+
@color_editor_modal.frame = @color_editor_modal.frame.right(Xray.app_bounds.width)
|
60
|
+
@color_editor_modal.fade_out
|
61
|
+
|
62
|
+
return UIView.alloc.initWithFrame([[0, 0], [container_width, 34]]).tap do |view|
|
63
|
+
color_size = CGSize.new(50, 24)
|
64
|
+
@color_picker = XrayColorSwatch.alloc.initWithFrame([[4, 4], color_size])
|
65
|
+
@color_picker.color = get_value
|
66
|
+
view << @color_picker
|
67
|
+
|
68
|
+
@color_picker.on :touch do
|
69
|
+
open_color_editor
|
70
|
+
end
|
71
|
+
|
72
|
+
label_x = color_size.width + 8
|
73
|
+
@label_view = UILabel.new.tap do |lbl|
|
74
|
+
lbl.frame = [[label_x, 5], [container_width - label_x, 18]]
|
75
|
+
lbl.font = :small.uifont
|
76
|
+
lbl.backgroundColor = :clear.uicolor
|
77
|
+
lbl.numberOfLines = 1
|
78
|
+
end
|
79
|
+
view << @label_view
|
80
|
+
update_views
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def open_color_editor
|
85
|
+
@color_picker.userInteractionEnabled = false
|
86
|
+
# move it off screen before sliding it in
|
87
|
+
Xray.window << @color_editor_modal
|
88
|
+
@color_sliders.color = get_value || :clear.uicolor
|
89
|
+
@color_editor_modal.fade_in
|
90
|
+
@color_editor_modal.slide(:left) {
|
91
|
+
@color_picker.userInteractionEnabled = true
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def close_color_editor
|
96
|
+
@color_picker.userInteractionEnabled = false
|
97
|
+
@color_editor_modal.fade_out
|
98
|
+
@color_editor_modal.slide(:left) {
|
99
|
+
@color_editor_modal.removeFromSuperview
|
100
|
+
# move it off screen, ready to move back in
|
101
|
+
@color_editor_modal.frame = @color_editor_modal.frame.x(Xray.app_bounds.width)
|
102
|
+
@color_picker.userInteractionEnabled = true
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def update_views
|
107
|
+
color = get_value
|
108
|
+
@color_picker.color = color
|
109
|
+
@label_view.text = "#{@property}: #{color.inspect}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def color_did_change(color)
|
113
|
+
set_value(color)
|
114
|
+
update_views
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Motion ; module Xray
|
2
|
+
|
3
|
+
class FrameEditor < PropertyEditor
|
4
|
+
|
5
|
+
def edit_view(container_width)
|
6
|
+
return UIView.alloc.initWithFrame([[0, 0], [container_width, 80]]).tap do |view|
|
7
|
+
frame_view = UIView.alloc.initWithFrame([[4, 4], [92, 72]])
|
8
|
+
frame_view.clipsToBounds = true
|
9
|
+
frame_view.backgroundColor = :lightgray.uicolor
|
10
|
+
frame_view.layer.borderWidth = 1
|
11
|
+
frame_view.layer.borderColor = :gray.uicolor.cgcolor
|
12
|
+
frame_view.layer.cornerRadius = 5
|
13
|
+
view << frame_view
|
14
|
+
|
15
|
+
labels_view = UIView.alloc.initWithFrame([[3, 0], [24, frame_view.bounds.height]])
|
16
|
+
label = UILabel.new
|
17
|
+
label.frame = [[4, 0], [18, 72]]
|
18
|
+
label.text = "X:\nY:\nW:\nH:"
|
19
|
+
label.textAlignment = :right.uitextalignment
|
20
|
+
label.font = :small.uifont
|
21
|
+
label.backgroundColor = :clear.uicolor
|
22
|
+
label.numberOfLines = 4
|
23
|
+
labels_view << label
|
24
|
+
frame_view << labels_view
|
25
|
+
|
26
|
+
values_view = UIView.alloc.initWithFrame([[labels_view.frame.max_x, 0], [65, frame_view.bounds.height]])
|
27
|
+
values_view.backgroundColor = :white.uicolor
|
28
|
+
values_view.layer.borderWidth = 1
|
29
|
+
values_view.layer.borderColor = :gray.uicolor
|
30
|
+
@frame_label = UILabel.new
|
31
|
+
@frame_label.frame = [[8, 0], [52, 72]]
|
32
|
+
@frame_label.font = :small.uifont
|
33
|
+
@frame_label.backgroundColor = :clear.uicolor
|
34
|
+
@frame_label.numberOfLines = 0
|
35
|
+
values_view << @frame_label
|
36
|
+
|
37
|
+
update_frame
|
38
|
+
frame_view << values_view
|
39
|
+
|
40
|
+
origin_dpad = XrayDpad.alloc.initWithFrame([[100, 4], [72, 72]])
|
41
|
+
origin_dpad.add_listener(self, :change_origin)
|
42
|
+
view << origin_dpad
|
43
|
+
|
44
|
+
size_dpad = XrayDpad.alloc.initWithFrame([[176, 4], [72, 72]])
|
45
|
+
size_dpad.add_listener(self, :change_size)
|
46
|
+
view << size_dpad
|
47
|
+
|
48
|
+
@locked_button = XrayLockButton.alloc.init
|
49
|
+
@locked_button.frame = @locked_button.frame.x(252).y(27)
|
50
|
+
view << @locked_button
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_frame
|
55
|
+
frame = get_value
|
56
|
+
@frame_label.text = "#{frame.origin.x}\n" +
|
57
|
+
"#{frame.origin.y}\n" +
|
58
|
+
"#{frame.size.width}\n" +
|
59
|
+
"#{frame.size.height}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def change_origin(delta)
|
63
|
+
if @locked_button.lock_state == XrayLockButton::LockedState
|
64
|
+
return
|
65
|
+
end
|
66
|
+
|
67
|
+
if @locked_button.lock_state == XrayLockButton::LockedHorizontalState
|
68
|
+
delta.y = 0
|
69
|
+
end
|
70
|
+
if @locked_button.lock_state == XrayLockButton::LockedVerticalState
|
71
|
+
delta.x = 0
|
72
|
+
end
|
73
|
+
|
74
|
+
frame = get_value
|
75
|
+
frame.origin.x += delta.x
|
76
|
+
frame.origin.y += delta.y
|
77
|
+
set_value(frame)
|
78
|
+
|
79
|
+
update_frame
|
80
|
+
end
|
81
|
+
|
82
|
+
def change_size(delta)
|
83
|
+
if @locked_button.lock_state == XrayLockButton::LockedState
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
if @locked_button.lock_state == XrayLockButton::LockedHorizontalState
|
88
|
+
delta.y = 0
|
89
|
+
end
|
90
|
+
if @locked_button.lock_state == XrayLockButton::LockedVerticalState
|
91
|
+
delta.x = 0
|
92
|
+
end
|
93
|
+
|
94
|
+
frame = get_value
|
95
|
+
frame.size.width += delta.x
|
96
|
+
frame.size.height += delta.y
|
97
|
+
set_value(frame)
|
98
|
+
|
99
|
+
update_frame
|
100
|
+
end
|
101
|
+
|
102
|
+
def did_change?
|
103
|
+
! CGRectEqualToRect(@original, @target.send(@property))
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Motion ; module Xray
|
2
|
+
|
3
|
+
class ImageEditor < PropertyEditor
|
4
|
+
|
5
|
+
def edit_view(container_width)
|
6
|
+
canvas_bounds = Xray.ui.bottom_half.frame
|
7
|
+
@editor_margin = 20
|
8
|
+
@editor_modal = UIView.alloc.initWithFrame(Xray.window.bounds).tap do |editor_modal|
|
9
|
+
close_editor_control = UIControl.alloc.initWithFrame(editor_modal.bounds)
|
10
|
+
close_editor_control.on :touch do
|
11
|
+
# touching outside
|
12
|
+
self.close_editor
|
13
|
+
end
|
14
|
+
editor_modal << close_editor_control
|
15
|
+
|
16
|
+
editor_modal << UIView.alloc.initWithFrame(canvas_bounds.shrink(@editor_margin)).tap do |background|
|
17
|
+
background.layer.cornerRadius = 5
|
18
|
+
background.layer.borderWidth = 1
|
19
|
+
background.layer.borderColor = :dimgray.uicolor.cgcolor
|
20
|
+
background.backgroundColor = :black.uicolor
|
21
|
+
|
22
|
+
@image_picker = ImagePicker.alloc.initWithFrame(background.bounds.shrink(10))
|
23
|
+
background << @image_picker
|
24
|
+
@image_picker.on :change {
|
25
|
+
image_did_change(@image_picker.image)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@editor_modal.frame = @editor_modal.frame.right(Xray.app_bounds.width)
|
30
|
+
@editor_modal.fade_out
|
31
|
+
|
32
|
+
return UIView.alloc.initWithFrame([[0, 0], [container_width, 34]]).tap do |view|
|
33
|
+
image_size = CGSize.new(50, 24)
|
34
|
+
@image_thumbnail = XrayColorSwatch.alloc.initWithFrame([[4, 4], image_size])
|
35
|
+
@image_thumbnail.image = get_value
|
36
|
+
view << @image_thumbnail
|
37
|
+
|
38
|
+
@image_thumbnail.on :touch do
|
39
|
+
open_editor
|
40
|
+
end
|
41
|
+
|
42
|
+
label_x = image_size.width + 8
|
43
|
+
label_view = UILabel.new
|
44
|
+
label_view.frame = [[label_x, 5], [container_width - label_x, 18]]
|
45
|
+
label_view.text = @property.to_s
|
46
|
+
label_view.font = :small.uifont
|
47
|
+
label_view.backgroundColor = :clear.uicolor
|
48
|
+
label_view.numberOfLines = 1
|
49
|
+
view << label_view
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def open_editor
|
54
|
+
@image_thumbnail.userInteractionEnabled = false
|
55
|
+
# move it off screen before sliding it in
|
56
|
+
Xray.window << @editor_modal
|
57
|
+
@image_picker.image = get_value
|
58
|
+
@editor_modal.fade_in
|
59
|
+
@editor_modal.slide(:left) {
|
60
|
+
@image_thumbnail.userInteractionEnabled = true
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def close_editor
|
65
|
+
@image_thumbnail.userInteractionEnabled = false
|
66
|
+
@editor_modal.fade_out
|
67
|
+
@editor_modal.slide(:left) {
|
68
|
+
@editor_modal.removeFromSuperview
|
69
|
+
# move it off screen, ready to move back in
|
70
|
+
@editor_modal.frame = @editor_modal.frame.x(Xray.app_bounds.width)
|
71
|
+
@image_thumbnail.userInteractionEnabled = true
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Motion ; module Xray
|
2
|
+
|
3
|
+
class TextEditor < PropertyEditor
|
4
|
+
|
5
|
+
def edit_view(container_width)
|
6
|
+
canvas_bounds = CGRect.new([0, 0], [Xray.ui.full_screen_width, Xray.ui.half_screen_height])
|
7
|
+
@text_editor_margin = 20
|
8
|
+
@text_editor_modal = UIView.alloc.initWithFrame(Xray.window.bounds).tap do |text_editor_modal|
|
9
|
+
text_editor_modal.backgroundColor = :black.uicolor(0.5)
|
10
|
+
|
11
|
+
close_editor_control = UIControl.alloc.initWithFrame(text_editor_modal.bounds)
|
12
|
+
close_editor_control.on :touch do
|
13
|
+
# touching outside
|
14
|
+
self.close_text_editor
|
15
|
+
end
|
16
|
+
text_editor_modal << close_editor_control
|
17
|
+
|
18
|
+
text_editor_modal << UIView.alloc.initWithFrame(canvas_bounds.shrink(@text_editor_margin)).tap do |background|
|
19
|
+
background.layer.cornerRadius = 5
|
20
|
+
background.layer.borderWidth = 1
|
21
|
+
background.layer.borderColor = :dimgray.uicolor.cgcolor
|
22
|
+
background.backgroundColor = :black.uicolor
|
23
|
+
|
24
|
+
@text_editor = UITextView.alloc.initWithFrame(background.bounds.shrink(10))
|
25
|
+
background << @text_editor
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@text_editor_modal.frame = @text_editor_modal.frame.right(Xray.app_bounds.width)
|
29
|
+
@text_editor_modal.fade_out
|
30
|
+
|
31
|
+
return UIView.alloc.initWithFrame([[0, 0], [container_width, 77]]).tap do |view|
|
32
|
+
label_view = UILabel.new
|
33
|
+
label_view.frame = [[4, 5], [container_width - 8, 18]]
|
34
|
+
label_view.text = @property.to_s
|
35
|
+
label_view.font = :small.uifont
|
36
|
+
label_view.backgroundColor = :clear.uicolor
|
37
|
+
label_view.numberOfLines = 1
|
38
|
+
view << label_view
|
39
|
+
|
40
|
+
@open_text_button = UIButton.custom.tap do |button|
|
41
|
+
button.setImage('xray_edit_button'.uiimage, forState: :normal.uicontrolstate)
|
42
|
+
button.frame = view.bounds
|
43
|
+
button.sizeToFit
|
44
|
+
button.frame = button.frame.x(view.bounds.top_right.x - button.frame.width)
|
45
|
+
button.on :touch {
|
46
|
+
open_text_editor
|
47
|
+
}
|
48
|
+
end
|
49
|
+
view << @open_text_button
|
50
|
+
|
51
|
+
@text_view = UITextView.alloc.initWithFrame([[4, 23], [container_width, 54]]).tap do |text_view|
|
52
|
+
text_view.backgroundColor = :white.uicolor
|
53
|
+
text_view.editable = false
|
54
|
+
text_view.font = :small.uifont
|
55
|
+
text_view.layer.borderWidth = 1
|
56
|
+
text_view.layer.borderColor = :black.uicolor.cgcolor
|
57
|
+
end
|
58
|
+
view << @text_view
|
59
|
+
update_text
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_text
|
65
|
+
@text_view.text = get_value
|
66
|
+
end
|
67
|
+
|
68
|
+
def open_text_editor
|
69
|
+
# move it off screen before sliding it in
|
70
|
+
@text_editor.text = get_value
|
71
|
+
Xray.window << @text_editor_modal
|
72
|
+
@text_editor.becomeFirstResponder
|
73
|
+
@text_editor_modal.fade_in
|
74
|
+
@text_editor_modal.slide(:left) {
|
75
|
+
@open_text_button.userInteractionEnabled = true
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def close_text_editor
|
80
|
+
@text_editor.resignFirstResponder
|
81
|
+
@text_editor_modal.fade_out
|
82
|
+
@text_editor_modal.slide(:left) {
|
83
|
+
@text_editor_modal.removeFromSuperview
|
84
|
+
# move it off screen, ready to move back in
|
85
|
+
@text_editor_modal.frame = @text_editor_modal.frame.x(Xray.app_bounds.width)
|
86
|
+
@open_text_button.userInteractionEnabled = true
|
87
|
+
set_value(@text_editor.text)
|
88
|
+
update_text
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|