galakei 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +3 -3
- data/galakei.gemspec +1 -1
- data/lib/galakei/email.rb +5 -10
- data/lib/galakei/emoji_table.rb +54 -45
- data/lib/galakei/filter/recode.rb +1 -0
- data/lib/galakei/version.rb +1 -1
- data/spec/acceptance/emoji_table_spec.rb +14 -0
- data/spec/galakei/email_spec.rb +2 -7
- metadata +58 -95
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
galakei (0.9.
|
5
|
-
actionpack (
|
4
|
+
galakei (0.9.0)
|
5
|
+
actionpack (~> 3.0.3)
|
6
6
|
css_parser
|
7
7
|
nokogiri
|
8
8
|
rack (>= 1.2.1)
|
@@ -107,7 +107,7 @@ GEM
|
|
107
107
|
rspec (~> 2.5.0)
|
108
108
|
rubyzip (0.9.4)
|
109
109
|
sanitize (2.0.3)
|
110
|
-
nokogiri (
|
110
|
+
nokogiri (>= 1.4.4, < 1.6)
|
111
111
|
selenium-webdriver (0.1.3)
|
112
112
|
childprocess (~> 0.1.5)
|
113
113
|
ffi (~> 0.6.3)
|
data/galakei.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.require_path = 'lib'
|
16
16
|
s.rubyforge_project = "galakei"
|
17
17
|
|
18
|
-
s.add_dependency 'actionpack', '
|
18
|
+
s.add_dependency 'actionpack', '~> 3.0.3'
|
19
19
|
s.add_dependency 'rack', '>= 1.2.1'
|
20
20
|
s.add_dependency 'css_parser'
|
21
21
|
s.add_dependency 'nokogiri'
|
data/lib/galakei/email.rb
CHANGED
@@ -10,14 +10,9 @@ module Galakei::Email
|
|
10
10
|
/^.+@emnet\.ne\.jp$/,
|
11
11
|
/^.+@docomo\.ne\.jp$/ ]
|
12
12
|
|
13
|
-
SANITIZE_OPTIONS = {
|
14
|
-
:elements => %w{
|
15
|
-
:attributes => {'a' => ['href'],
|
16
|
-
'font' => ['size','color'],
|
17
|
-
'marquee' => ['behaviour'],
|
18
|
-
'hr' => ['color'],
|
19
|
-
'div' => ['align'],
|
20
|
-
},
|
13
|
+
SANITIZE_OPTIONS = {
|
14
|
+
:elements => %w{br a div hr},
|
15
|
+
:attributes => {'a' => ['href'] },
|
21
16
|
:protocols => {'a' => {'href' => ['http', 'https', 'mailto']}},
|
22
17
|
:whitespace_elements => []
|
23
18
|
}
|
@@ -34,9 +29,9 @@ module Galakei::Email
|
|
34
29
|
node.name = "div"
|
35
30
|
node.after("<br />")
|
36
31
|
end
|
37
|
-
|
32
|
+
|
38
33
|
res = "<html><head>"
|
39
|
-
res << "<meta http-equiv=\"Content-type\" content=\"text/html;charset=#{
|
34
|
+
res << "<meta http-equiv=\"Content-type\" content=\"text/html;charset=#{doc.meta_encoding}\" />"
|
40
35
|
res << "</head><body>"
|
41
36
|
res << Sanitize.clean(doc.to_s, SANITIZE_OPTIONS)
|
42
37
|
res << "</body></html>"
|
data/lib/galakei/emoji_table.rb
CHANGED
@@ -2,70 +2,79 @@ require 'active_support/core_ext/string/output_safety'
|
|
2
2
|
module Galakei
|
3
3
|
class EmojiTable
|
4
4
|
MAPPING = {
|
5
|
-
:black_sun_with_rays => %w[2600 E63E E488 E04A EF60],
|
6
|
-
:cloud => %w[2601 E63F E48D E049 EF65],
|
7
|
-
:black_telephon => %w[260E E687 E596 E009 F0B3],
|
8
|
-
:white_smiling_face => %w[263A E6F0 E4FB E414 EFD4],
|
9
|
-
:persevering_face => %w[1F623 E72B EAC2 E406 EC96],
|
10
|
-
:left_pointing_magnifying_glass => %w[1F50D E6DC E518 E114 EFF1],
|
11
|
-
:envelope => %w[2709 E6D3 E521 E103 EFFA],
|
12
|
-
:envelope_with_downwards_arrow_above => %w[1F4E9 E6CF EB62 E103 ED66],
|
13
|
-
:footprints => %w[1F463 E698 EB2A E536 ECEB],
|
14
|
-
:pencil => %w[270F E719 E4A1 E301 EF79],
|
15
|
-
:key => %w[1F511 E6D9 E519 E03F EFF2],
|
16
|
-
:alarm_clock => %w[23F0 E6BA E594 E02D F0B1],
|
17
|
-
:four_leaf_clover => %w[1F340 E741 E513 E110 EFEC],
|
18
|
-
:warning_sign => %w[26A0 E737 E481 E252 EF59],
|
19
|
-
:winking_face => %w[1F609 E729 E5C3 E405 F0F3],
|
20
|
-
:smiling_face_with_open_mouth => %w[1F603 E6F0 E471 E057 EF49],
|
21
|
-
:house_building => %w[1F3E0 E663 E4AB E036 EF84],
|
22
|
-
:squared_new => %w[1F195 E6DD E5B5 E212 F0E5],
|
23
|
-
:sparkle => %w[2747 E6FA E46C E32E EF44],
|
24
|
-
:copyright_sign => %w[00A9 E731 E558 E24E F074],
|
25
|
-
:registered_sign => %w[00AE E736 E559 E24F F075],
|
26
|
-
:trade_mark_sign => %w[2122 E732 E54E E537 F06A],
|
27
|
-
:hash_key => [ %w[0023 20E3] ] + %w[E6E0 EB84 E210 ED89],
|
28
|
-
:keycap_1 => [ %w[0031 20E3] ] + %w[E6E2 E522 E21C EFFB],
|
29
|
-
:keycap_2 => [ %w[0032 20E3] ] + %w[E6E3 E523 E21D EFFC],
|
30
|
-
:keycap_3 => [ %w[0033 20E3] ] + %w[E6E4 E524 E21E F040],
|
31
|
-
:keycap_4 => [ %w[0034 20E3] ] + %w[E6E5 E525 E21F F041],
|
32
|
-
:keycap_5 => [ %w[0035 20E3] ] + %w[E6E6 E526 E220 F042],
|
33
|
-
:keycap_6 => [ %w[0036 20E3] ] + %w[E6E7 E527 E221 F043],
|
34
|
-
:keycap_7 => [ %w[0037 20E3] ] + %w[E6E8 E528 E222 F044],
|
35
|
-
:keycap_8 => [ %w[0040 20E3] ] + %w[E6E9 E529 E223 F045],
|
36
|
-
:keycap_9 => [ %w[0041 20E3] ] + %w[E6EA E52A E224 F046],
|
37
|
-
:keycap_0 => [ %w[0030 20E3] ] + %w[E6EB E52C E225 F047],
|
5
|
+
:black_sun_with_rays => %w[2600 E63E E488 E04A EF60 F660],
|
6
|
+
:cloud => %w[2601 E63F E48D E049 EF65 F665],
|
7
|
+
:black_telephon => %w[260E E687 E596 E009 F0B3 F7B3],
|
8
|
+
:white_smiling_face => %w[263A E6F0 E4FB E414 EFD4 F6D4],
|
9
|
+
:persevering_face => %w[1F623 E72B EAC2 E406 EC96 F396],
|
10
|
+
:left_pointing_magnifying_glass => %w[1F50D E6DC E518 E114 EFF1 F6F1],
|
11
|
+
:envelope => %w[2709 E6D3 E521 E103 EFFA F6FA],
|
12
|
+
:envelope_with_downwards_arrow_above => %w[1F4E9 E6CF EB62 E103 ED66 F466],
|
13
|
+
:footprints => %w[1F463 E698 EB2A E536 ECEB F3EB],
|
14
|
+
:pencil => %w[270F E719 E4A1 E301 EF79 F679],
|
15
|
+
:key => %w[1F511 E6D9 E519 E03F EFF2 F6F2],
|
16
|
+
:alarm_clock => %w[23F0 E6BA E594 E02D F0B1 F7B1],
|
17
|
+
:four_leaf_clover => %w[1F340 E741 E513 E110 EFEC F6EC],
|
18
|
+
:warning_sign => %w[26A0 E737 E481 E252 EF59 F659],
|
19
|
+
:winking_face => %w[1F609 E729 E5C3 E405 F0F3 F7F3],
|
20
|
+
:smiling_face_with_open_mouth => %w[1F603 E6F0 E471 E057 EF49 F649],
|
21
|
+
:house_building => %w[1F3E0 E663 E4AB E036 EF84 F684],
|
22
|
+
:squared_new => %w[1F195 E6DD E5B5 E212 F0E5 F7E5],
|
23
|
+
:sparkle => %w[2747 E6FA E46C E32E EF44 F644],
|
24
|
+
:copyright_sign => %w[00A9 E731 E558 E24E F074 F774],
|
25
|
+
:registered_sign => %w[00AE E736 E559 E24F F075 F775],
|
26
|
+
:trade_mark_sign => %w[2122 E732 E54E E537 F06A F76A],
|
27
|
+
:hash_key => [ %w[0023 20E3] ] + %w[E6E0 EB84 E210 ED89 F489],
|
28
|
+
:keycap_1 => [ %w[0031 20E3] ] + %w[E6E2 E522 E21C EFFB F6FB],
|
29
|
+
:keycap_2 => [ %w[0032 20E3] ] + %w[E6E3 E523 E21D EFFC F6FC],
|
30
|
+
:keycap_3 => [ %w[0033 20E3] ] + %w[E6E4 E524 E21E F040 F741],
|
31
|
+
:keycap_4 => [ %w[0034 20E3] ] + %w[E6E5 E525 E21F F041 F742],
|
32
|
+
:keycap_5 => [ %w[0035 20E3] ] + %w[E6E6 E526 E220 F042 F743],
|
33
|
+
:keycap_6 => [ %w[0036 20E3] ] + %w[E6E7 E527 E221 F043 F744],
|
34
|
+
:keycap_7 => [ %w[0037 20E3] ] + %w[E6E8 E528 E222 F044 F744],
|
35
|
+
:keycap_8 => [ %w[0040 20E3] ] + %w[E6E9 E529 E223 F045 F745],
|
36
|
+
:keycap_9 => [ %w[0041 20E3] ] + %w[E6EA E52A E224 F046 F746],
|
37
|
+
:keycap_0 => [ %w[0030 20E3] ] + %w[E6EB E52C E225 F047 F747],
|
38
38
|
}
|
39
|
-
|
40
|
-
|
39
|
+
class << self
|
40
|
+
def au_utf8_to_sjis(s)
|
41
|
+
MAPPING.values.inject(s) do |s, a|
|
42
|
+
from = "&##{a[4].to_i(16)};"
|
43
|
+
to = [a[5].to_i(16)].pack("n").force_encoding("Shift_JIS")
|
44
|
+
s.gsub(from, to)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
private
|
48
|
+
def pack_as_unicode(a)
|
41
49
|
a = [ a ] if a.is_a?(String)
|
42
|
-
a.map{|s| ("0x" + s).hex}.pack("U*")
|
50
|
+
a.map{|s| ("0x" + s).hex}.pack("U*")
|
43
51
|
end
|
52
|
+
end
|
53
|
+
|
54
|
+
MAPPING.each do |k,v|
|
44
55
|
define_method k do
|
45
|
-
|
56
|
+
@table[k]
|
46
57
|
end
|
47
58
|
end
|
48
59
|
|
49
|
-
def initialize(
|
50
|
-
@
|
60
|
+
def initialize(table)
|
61
|
+
@table = table
|
51
62
|
end
|
52
63
|
|
53
64
|
def self.unicode
|
54
|
-
@unicode ||= EmojiTable.new(0)
|
65
|
+
@unicode ||= EmojiTable.new(Hash[MAPPING.map {|k,a| [k, pack_as_unicode(a[0])]}])
|
55
66
|
end
|
56
67
|
|
57
68
|
def self.docomo
|
58
|
-
@docomo ||= EmojiTable.new(1)
|
69
|
+
@docomo ||= EmojiTable.new(Hash[MAPPING.map {|k,a| [k, pack_as_unicode(a[1])]}])
|
59
70
|
end
|
60
71
|
|
61
72
|
def self.au
|
62
|
-
@au ||= EmojiTable.new(4)
|
73
|
+
@au ||= EmojiTable.new(Hash[MAPPING.map {|k,a| [k, pack_as_unicode(a[4])]}])
|
63
74
|
end
|
64
75
|
|
65
|
-
|
66
|
-
|
67
76
|
def self.softbank
|
68
|
-
@softbank ||= EmojiTable.new(3)
|
77
|
+
@softbank ||= EmojiTable.new(Hash[MAPPING.map {|k,a| [k, pack_as_unicode(a[3])]}])
|
69
78
|
end
|
70
79
|
end
|
71
80
|
end
|
@@ -17,6 +17,7 @@ class Galakei::Filter::Recode < Galakei::Filter::Base
|
|
17
17
|
yield
|
18
18
|
doc = Nokogiri::HTML(response.body)
|
19
19
|
response.body = doc.serialize(:encoding => 'Shift_JIS')
|
20
|
+
response.body = Galakei::EmojiTable.au_utf8_to_sjis(response.body)
|
20
21
|
response.charset = "Shift_JIS"
|
21
22
|
end
|
22
23
|
|
data/lib/galakei/version.rb
CHANGED
@@ -5,6 +5,9 @@ class EmojiController < ApplicationController
|
|
5
5
|
def index
|
6
6
|
render :inline => "<%= emoji_table.black_sun_with_rays %>", :layout => true
|
7
7
|
end
|
8
|
+
def with_unicode
|
9
|
+
render :inline => "テスト<%= emoji_table.black_sun_with_rays %>", :layout => true
|
10
|
+
end
|
8
11
|
end
|
9
12
|
|
10
13
|
feature 'emoji table' do
|
@@ -18,6 +21,17 @@ feature 'emoji table' do
|
|
18
21
|
page.body.should match("\uEF60")
|
19
22
|
end
|
20
23
|
|
24
|
+
scenario 'for au SSL', :driver => :au do
|
25
|
+
visit 'https://www.example.com/emoji'
|
26
|
+
page.body.should match([0xF660].pack("n").force_encoding("Shift_JIS"))
|
27
|
+
end
|
28
|
+
|
29
|
+
scenario 'for au SSL with unicode source', :driver => :au do
|
30
|
+
visit 'https://www.example.com/emoji/with_unicode'
|
31
|
+
expected = "テスト".encode("Shift_JIS") + [0xF660].pack("n").force_encoding("Shift_JIS")
|
32
|
+
page.body.should match(expected)
|
33
|
+
end
|
34
|
+
|
21
35
|
scenario 'for softbank', :driver => :softbank do
|
22
36
|
visit '/emoji'
|
23
37
|
page.body.should match("\uE04A")
|
data/spec/galakei/email_spec.rb
CHANGED
@@ -29,13 +29,8 @@ describe Galakei::Email do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should have div,href,br,hr elements" do
|
32
|
-
html_email='<div
|
33
|
-
Galakei::Email.to_galakei_email(html_email).should =~ /div(.*)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should allow font, blink and marquee elements" do
|
37
|
-
html_email='<div align="center"><font size="2" color="red">NEWS FLASH</font><blink>plink plink plink the nineties!</blink><marquee behaviour="scroll">This is corn!</marquee></div>'
|
38
|
-
Galakei::Email.to_galakei_email(html_email).should =~ /font(.*)size(.*)color(.*)blink(.*)marquee(.*)behaviour/m
|
32
|
+
html_email='<div><a href="http://dragonmobile.nuancemobiledeveloper.com/"><img src="http://www.mobilemonday.jp/wp-content/uploads/2011/01/NMDP.jpg" alt=""></a></div><hr> <br><div class="register_button"><a href="http://gigs.checkin.local:3000/events/2/tickets/new?auth_token=demo">Register</a></div>'
|
33
|
+
Galakei::Email.to_galakei_email(html_email).should =~ /div(.*)href(.*)hr(.*)br/m
|
39
34
|
end
|
40
35
|
|
41
36
|
end
|
metadata
CHANGED
@@ -1,107 +1,80 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: galakei
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
- 1
|
10
|
-
version: 0.9.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Paul McMahon
|
14
9
|
- Michael Reinsch
|
15
10
|
- Yuki Akamatsu
|
16
11
|
autorequire:
|
17
12
|
bindir: bin
|
18
13
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
date: 2011-09-02 00:00:00.000000000Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
23
17
|
name: actionpack
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirement: &2157761600 !ruby/object:Gem::Requirement
|
26
19
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 1
|
31
|
-
segments:
|
32
|
-
- 3
|
33
|
-
- 0
|
34
|
-
- 3
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
35
23
|
version: 3.0.3
|
36
24
|
type: :runtime
|
37
|
-
version_requirements: *id001
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: rack
|
40
25
|
prerelease: false
|
41
|
-
|
26
|
+
version_requirements: *2157761600
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rack
|
29
|
+
requirement: &2157761100 !ruby/object:Gem::Requirement
|
42
30
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
hash: 29
|
47
|
-
segments:
|
48
|
-
- 1
|
49
|
-
- 2
|
50
|
-
- 1
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
51
34
|
version: 1.2.1
|
52
35
|
type: :runtime
|
53
|
-
version_requirements: *id002
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: css_parser
|
56
36
|
prerelease: false
|
57
|
-
|
37
|
+
version_requirements: *2157761100
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: css_parser
|
40
|
+
requirement: &2157760720 !ruby/object:Gem::Requirement
|
58
41
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
segments:
|
64
|
-
- 0
|
65
|
-
version: "0"
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
66
46
|
type: :runtime
|
67
|
-
version_requirements: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: nokogiri
|
70
47
|
prerelease: false
|
71
|
-
|
48
|
+
version_requirements: *2157760720
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: nokogiri
|
51
|
+
requirement: &2157760260 !ruby/object:Gem::Requirement
|
72
52
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
version: "0"
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
80
57
|
type: :runtime
|
81
|
-
version_requirements: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: sanitize
|
84
58
|
prerelease: false
|
85
|
-
|
59
|
+
version_requirements: *2157760260
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: sanitize
|
62
|
+
requirement: &2157759840 !ruby/object:Gem::Requirement
|
86
63
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
|
91
|
-
segments:
|
92
|
-
- 0
|
93
|
-
version: "0"
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
94
68
|
type: :runtime
|
95
|
-
|
96
|
-
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *2157759840
|
71
|
+
description: Japanese feature phones (a.k.a., keitai, galakei) have a number of restrictions
|
72
|
+
over normal web browsers. This library adds support for them
|
97
73
|
email: info@mobalean.com
|
98
74
|
executables: []
|
99
|
-
|
100
75
|
extensions: []
|
101
|
-
|
102
76
|
extra_rdoc_files: []
|
103
|
-
|
104
|
-
files:
|
77
|
+
files:
|
105
78
|
- .gitignore
|
106
79
|
- Gemfile
|
107
80
|
- Gemfile.lock
|
@@ -165,36 +138,26 @@ files:
|
|
165
138
|
- spec/spec_helper.rb
|
166
139
|
homepage: http://www.mobalean.com
|
167
140
|
licenses: []
|
168
|
-
|
169
141
|
post_install_message:
|
170
142
|
rdoc_options: []
|
171
|
-
|
172
|
-
require_paths:
|
143
|
+
require_paths:
|
173
144
|
- lib
|
174
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
175
146
|
none: false
|
176
|
-
requirements:
|
177
|
-
- -
|
178
|
-
- !ruby/object:Gem::Version
|
179
|
-
|
180
|
-
|
181
|
-
- 0
|
182
|
-
version: "0"
|
183
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
152
|
none: false
|
185
|
-
requirements:
|
186
|
-
- -
|
187
|
-
- !ruby/object:Gem::Version
|
188
|
-
|
189
|
-
segments:
|
190
|
-
- 0
|
191
|
-
version: "0"
|
153
|
+
requirements:
|
154
|
+
- - ! '>='
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
192
157
|
requirements: []
|
193
|
-
|
194
158
|
rubyforge_project: galakei
|
195
159
|
rubygems_version: 1.8.6
|
196
160
|
signing_key:
|
197
161
|
specification_version: 3
|
198
162
|
summary: Japanese feature phones support
|
199
163
|
test_files: []
|
200
|
-
|