mongoid 5.2.0 → 5.2.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
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/extensions/origin/regexp_raw.rb +43 -0
- data/lib/mongoid/matchable.rb +8 -1
- data/lib/mongoid/matchable/regexp.rb +27 -0
- data/lib/mongoid/version.rb +1 -1
- data/spec/mongoid/criteria_spec.rb +11 -0
- data/spec/mongoid/extensions/origin/regexp_raw_spec.rb +89 -0
- data/spec/mongoid/matchable/regexp_spec.rb +59 -0
- data/spec/mongoid/matchable_spec.rb +51 -1
- metadata +10 -26
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5ae2a3a33da11eae20a6d6b268ad3e69d601a13
|
4
|
+
data.tar.gz: 661ff308d0402ab14a5a3920534a1a88f879e3ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a910a280572a11c133f8f3900f878fdb719c548998381bb38c08714c911cbfc1ebfd508ffb84621489cdd8806a8e054cbb55aa041a189267f1fdb30d322d8895
|
7
|
+
data.tar.gz: 0bfeada8b1bc927fde4414f1accdfe30037b36d56776c5f9b904b041e5356bd4df7a202fbb69e40edda9c165d84a78cdc0f4971ebb7afcad021bd7526d9e6cf0
|
data/lib/mongoid/extensions.rb
CHANGED
@@ -39,6 +39,7 @@ require "mongoid/extensions/module"
|
|
39
39
|
require "mongoid/extensions/nil_class"
|
40
40
|
require "mongoid/extensions/object"
|
41
41
|
require "mongoid/extensions/object_id"
|
42
|
+
require "mongoid/extensions/origin/regexp_raw"
|
42
43
|
require "mongoid/extensions/range"
|
43
44
|
require "mongoid/extensions/regexp"
|
44
45
|
require "mongoid/extensions/set"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Origin
|
2
|
+
module Extensions
|
3
|
+
|
4
|
+
# This module contains additional bson raw regex behaviour.
|
5
|
+
module Regexp
|
6
|
+
|
7
|
+
module Raw
|
8
|
+
|
9
|
+
# Is the object a regexp?
|
10
|
+
#
|
11
|
+
# @example Is the object a regex?
|
12
|
+
# bson_raw_regexp.regexp?
|
13
|
+
#
|
14
|
+
# @return [ true ] Always true.
|
15
|
+
#
|
16
|
+
# @since 5.2.1
|
17
|
+
def regexp?; true; end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
# Evolve the object into a raw bson regex.
|
22
|
+
#
|
23
|
+
# @example Evolve the object to a regex.
|
24
|
+
# BSON::Regexp::Raw.evolve("^[123]")
|
25
|
+
#
|
26
|
+
# @param [ BSON::Regexp::Raw, String ] object The object to evolve.
|
27
|
+
#
|
28
|
+
# @return [ BSON::Regexp::Raw ] The evolved raw regex.
|
29
|
+
#
|
30
|
+
# @since 5.2.1
|
31
|
+
def evolve(object)
|
32
|
+
__evolve__(object) do |obj|
|
33
|
+
obj.is_a?(String) ? BSON::Regexp::Raw.new(obj) : obj
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
BSON::Regexp::Raw.__send__(:include, Origin::Extensions::Regexp::Raw)
|
43
|
+
BSON::Regexp::Raw.__send__(:extend, Origin::Extensions::Regexp::Raw::ClassMethods)
|
data/lib/mongoid/matchable.rb
CHANGED
@@ -12,6 +12,7 @@ require "mongoid/matchable/ne"
|
|
12
12
|
require "mongoid/matchable/nin"
|
13
13
|
require "mongoid/matchable/or"
|
14
14
|
require "mongoid/matchable/size"
|
15
|
+
require "mongoid/matchable/regexp"
|
15
16
|
|
16
17
|
module Mongoid
|
17
18
|
|
@@ -115,6 +116,8 @@ module Mongoid
|
|
115
116
|
else
|
116
117
|
Default.new(extract_attribute(document, key))
|
117
118
|
end
|
119
|
+
elsif value.regexp?
|
120
|
+
Regexp.new(extract_attribute(document, key))
|
118
121
|
else
|
119
122
|
case key.to_s
|
120
123
|
when "$or" then Or.new(value, document)
|
@@ -143,7 +146,11 @@ module Mongoid
|
|
143
146
|
if (key_string = key.to_s) =~ /.+\..+/
|
144
147
|
key_string.split('.').inject(document.as_document) do |_attribs, _key|
|
145
148
|
if _attribs.is_a?(::Array)
|
146
|
-
_attribs.
|
149
|
+
if _key =~ /\A\d+\z/ && _attribs.none? {|doc| doc.is_a?(Hash)}
|
150
|
+
_attribs.try(:[], _key.to_i)
|
151
|
+
else
|
152
|
+
_attribs.map { |doc| doc.try(:[], _key) }
|
153
|
+
end
|
147
154
|
else
|
148
155
|
_attribs.try(:[], _key)
|
149
156
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchable
|
3
|
+
|
4
|
+
# Defines behavior for handling regular expressions in embedded documents.
|
5
|
+
class Regexp < Default
|
6
|
+
|
7
|
+
# Does the supplied query match the attribute?
|
8
|
+
#
|
9
|
+
# @example Does this match?
|
10
|
+
# matcher.matches?(/^Em/)
|
11
|
+
# matcher.matches?(BSON::Regex::Raw.new("^Em"))
|
12
|
+
#
|
13
|
+
# @param [ BSON::Regexp::Raw, Regexp ] regexp The regular expression object.
|
14
|
+
#
|
15
|
+
# @return [ true, false ] True if matches, false if not.
|
16
|
+
#
|
17
|
+
# @since 5.2.1
|
18
|
+
def matches?(regexp)
|
19
|
+
if native_regexp = regexp.try(:compile)
|
20
|
+
super(native_regexp)
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/mongoid/version.rb
CHANGED
@@ -3314,6 +3314,17 @@ describe Mongoid::Criteria do
|
|
3314
3314
|
end
|
3315
3315
|
end
|
3316
3316
|
|
3317
|
+
context 'when the criteria contains a BSON::Regexp::Raw' do
|
3318
|
+
|
3319
|
+
let(:criteria) do
|
3320
|
+
Band.where(name: BSON::Regexp::Raw.new("^Depeche"))
|
3321
|
+
end
|
3322
|
+
|
3323
|
+
it "returns the matching documents" do
|
3324
|
+
expect(criteria).to eq([ match ])
|
3325
|
+
end
|
3326
|
+
end
|
3327
|
+
|
3317
3328
|
context "when the criteria is an exact fk array match" do
|
3318
3329
|
|
3319
3330
|
let(:id_one) do
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Origin::Extensions::Regexp::Raw do
|
4
|
+
|
5
|
+
describe ".evolve" do
|
6
|
+
|
7
|
+
context "when provided a bson raw regexp" do
|
8
|
+
|
9
|
+
let(:regexp) do
|
10
|
+
BSON::Regexp::Raw.new("^[123]")
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:evolved) do
|
14
|
+
BSON::Regexp::Raw.evolve(regexp)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns the regexp" do
|
18
|
+
expect(evolved).to be(regexp)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when providing a string" do
|
23
|
+
|
24
|
+
let(:regexp_string) do
|
25
|
+
'^[123]'
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:evolved) do
|
29
|
+
BSON::Regexp::Raw.evolve(regexp_string)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns the converted raw regexp" do
|
33
|
+
expect(evolved).to eq(BSON::Regexp::Raw.new(regexp_string))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when provided an array" do
|
38
|
+
|
39
|
+
context "when the elements are bson raw regexps" do
|
40
|
+
|
41
|
+
let(:regexp) do
|
42
|
+
BSON::Regexp::Raw.new("^[123]")
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:array) do
|
46
|
+
[ regexp ]
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:evolved) do
|
50
|
+
BSON::Regexp::Raw.evolve(array)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the array containing raw regexps" do
|
54
|
+
expect(evolved).to eq([ regexp ])
|
55
|
+
end
|
56
|
+
|
57
|
+
it "does not evolve in place" do
|
58
|
+
expect(evolved).to_not equal(array)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when the elements are strings" do
|
63
|
+
|
64
|
+
let(:regexp_string) do
|
65
|
+
"^[123]"
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:evolved) do
|
69
|
+
BSON::Regexp::Raw.evolve([ regexp_string ])
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns the regexps" do
|
73
|
+
expect(evolved).to eq([ BSON::Regexp::Raw.new(regexp_string) ])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#regexp?" do
|
80
|
+
|
81
|
+
let(:regexp) do
|
82
|
+
BSON::Regexp::Raw.new('^[123]')
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns true" do
|
86
|
+
expect(regexp).to be_regexp
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Matchable::Regexp do
|
4
|
+
|
5
|
+
let(:matcher) do
|
6
|
+
described_class.new(attribute)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:attribute) do
|
10
|
+
'Emily'
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#matches?' do
|
14
|
+
|
15
|
+
context 'when a BSON::Regexp::Raw object is passed' do
|
16
|
+
|
17
|
+
let(:regexp) do
|
18
|
+
BSON::Regexp::Raw.new('^Em')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'compiles the regexp object to a native regexp for the matching' do
|
22
|
+
expect(matcher.matches?(regexp)).to be(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the value does not match the attribute' do
|
26
|
+
|
27
|
+
let(:attribute) do
|
28
|
+
'ily'
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'compiles the regexp object to a native regexp for the matching' do
|
32
|
+
expect(matcher.matches?(regexp)).to be(false)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when a native Regexp object is passed' do
|
38
|
+
|
39
|
+
let(:regexp) do
|
40
|
+
/^Em/
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'calls super with the native regexp' do
|
44
|
+
expect(matcher.matches?(regexp)).to be(true)
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the value does not match the attribute' do
|
48
|
+
|
49
|
+
let(:attribute) do
|
50
|
+
'ily'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'compiles the regexp object to a native regexp for the matching' do
|
54
|
+
expect(matcher.matches?(regexp)).to be(false)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -9,12 +9,13 @@ describe Mongoid::Matchable do
|
|
9
9
|
let(:document) do
|
10
10
|
Address.new(street: "Clarkenwell Road")
|
11
11
|
end
|
12
|
+
let(:occupants){[{'name' => 'Tim'}]}
|
12
13
|
|
13
14
|
before do
|
14
15
|
document.locations << Location.new(
|
15
16
|
name: 'No.1',
|
16
17
|
info: { 'door' => 'Red'},
|
17
|
-
occupants:
|
18
|
+
occupants: occupants
|
18
19
|
)
|
19
20
|
end
|
20
21
|
|
@@ -76,6 +77,33 @@ describe Mongoid::Matchable do
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
80
|
+
context "when matching index of an array" do
|
81
|
+
|
82
|
+
let(:occupants){["Tim","Logan"]}
|
83
|
+
|
84
|
+
context "when the contents match" do
|
85
|
+
|
86
|
+
let(:selector) do
|
87
|
+
{ "occupants.0" => "Tim" }
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns true" do
|
91
|
+
expect(document.locations.first.matches?(selector)).to be true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when the contents do not match" do
|
96
|
+
|
97
|
+
let(:selector) do
|
98
|
+
{ "occupants.0" => "Logan" }
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns false" do
|
102
|
+
expect(document.locations.first.matches?(selector)).to be false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
79
107
|
context "when matching values of multiple embedded hashes" do
|
80
108
|
|
81
109
|
context "when the contents match" do
|
@@ -141,6 +169,28 @@ describe Mongoid::Matchable do
|
|
141
169
|
expect(document.matches?(selector)).to be false
|
142
170
|
end
|
143
171
|
end
|
172
|
+
|
173
|
+
context 'when a BSON::Regexp::Raw object is used' do
|
174
|
+
|
175
|
+
let(:selector) do
|
176
|
+
{ street: BSON::Regexp::Raw.new("^Clarkenwell") }
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns true" do
|
180
|
+
expect(document.matches?(selector)).to be true
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when a native Regexp object is used' do
|
185
|
+
|
186
|
+
let(:selector) do
|
187
|
+
{ street: /^Clarkenwell/ }
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns true" do
|
191
|
+
expect(document.matches?(selector)).to be true
|
192
|
+
end
|
193
|
+
end
|
144
194
|
end
|
145
195
|
|
146
196
|
context "when performing complex matching" do
|
metadata
CHANGED
@@ -1,36 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.2.
|
4
|
+
version: 5.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Durran Jordan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
-
|
12
|
-
-----BEGIN CERTIFICATE-----
|
13
|
-
MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMRQwEgYDVQQDDAtkcml2
|
14
|
-
ZXItcnVieTEVMBMGCgmSJomT8ixkARkWBTEwZ2VuMRMwEQYKCZImiZPyLGQBGRYD
|
15
|
-
Y29tMB4XDTE2MTIwMTE0MDcxMloXDTE3MTIwMTE0MDcxMlowQjEUMBIGA1UEAwwL
|
16
|
-
ZHJpdmVyLXJ1YnkxFTATBgoJkiaJk/IsZAEZFgUxMGdlbjETMBEGCgmSJomT8ixk
|
17
|
-
ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFdSAa8fRm1
|
18
|
-
bAM9za6Z0fAH4g02bqM1NGnw8zJQrE/PFrFfY6IFCT2AsLfOwr1maVm7iU1+kdVI
|
19
|
-
IQ+iI/9+E+ArJ+rbGV3dDPQ+SLl3mLT+vXjfjcxMqI2IW6UuVtt2U3Rxd4QU0kdT
|
20
|
-
JxmcPYs5fDN6BgYc6XXgUjy3m+Kwha2pGctdciUOwEfOZ4RmNRlEZKCMLRHdFP8j
|
21
|
-
4WTnJSGfXDiuoXICJb5yOPOZPuaapPSNXp93QkUdsqdKC32I+KMpKKYGBQ6yisfA
|
22
|
-
5MyVPPCzLR1lP5qXVGJPnOqUAkvEUfCahg7EP9tI20qxiXrR6TSEraYhIFXL0EGY
|
23
|
-
u8KAcPHm5KkCAwEAAaN9MHswCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
24
|
-
BBYEFFt3WbF+9JpUjAoj62cQBgNb8HzXMCAGA1UdEQQZMBeBFWRyaXZlci1ydWJ5
|
25
|
-
QDEwZ2VuLmNvbTAgBgNVHRIEGTAXgRVkcml2ZXItcnVieUAxMGdlbi5jb20wDQYJ
|
26
|
-
KoZIhvcNAQEFBQADggEBAKBDaVkycCUC1zMfpAkXIgWtji2Nr2ZygYQR53AgxOaE
|
27
|
-
7nqxdh5Lh8pnfwa71/ucrZFJt+g/mEhen9lFNmcizvpP43Hh4rYf8j6T8Y+mQ6tr
|
28
|
-
sp5xWiv93DlLXGmas0hv9VRYDvV1vLFaG05FHOAZKdo6pD2t6jNyMSAn4fMHKctw
|
29
|
-
UoYN5FLt84jacRQF5nhy9gBhfgvA19LcjeMLQC11x3fykDLzCXF2wEe5Q5iYaWvb
|
30
|
-
cGiNQIiHBj/9/xHfOyOthBPUevTiVnuffarDr434z/LGLwYzgaG5EcJFvZqpvUpP
|
31
|
-
fGcAPtAZUMGLXwcOB1BJEFkDxUQIJiEpSmf4YzzZhEM=
|
32
|
-
-----END CERTIFICATE-----
|
33
|
-
date: 2017-01-26 00:00:00.000000000 Z
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-05 00:00:00.000000000 Z
|
34
12
|
dependencies:
|
35
13
|
- !ruby/object:Gem::Dependency
|
36
14
|
name: activemodel
|
@@ -218,6 +196,7 @@ files:
|
|
218
196
|
- lib/mongoid/extensions/nil_class.rb
|
219
197
|
- lib/mongoid/extensions/object.rb
|
220
198
|
- lib/mongoid/extensions/object_id.rb
|
199
|
+
- lib/mongoid/extensions/origin/regexp_raw.rb
|
221
200
|
- lib/mongoid/extensions/range.rb
|
222
201
|
- lib/mongoid/extensions/regexp.rb
|
223
202
|
- lib/mongoid/extensions/set.rb
|
@@ -253,6 +232,7 @@ files:
|
|
253
232
|
- lib/mongoid/matchable/ne.rb
|
254
233
|
- lib/mongoid/matchable/nin.rb
|
255
234
|
- lib/mongoid/matchable/or.rb
|
235
|
+
- lib/mongoid/matchable/regexp.rb
|
256
236
|
- lib/mongoid/matchable/size.rb
|
257
237
|
- lib/mongoid/persistable.rb
|
258
238
|
- lib/mongoid/persistable/creatable.rb
|
@@ -668,6 +648,7 @@ files:
|
|
668
648
|
- spec/mongoid/extensions/nil_class_spec.rb
|
669
649
|
- spec/mongoid/extensions/object_id_spec.rb
|
670
650
|
- spec/mongoid/extensions/object_spec.rb
|
651
|
+
- spec/mongoid/extensions/origin/regexp_raw_spec.rb
|
671
652
|
- spec/mongoid/extensions/range_spec.rb
|
672
653
|
- spec/mongoid/extensions/regexp_spec.rb
|
673
654
|
- spec/mongoid/extensions/set_spec.rb
|
@@ -702,6 +683,7 @@ files:
|
|
702
683
|
- spec/mongoid/matchable/ne_spec.rb
|
703
684
|
- spec/mongoid/matchable/nin_spec.rb
|
704
685
|
- spec/mongoid/matchable/or_spec.rb
|
686
|
+
- spec/mongoid/matchable/regexp_spec.rb
|
705
687
|
- spec/mongoid/matchable/size_spec.rb
|
706
688
|
- spec/mongoid/matchable_spec.rb
|
707
689
|
- spec/mongoid/persistable/creatable_spec.rb
|
@@ -821,7 +803,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
821
803
|
version: 1.3.6
|
822
804
|
requirements: []
|
823
805
|
rubyforge_project: mongoid
|
824
|
-
rubygems_version: 2.
|
806
|
+
rubygems_version: 2.6.11
|
825
807
|
signing_key:
|
826
808
|
specification_version: 4
|
827
809
|
summary: Elegant Persistence in Ruby for MongoDB.
|
@@ -1125,6 +1107,7 @@ test_files:
|
|
1125
1107
|
- spec/mongoid/extensions/nil_class_spec.rb
|
1126
1108
|
- spec/mongoid/extensions/object_id_spec.rb
|
1127
1109
|
- spec/mongoid/extensions/object_spec.rb
|
1110
|
+
- spec/mongoid/extensions/origin/regexp_raw_spec.rb
|
1128
1111
|
- spec/mongoid/extensions/range_spec.rb
|
1129
1112
|
- spec/mongoid/extensions/regexp_spec.rb
|
1130
1113
|
- spec/mongoid/extensions/set_spec.rb
|
@@ -1159,6 +1142,7 @@ test_files:
|
|
1159
1142
|
- spec/mongoid/matchable/ne_spec.rb
|
1160
1143
|
- spec/mongoid/matchable/nin_spec.rb
|
1161
1144
|
- spec/mongoid/matchable/or_spec.rb
|
1145
|
+
- spec/mongoid/matchable/regexp_spec.rb
|
1162
1146
|
- spec/mongoid/matchable/size_spec.rb
|
1163
1147
|
- spec/mongoid/matchable_spec.rb
|
1164
1148
|
- spec/mongoid/persistable/creatable_spec.rb
|
checksums.yaml.gz.sig
DELETED
Binary file
|
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
�N�H��vb�E?���|%��wH�7ùq��({*4 �\!��?�R9��w#D��ٍ��� ����9�ݒ(�s��+l�N�'������ǿ:=}%4'��3\Q����Q_¼{A�J�$�H
|