refinements 11.0.1 → 11.1.1
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
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +108 -41
- data/lib/refinements/data.rb +12 -0
- data/lib/refinements/hashes.rb +14 -1
- data/lib/refinements/shared/values/diff.rb +19 -0
- data/lib/refinements/structs.rb +4 -0
- data/lib/refinements.rb +1 -0
- data/refinements.gemspec +1 -1
- data.tar.gz.sig +0 -0
- metadata +5 -3
- metadata.gz.sig +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91fae4e74017d86d0ca24e153dc7210fd9503276ccdf79da032e0f8f8ee2d181
|
4
|
+
data.tar.gz: eeea2c49941fe6508e9e4aab89aa42f38c2e23efd48b4f5381d4487a08061e3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08e77b3c0837d2158593f431a6cdd427cdc7cf9a1605178c0762444549b08807e3f3890cd7c578a8bc429d453b8961d38649a412b4616ea92889f745a721bc1f'
|
7
|
+
data.tar.gz: 20525ddb58f09cb45d4fc39fe652d0790b156f387bea40fe0f6574be0d396d8607cc6e9f692a6e6feee78f8608b102aaab5d9219ef6f4d43dcdd5e73e8ad4957
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.adoc
CHANGED
@@ -14,6 +14,7 @@ Enhances the following objects:
|
|
14
14
|
|
15
15
|
* Array
|
16
16
|
* BigDecimal
|
17
|
+
* Data
|
17
18
|
* DateTime
|
18
19
|
* Hash
|
19
20
|
* IO
|
@@ -78,6 +79,7 @@ gem "refinements", require: false
|
|
78
79
|
----
|
79
80
|
require "refinements/arrays"
|
80
81
|
require "refinements/big_decimals"
|
82
|
+
require "refinements/data"
|
81
83
|
require "refinements/date_times"
|
82
84
|
require "refinements/hashes"
|
83
85
|
require "refinements/ios"
|
@@ -100,6 +102,7 @@ refinement(s):
|
|
100
102
|
class Example
|
101
103
|
using Refinements::Arrays
|
102
104
|
using Refinements::BigDecimals
|
105
|
+
using Refinements::Data
|
103
106
|
using Refinements::DateTimes
|
104
107
|
using Refinements::Hashes
|
105
108
|
using Refinements::IOs
|
@@ -184,9 +187,9 @@ Answers the first element which evaluates to true from a filtered collection.
|
|
184
187
|
[source,ruby]
|
185
188
|
----
|
186
189
|
handlers = [
|
187
|
-
->
|
190
|
+
-> object { object if object == :b },
|
188
191
|
proc { false },
|
189
|
-
->
|
192
|
+
-> object { object if object == :a }
|
190
193
|
]
|
191
194
|
|
192
195
|
handlers.filter_find # Enumerator::Lazy
|
@@ -206,7 +209,7 @@ Adds given array or elements without mutating itself.
|
|
206
209
|
|
207
210
|
===== #intersperse
|
208
211
|
|
209
|
-
Inserts additional elements or an array between all members of given array.
|
212
|
+
Inserts additional elements, or an array, between all members of given array.
|
210
213
|
|
211
214
|
[source,ruby]
|
212
215
|
----
|
@@ -234,11 +237,13 @@ Answers the maximum extracted value from a collection of objects.
|
|
234
237
|
|
235
238
|
[source,ruby]
|
236
239
|
----
|
237
|
-
Point =
|
240
|
+
Point = Data.define :x, :y
|
238
241
|
points = [Point[x: 1, y: 2], Point[x: 0, y: 1], Point[x: 2, y: 3]]
|
239
242
|
|
240
|
-
points.maximum
|
241
|
-
points.maximum
|
243
|
+
points.maximum :x # 2
|
244
|
+
points.maximum :y # 3
|
245
|
+
points.maximum :z # undefined method `z' for #<data Point x=1, y=2> (NoMethodError)
|
246
|
+
[].maximum :x # nil
|
242
247
|
----
|
243
248
|
|
244
249
|
===== #mean
|
@@ -259,11 +264,13 @@ Answers the minimum extracted value from a collection of objects.
|
|
259
264
|
|
260
265
|
[source,ruby]
|
261
266
|
----
|
262
|
-
Point =
|
267
|
+
Point = Data.define :x, :y
|
263
268
|
points = [Point[x: 1, y: 2], Point[x: 0, y: 1], Point[x: 2, y: 3]]
|
264
269
|
|
265
|
-
points.minimum
|
266
|
-
points.minimum
|
270
|
+
points.minimum :x # 0
|
271
|
+
points.minimum :y # 1
|
272
|
+
points.minimum :z # undefined method `z' for #<data Point x=1, y=2> (NoMethodError)
|
273
|
+
[].minimum :x # nil
|
267
274
|
----
|
268
275
|
|
269
276
|
===== #pad
|
@@ -289,7 +296,7 @@ array = [{name: "a", label: "A"}, {name: "b", label: "B"}, {name: "c", label: "C
|
|
289
296
|
array.pick :name # "a"
|
290
297
|
array.pick :name, :label # ["a", "A"]
|
291
298
|
array.pick # nil
|
292
|
-
[].pick
|
299
|
+
[].pick :other # nil
|
293
300
|
----
|
294
301
|
|
295
302
|
===== #pluck
|
@@ -312,10 +319,10 @@ Answers mutated array where an element -- at a specific index -- is replaced by
|
|
312
319
|
|
313
320
|
[source,ruby]
|
314
321
|
----
|
315
|
-
%i[a b c].replace_at
|
316
|
-
%i[a b c].replace_at
|
317
|
-
%i[a b c].replace_at
|
318
|
-
%i[a b c].replace_at
|
322
|
+
%i[a b c].replace_at 0, :x # [:x, :b, :c]
|
323
|
+
%i[a b c].replace_at 1, :x # [:a, :x, :c]
|
324
|
+
%i[a b c].replace_at 1, :x, :y # [:a, :x, :y, :c]
|
325
|
+
%i[a b c].replace_at -1, :x # [:a, :b, :x]
|
319
326
|
----
|
320
327
|
|
321
328
|
===== #ring
|
@@ -397,6 +404,28 @@ Allows one to inspect a big decimal with numeric representation.
|
|
397
404
|
BigDecimal.new("5.0E-10").inspect # "#<BigDecimal:3fd3d458fe84 0.0000000005>"
|
398
405
|
----
|
399
406
|
|
407
|
+
==== Data
|
408
|
+
|
409
|
+
===== #diff
|
410
|
+
|
411
|
+
Allows you to obtain the differences between two objects.
|
412
|
+
|
413
|
+
[source,ruby]
|
414
|
+
----
|
415
|
+
implementation = Data.define :a, :b, :c
|
416
|
+
|
417
|
+
one = implementation.new a: 1, b: 2, c: 3
|
418
|
+
two = implementation.new a: 3, b: 2, c: 1
|
419
|
+
three = Data.define(:x, :y).new x: 1, y: 2
|
420
|
+
|
421
|
+
one.diff one # {}
|
422
|
+
one.diff two # {:a=>[1, 3], :c=>[3, 1]}
|
423
|
+
one.diff three # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
424
|
+
one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
425
|
+
----
|
426
|
+
|
427
|
+
Any object that _is not_ the same type will have a `nil` value as shown in the last two examples.
|
428
|
+
|
400
429
|
==== DateTime
|
401
430
|
|
402
431
|
===== .utc
|
@@ -532,6 +561,26 @@ example.deep_symbolize_keys! # {a: {b: 1}}
|
|
532
561
|
example # {a: {b: 1}}
|
533
562
|
----
|
534
563
|
|
564
|
+
===== #diff
|
565
|
+
|
566
|
+
Allows you to obtain the differences between two objects.
|
567
|
+
|
568
|
+
[source,ruby]
|
569
|
+
----
|
570
|
+
one = {a: 1, b: 2, c: 3}
|
571
|
+
two = {a: 3, b: 2, c: 1}
|
572
|
+
three = {c: 3, b: 2, a: 1}
|
573
|
+
four = Data.define(:x, :y).new x: 1, y: 2
|
574
|
+
|
575
|
+
one.diff one # {}
|
576
|
+
one.diff two # {:a=>[1, 3], :c=>[3, 1]}
|
577
|
+
one.diff three # {}
|
578
|
+
one.diff four # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
579
|
+
one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
580
|
+
----
|
581
|
+
|
582
|
+
Any object that _is not_ the same type will have a `nil` value as shown in the last two examples. Two hashes with the same keys but defined in different order behave as if they had the same key order.
|
583
|
+
|
535
584
|
===== #fetch_value
|
536
585
|
|
537
586
|
Fetches value for exiting or missing key. Behavior is identical to `#fetch` except when the value of
|
@@ -751,12 +800,12 @@ Answers full stream by rewinding to beginning of stream and reading all content.
|
|
751
800
|
io = IO.new IO.sysopen(Pathname("demo.txt").to_s, "w+")
|
752
801
|
io.write "This is a demo."
|
753
802
|
|
754
|
-
io.reread
|
755
|
-
io.reread 4
|
803
|
+
io.reread # "This is a demo."
|
804
|
+
io.reread 4 # "This"
|
756
805
|
|
757
806
|
buffer = "".dup
|
758
|
-
io.reread(buffer:
|
759
|
-
buffer
|
807
|
+
io.reread(buffer:) # "This is a demo."
|
808
|
+
buffer # "This is a demo."
|
760
809
|
----
|
761
810
|
|
762
811
|
===== #squelch
|
@@ -784,17 +833,17 @@ Answers previously written content by rewinding to beginning of device.
|
|
784
833
|
# With File.
|
785
834
|
device = Logger::LogDevice.new "test.log"
|
786
835
|
device.write "Test."
|
787
|
-
device.reread
|
836
|
+
device.reread # "Test."
|
788
837
|
|
789
838
|
# With StringIO.
|
790
839
|
device = Logger::LogDevice.new StringIO.new
|
791
840
|
device.write "Test."
|
792
|
-
device.reread
|
841
|
+
device.reread # "Test."
|
793
842
|
|
794
843
|
# With STDOUT.
|
795
844
|
device = Logger::LogDevice.new $stdout
|
796
845
|
device.write "Test."
|
797
|
-
device.reread
|
846
|
+
device.reread # ""
|
798
847
|
----
|
799
848
|
|
800
849
|
==== Logger
|
@@ -808,17 +857,17 @@ Answers previously written content by rewinding to beginning of log.
|
|
808
857
|
# With File.
|
809
858
|
logger = Logger.new "test.log"
|
810
859
|
logger.write "Test."
|
811
|
-
logger.reread
|
860
|
+
logger.reread # "Test."
|
812
861
|
|
813
862
|
# With StringIO.
|
814
863
|
logger = Logger.new StringIO.new
|
815
864
|
logger.write "Test."
|
816
|
-
logger.reread
|
865
|
+
logger.reread # "Test."
|
817
866
|
|
818
867
|
# With STDOUT.
|
819
868
|
logger = Logger.new $stdout
|
820
869
|
logger.write "Test."
|
821
|
-
logger.reread
|
870
|
+
logger.reread # ""
|
822
871
|
----
|
823
872
|
|
824
873
|
===== #any
|
@@ -846,7 +895,7 @@ construct a valid path.
|
|
846
895
|
|
847
896
|
[source,ruby]
|
848
897
|
----
|
849
|
-
Pathname
|
898
|
+
Pathname nil # Pathname("")
|
850
899
|
----
|
851
900
|
|
852
901
|
===== .home
|
@@ -972,9 +1021,9 @@ Deletes a path prefix and answers new pathname.
|
|
972
1021
|
|
973
1022
|
[source,ruby]
|
974
1023
|
----
|
975
|
-
Pathname("a/path/example-test.rb").delete_prefix
|
976
|
-
Pathname("example-test.rb").delete_prefix
|
977
|
-
Pathname("example-test.rb").delete_prefix
|
1024
|
+
Pathname("a/path/example-test.rb").delete_prefix "example-" # Pathname("a/path/test.rb")
|
1025
|
+
Pathname("example-test.rb").delete_prefix "example-" # Pathname("test.rb")
|
1026
|
+
Pathname("example-test.rb").delete_prefix "miss" # Pathname("example-test.rb")
|
978
1027
|
----
|
979
1028
|
|
980
1029
|
===== #delete_suffix
|
@@ -983,9 +1032,9 @@ Deletes a path suffix and answers new pathname.
|
|
983
1032
|
|
984
1033
|
[source,ruby]
|
985
1034
|
----
|
986
|
-
Pathname("a/path/test-example.rb").delete_suffix
|
987
|
-
Pathname("test-example.rb").delete_suffix
|
988
|
-
Pathname("test-example.rb").delete_suffix
|
1035
|
+
Pathname("a/path/test-example.rb").delete_suffix "-example" # Pathname("a/path/test.rb")
|
1036
|
+
Pathname("test-example.rb").delete_suffix "-example" # Pathname("test.rb")
|
1037
|
+
Pathname("test-example.rb").delete_suffix "miss" # Pathname("test-example.rb")
|
989
1038
|
----
|
990
1039
|
|
991
1040
|
===== #directories
|
@@ -1039,10 +1088,10 @@ Same behavior as `String#gsub` but answers a path with patterns replaced with de
|
|
1039
1088
|
|
1040
1089
|
[source,ruby]
|
1041
1090
|
----
|
1042
|
-
Pathname("/a/path/some/path").gsub
|
1091
|
+
Pathname("/a/path/some/path").gsub "path", "test"
|
1043
1092
|
# Pathname("/a/test/some/test")
|
1044
1093
|
|
1045
|
-
Pathname("/%placeholder%/some/%placeholder%").gsub
|
1094
|
+
Pathname("/%placeholder%/some/%placeholder%").gsub "%placeholder%", "test"
|
1046
1095
|
# Pathname("/test/some/test")
|
1047
1096
|
----
|
1048
1097
|
|
@@ -1090,11 +1139,11 @@ Pathname("example.txt").name # Pathname("example")
|
|
1090
1139
|
|
1091
1140
|
===== #relative_parent
|
1092
1141
|
|
1093
|
-
Answers relative path from parent directory. This
|
1142
|
+
Answers relative path from parent directory. This complements: `#relative_path_from`.
|
1094
1143
|
|
1095
1144
|
[source,ruby]
|
1096
1145
|
----
|
1097
|
-
Pathname("/one/two/three").relative_parent
|
1146
|
+
Pathname("/one/two/three").relative_parent "/one" # Pathname "two"
|
1098
1147
|
----
|
1099
1148
|
|
1100
1149
|
===== #remove_dir
|
@@ -1333,8 +1382,8 @@ io.reread # "This is a test."
|
|
1333
1382
|
io.reread 4 # "This"
|
1334
1383
|
|
1335
1384
|
buffer = "".dup
|
1336
|
-
io.reread(buffer:
|
1337
|
-
buffer
|
1385
|
+
io.reread(buffer:) # "This is a test."
|
1386
|
+
buffer # "This is a test."
|
1338
1387
|
----
|
1339
1388
|
|
1340
1389
|
==== Struct
|
@@ -1355,6 +1404,26 @@ Example.with_positions 1, 2, 3 # #<struct a=1, b=2, c=3>
|
|
1355
1404
|
Example.with_positions 1 # #<struct a=1, b=nil, c=nil>
|
1356
1405
|
----
|
1357
1406
|
|
1407
|
+
===== #diff
|
1408
|
+
|
1409
|
+
Allows you to obtain the differences between two objects.
|
1410
|
+
|
1411
|
+
[source,ruby]
|
1412
|
+
----
|
1413
|
+
implementation = Struct.new :a, :b, :c
|
1414
|
+
|
1415
|
+
one = implementation.new a: 1, b: 2, c: 3
|
1416
|
+
two = implementation.new a: 3, b: 2, c: 1
|
1417
|
+
three = Struct.new(:x, :y).new x: 1, y: 2
|
1418
|
+
|
1419
|
+
one.diff one # {}
|
1420
|
+
one.diff two # {:a=>[1, 3], :c=>[3, 1]}
|
1421
|
+
one.diff three # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
1422
|
+
one.diff Object.new # {:a=>[1, nil], :b=>[2, nil], :c=>[3, nil]}
|
1423
|
+
----
|
1424
|
+
|
1425
|
+
Any object that _is not_ the same type will have a `nil` value as shown in the last two examples.
|
1426
|
+
|
1358
1427
|
===== #merge
|
1359
1428
|
|
1360
1429
|
Merges multiple attributes without mutating itself and supports any object that responds to `#to_h`.
|
@@ -1393,8 +1462,7 @@ example # #<struct Struct::Example a=10, b=20, c=30>
|
|
1393
1462
|
|
1394
1463
|
Transforms values without mutating itself. An optional hash can be supplied to target specific
|
1395
1464
|
attributes. In the event that a block isn't supplied, the struct will answer itself since there is
|
1396
|
-
nothing to operate on.
|
1397
|
-
positional or keyword arguments. Works regardless of whether the struct is constructed with
|
1465
|
+
nothing to operate on. Works regardless of whether the struct is constructed with
|
1398
1466
|
positional or keyword arguments.
|
1399
1467
|
|
1400
1468
|
[source,ruby]
|
@@ -1412,8 +1480,7 @@ example # #<struct Str
|
|
1412
1480
|
|
1413
1481
|
Transforms values while mutating itself. An optional hash can be supplied to target specific
|
1414
1482
|
attributes. In the event that a block isn't supplied, the struct will answer itself since there is
|
1415
|
-
nothing to operate on.
|
1416
|
-
positional or keyword arguments. Works regardless of whether the struct is constructed with
|
1483
|
+
nothing to operate on. Works regardless of whether the struct is constructed with
|
1417
1484
|
positional or keyword arguments.
|
1418
1485
|
|
1419
1486
|
[source,ruby]
|
data/lib/refinements/hashes.rb
CHANGED
@@ -45,7 +45,13 @@ module Refinements
|
|
45
45
|
|
46
46
|
def deep_symbolize_keys! = replace(deep_symbolize_keys)
|
47
47
|
|
48
|
-
def
|
48
|
+
def diff other
|
49
|
+
return differences_from other if other.is_a?(self.class) && keys.sort! == other.keys.sort!
|
50
|
+
|
51
|
+
each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
|
52
|
+
end
|
53
|
+
|
54
|
+
def fetch_value(key, *default, &) = fetch(key, *default, &) || default.first
|
49
55
|
|
50
56
|
def flatten_keys prefix: nil, delimiter: "_"
|
51
57
|
reduce({}) do |accumulator, (key, value)|
|
@@ -88,6 +94,13 @@ module Refinements
|
|
88
94
|
.map { |(_type, key)| self[key] || self[key.to_s] }
|
89
95
|
.then { |values| yield values }
|
90
96
|
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def differences_from other
|
101
|
+
result = merge(other.to_h) { |_, one, two| [one, two].uniq }
|
102
|
+
result.select { |_, diff| diff.size == 2 }
|
103
|
+
end
|
91
104
|
end
|
92
105
|
end
|
93
106
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Refinements
|
4
|
+
module Shared
|
5
|
+
module Values
|
6
|
+
# Provides shared whole value functionality for knowing the difference between two objects.
|
7
|
+
module Diff
|
8
|
+
def diff other
|
9
|
+
if other.is_a? self.class
|
10
|
+
to_h.merge(other.to_h) { |_, one, two| [one, two].uniq }
|
11
|
+
.select { |_, diff| diff.size == 2 }
|
12
|
+
else
|
13
|
+
to_h.each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/refinements/structs.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "refinements/shared/values/diff"
|
4
|
+
|
3
5
|
module Refinements
|
4
6
|
# Provides additional enhancements to the Struct primitive.
|
5
7
|
module Structs
|
@@ -8,6 +10,8 @@ module Refinements
|
|
8
10
|
end
|
9
11
|
|
10
12
|
refine Struct do
|
13
|
+
import_methods Shared::Values::Diff
|
14
|
+
|
11
15
|
def merge(...) = dup.merge!(...)
|
12
16
|
|
13
17
|
def merge! object = nil
|
data/lib/refinements.rb
CHANGED
data/refinements.gemspec
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: refinements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 11.
|
4
|
+
version: 11.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
|
36
36
|
gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2023-
|
38
|
+
date: 2023-11-04 00:00:00.000000000 Z
|
39
39
|
dependencies: []
|
40
40
|
description:
|
41
41
|
email:
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- lib/refinements.rb
|
52
52
|
- lib/refinements/arrays.rb
|
53
53
|
- lib/refinements/big_decimals.rb
|
54
|
+
- lib/refinements/data.rb
|
54
55
|
- lib/refinements/date_times.rb
|
55
56
|
- lib/refinements/hashes.rb
|
56
57
|
- lib/refinements/ios.rb
|
@@ -59,6 +60,7 @@ files:
|
|
59
60
|
- lib/refinements/pathnames.rb
|
60
61
|
- lib/refinements/shared/enumerables/many.rb
|
61
62
|
- lib/refinements/shared/ios/reread.rb
|
63
|
+
- lib/refinements/shared/values/diff.rb
|
62
64
|
- lib/refinements/string_ios.rb
|
63
65
|
- lib/refinements/strings.rb
|
64
66
|
- lib/refinements/structs.rb
|
@@ -90,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
92
|
- !ruby/object:Gem::Version
|
91
93
|
version: '0'
|
92
94
|
requirements: []
|
93
|
-
rubygems_version: 3.4.
|
95
|
+
rubygems_version: 3.4.21
|
94
96
|
signing_key:
|
95
97
|
specification_version: 4
|
96
98
|
summary: A collection of core Ruby object refinements.
|
metadata.gz.sig
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
im����uV�?q��6�
|
2
|
+
bM���e������T�`�!��9�u=�R��[m���E,�j�q=7�a��EB\w8�\�����ɖv���U��(m��Z���ڌ#N�p�'���f���,�=��.�x}8_����D����ce�:�(�hr�0���!u�y ��z��#L[����x������^B���*K4ўS�+�S#�@��kR!9Z��[1���
|
3
|
+
�k�_�p�}˄��i|�a��!N!��hB��<0؛M�ri��?��U&u���̍9����i1?���9����V���D:�=1Y�X|�A6��v�c9�z��Y���u���u�.m�1e����nW��R�+�s���B���~�`l�h
|