topojson-rails 0.0.32.2 → 1.3.0
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.tar.gz.sig +0 -0
- data/certs/bai.pem +15 -15
- data/lib/topojson-rails/version.rb +1 -1
- data/vendor/assets/javascripts/topojson.js +224 -34
- metadata +17 -17
- metadata.gz.sig +1 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5f156ff2241c767b01dde4aa993ce33432bc156
|
4
|
+
data.tar.gz: e9df9b46d28f924c49c06de3aedd4b7fdf392dca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aea24cceeee16640b66898109d681bea1126f74b65a79010878a4dadd969cca8d21b85cc2a28a77eb5786c5217aaab2be2ad8de2a39a2d381fbf81741554dc18
|
7
|
+
data.tar.gz: 5f4bf9e50a878d9282c86187ed019add381a33600d7150e2657d0c0242c1f3c9ee6771c3fd7a9ddc54e5b05a656cb31b09bc59b7b0cd98eb5ff2872861483f49
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/certs/bai.pem
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
2
|
MIIDSDCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA1MQowCAYDVQQDDAF2MRMw
|
3
|
-
|
4
|
-
|
3
|
+
EQYKCZImiZPyLGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wHhcNMTMwNTIz
|
4
|
+
MjA0MTI3WhcNMTQwNTIzMjA0MTI3WjA1MQowCAYDVQQDDAF2MRMwEQYKCZImiZPy
|
5
5
|
LGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wggEiMA0GCSqGSIb3DQEBAQUA
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
A4IBDwAwggEKAoIBAQCtb8+GfjqcYl6M4IhIGomKsGgWEC4mwTXIq/Yl+jJAdP7s
|
7
|
+
bdV3lWnZybUPKtdHSQIJcxbm8GZspTqSqDgsECI/laTyLj7Srqcbyivf/ov50Tg1
|
8
|
+
CxMtt8STA6wNmY0ljO4SK72Pr8uQwFZIgNHBB9LcvrpmRn/TWDXlcqaq0db6QJKk
|
9
|
+
jGOv74ukiQun+saqthpxwNN6wm0rj1GDulrDuMeeMj/XDgu0piNHhBtsgQ6KrN94
|
10
|
+
cs0XGgwKihL0LdqWiOG9L8tZKeksKk72EcTpvaw1EYUfJ/rAcC8l6SluN2+BDMA0
|
11
|
+
/4LU70O+wTwHcHv2HimtKdlcpS936qOez3lXUD+3AgMBAAGjYzBhMAkGA1UdEwQC
|
12
|
+
MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSRvHatldjBIKT5agA2bnkfm4KUxTAT
|
13
13
|
BgNVHREEDDAKgQh2QGdvci5pbzATBgNVHRIEDDAKgQh2QGdvci5pbzANBgkqhkiG
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
9w0BAQUFAAOCAQEAmyGZCL6ISHS6UCkPAie1LZgyc+yS4ckMPtzBJtjODr5kfRTC
|
15
|
+
tLb9W4epJ9Aa2aGkKy/NL8MFS0BwTJmjSfufFDwFZlw0kI9aAvL4Nx9OHWNen9Dm
|
16
|
+
GtEWXXKpB0du12DBjfavJYl0QLcz18M0mtvug634t40H06GussO83uu7wHEvIPBP
|
17
|
+
Z5VMAbKvOmDgaP2I9XxZ2/lDmBKDZkVNqmqYiScw2CWsKxVPx3vhMGprTIz4O8y/
|
18
|
+
JCf887eMZl/8mEIeCLb+gH5sh5yJJpti2HTLnR4Q1QKWR/0T9tASoQPF3kL62n9+
|
19
|
+
m1B90+fEzJsBDQIAsnLPqxjivWbIIfZ7GeGZyA==
|
20
20
|
-----END CERTIFICATE-----
|
@@ -1,16 +1,9 @@
|
|
1
1
|
topojson = (function() {
|
2
2
|
|
3
3
|
function merge(topology, arcs) {
|
4
|
-
var
|
5
|
-
fragmentByStart = {},
|
4
|
+
var fragmentByStart = {},
|
6
5
|
fragmentByEnd = {};
|
7
6
|
|
8
|
-
arcs.forEach(function(i) {
|
9
|
-
var e = ends(i);
|
10
|
-
(arcsByEnd[e[0]] || (arcsByEnd[e[0]] = [])).push(i);
|
11
|
-
(arcsByEnd[e[1]] || (arcsByEnd[e[1]] = [])).push(~i);
|
12
|
-
});
|
13
|
-
|
14
7
|
arcs.forEach(function(i) {
|
15
8
|
var e = ends(i),
|
16
9
|
start = e[0],
|
@@ -136,15 +129,33 @@ topojson = (function() {
|
|
136
129
|
geometry(o);
|
137
130
|
|
138
131
|
geomsByArc.forEach(arguments.length < 3
|
139
|
-
? function(geoms, i) { arcs.push(
|
140
|
-
: function(geoms, i) { if (filter(geoms[0], geoms[geoms.length - 1])) arcs.push(
|
132
|
+
? function(geoms, i) { arcs.push(i); }
|
133
|
+
: function(geoms, i) { if (filter(geoms[0], geoms[geoms.length - 1])) arcs.push(i); });
|
141
134
|
} else {
|
142
|
-
for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(
|
135
|
+
for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);
|
143
136
|
}
|
144
137
|
|
145
138
|
return object(topology, {type: "MultiLineString", arcs: merge(topology, arcs)});
|
146
139
|
}
|
147
140
|
|
141
|
+
function featureOrCollection(topology, o) {
|
142
|
+
return o.type === "GeometryCollection" ? {
|
143
|
+
type: "FeatureCollection",
|
144
|
+
features: o.geometries.map(function(o) { return feature(topology, o); })
|
145
|
+
} : feature(topology, o);
|
146
|
+
}
|
147
|
+
|
148
|
+
function feature(topology, o) {
|
149
|
+
var f = {
|
150
|
+
type: "Feature",
|
151
|
+
id: o.id,
|
152
|
+
properties: o.properties || {},
|
153
|
+
geometry: object(topology, o)
|
154
|
+
};
|
155
|
+
if (o.id == null) delete f.id;
|
156
|
+
return f;
|
157
|
+
}
|
158
|
+
|
148
159
|
function object(topology, o) {
|
149
160
|
var tf = topology.transform,
|
150
161
|
kx = tf.scale[0],
|
@@ -155,27 +166,31 @@ topojson = (function() {
|
|
155
166
|
|
156
167
|
function arc(i, points) {
|
157
168
|
if (points.length) points.pop();
|
158
|
-
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, x = 0, y = 0, p; k < n; ++k)
|
159
|
-
(
|
160
|
-
(
|
161
|
-
|
169
|
+
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, x = 0, y = 0, p; k < n; ++k) {
|
170
|
+
points.push(p = a[k].slice());
|
171
|
+
p[0] = (x += p[0]) * kx + dx;
|
172
|
+
p[1] = (y += p[1]) * ky + dy;
|
173
|
+
}
|
162
174
|
if (i < 0) reverse(points, n);
|
163
175
|
}
|
164
176
|
|
165
|
-
function point(
|
166
|
-
|
177
|
+
function point(p) {
|
178
|
+
p = p.slice();
|
179
|
+
p[0] = p[0] * kx + dx;
|
180
|
+
p[1] = p[1] * ky + dy;
|
181
|
+
return p;
|
167
182
|
}
|
168
183
|
|
169
184
|
function line(arcs) {
|
170
185
|
var points = [];
|
171
186
|
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
|
172
|
-
if (points.length < 2) points.push(points[0]);
|
187
|
+
if (points.length < 2) points.push(points[0].slice());
|
173
188
|
return points;
|
174
189
|
}
|
175
190
|
|
176
191
|
function ring(arcs) {
|
177
192
|
var points = line(arcs);
|
178
|
-
while (points.length < 4) points.push(points[0]);
|
193
|
+
while (points.length < 4) points.push(points[0].slice());
|
179
194
|
return points;
|
180
195
|
}
|
181
196
|
|
@@ -184,12 +199,10 @@ topojson = (function() {
|
|
184
199
|
}
|
185
200
|
|
186
201
|
function geometry(o) {
|
187
|
-
var t = o.type
|
202
|
+
var t = o.type;
|
203
|
+
return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)}
|
188
204
|
: t in geometryType ? {type: t, coordinates: geometryType[t](o)}
|
189
|
-
:
|
190
|
-
if ("id" in o) g.id = o.id;
|
191
|
-
if ("properties" in o) g.properties = o.properties;
|
192
|
-
return g;
|
205
|
+
: null;
|
193
206
|
}
|
194
207
|
|
195
208
|
var geometryType = {
|
@@ -219,18 +232,15 @@ topojson = (function() {
|
|
219
232
|
}
|
220
233
|
|
221
234
|
function neighbors(objects) {
|
222
|
-
var
|
235
|
+
var indexesByArc = {}, // arc index -> array of object indexes
|
223
236
|
neighbors = objects.map(function() { return []; });
|
224
237
|
|
225
238
|
function line(arcs, i) {
|
226
239
|
arcs.forEach(function(a) {
|
227
240
|
if (a < 0) a = ~a;
|
228
|
-
var o =
|
229
|
-
if (
|
230
|
-
|
231
|
-
k = bisect(n = neighbors[i], j); if (n[k] !== j) n.splice(k, 0, j);
|
232
|
-
k = bisect(n = neighbors[j], i); if (n[k] !== i) n.splice(k, 0, i);
|
233
|
-
}), o[i] = i;
|
241
|
+
var o = indexesByArc[a];
|
242
|
+
if (o) o.push(i);
|
243
|
+
else indexesByArc[a] = [i];
|
234
244
|
});
|
235
245
|
}
|
236
246
|
|
@@ -251,13 +261,193 @@ topojson = (function() {
|
|
251
261
|
};
|
252
262
|
|
253
263
|
objects.forEach(geometry);
|
264
|
+
|
265
|
+
for (var i in indexesByArc) {
|
266
|
+
for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
|
267
|
+
for (var k = j + 1; k < m; ++k) {
|
268
|
+
var ij = indexes[j], ik = indexes[k], n;
|
269
|
+
if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
|
270
|
+
if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
|
271
|
+
}
|
272
|
+
}
|
273
|
+
}
|
274
|
+
|
254
275
|
return neighbors;
|
255
276
|
}
|
256
277
|
|
278
|
+
function presimplify(topology, triangleArea) {
|
279
|
+
var heap = minHeap(compareArea),
|
280
|
+
maxArea = 0,
|
281
|
+
triangle;
|
282
|
+
|
283
|
+
if (!triangleArea) triangleArea = cartesianArea;
|
284
|
+
|
285
|
+
topology.arcs.forEach(function(arc) {
|
286
|
+
var triangles = [];
|
287
|
+
|
288
|
+
arc.forEach(transformAbsolute(topology.transform));
|
289
|
+
|
290
|
+
for (var i = 1, n = arc.length - 1; i < n; ++i) {
|
291
|
+
triangle = arc.slice(i - 1, i + 2);
|
292
|
+
triangle[1][2] = triangleArea(triangle);
|
293
|
+
triangles.push(triangle);
|
294
|
+
heap.push(triangle);
|
295
|
+
}
|
296
|
+
|
297
|
+
// Always keep the arc endpoints!
|
298
|
+
arc[0][2] = arc[n][2] = Infinity;
|
299
|
+
|
300
|
+
for (var i = 0, n = triangles.length; i < n; ++i) {
|
301
|
+
triangle = triangles[i];
|
302
|
+
triangle.previous = triangles[i - 1];
|
303
|
+
triangle.next = triangles[i + 1];
|
304
|
+
}
|
305
|
+
});
|
306
|
+
|
307
|
+
while (triangle = heap.pop()) {
|
308
|
+
var previous = triangle.previous,
|
309
|
+
next = triangle.next;
|
310
|
+
|
311
|
+
// If the area of the current point is less than that of the previous point
|
312
|
+
// to be eliminated, use the latter's area instead. This ensures that the
|
313
|
+
// current point cannot be eliminated without eliminating previously-
|
314
|
+
// eliminated points.
|
315
|
+
if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
|
316
|
+
else maxArea = triangle[1][2];
|
317
|
+
|
318
|
+
if (previous) {
|
319
|
+
previous.next = next;
|
320
|
+
previous[2] = triangle[2];
|
321
|
+
update(previous);
|
322
|
+
}
|
323
|
+
|
324
|
+
if (next) {
|
325
|
+
next.previous = previous;
|
326
|
+
next[0] = triangle[0];
|
327
|
+
update(next);
|
328
|
+
}
|
329
|
+
}
|
330
|
+
|
331
|
+
topology.arcs.forEach(function(arc) {
|
332
|
+
arc.forEach(transformRelative(topology.transform));
|
333
|
+
});
|
334
|
+
|
335
|
+
function update(triangle) {
|
336
|
+
heap.remove(triangle);
|
337
|
+
triangle[1][2] = triangleArea(triangle);
|
338
|
+
heap.push(triangle);
|
339
|
+
}
|
340
|
+
|
341
|
+
return topology;
|
342
|
+
};
|
343
|
+
|
344
|
+
function cartesianArea(triangle) {
|
345
|
+
return Math.abs(
|
346
|
+
(triangle[0][0] - triangle[2][0]) * (triangle[1][1] - triangle[0][1])
|
347
|
+
- (triangle[0][0] - triangle[1][0]) * (triangle[2][1] - triangle[0][1])
|
348
|
+
);
|
349
|
+
}
|
350
|
+
|
351
|
+
function compareArea(a, b) {
|
352
|
+
return a[1][2] - b[1][2];
|
353
|
+
}
|
354
|
+
|
355
|
+
function minHeap(compare) {
|
356
|
+
var heap = {},
|
357
|
+
array = [];
|
358
|
+
|
359
|
+
heap.push = function() {
|
360
|
+
for (var i = 0, n = arguments.length; i < n; ++i) {
|
361
|
+
var object = arguments[i];
|
362
|
+
up(object.index = array.push(object) - 1);
|
363
|
+
}
|
364
|
+
return array.length;
|
365
|
+
};
|
366
|
+
|
367
|
+
heap.pop = function() {
|
368
|
+
var removed = array[0],
|
369
|
+
object = array.pop();
|
370
|
+
if (array.length) {
|
371
|
+
array[object.index = 0] = object;
|
372
|
+
down(0);
|
373
|
+
}
|
374
|
+
return removed;
|
375
|
+
};
|
376
|
+
|
377
|
+
heap.remove = function(removed) {
|
378
|
+
var i = removed.index,
|
379
|
+
object = array.pop();
|
380
|
+
if (i !== array.length) {
|
381
|
+
array[object.index = i] = object;
|
382
|
+
(compare(object, removed) < 0 ? up : down)(i);
|
383
|
+
}
|
384
|
+
return i;
|
385
|
+
};
|
386
|
+
|
387
|
+
function up(i) {
|
388
|
+
var object = array[i];
|
389
|
+
while (i > 0) {
|
390
|
+
var up = ((i + 1) >> 1) - 1,
|
391
|
+
parent = array[up];
|
392
|
+
if (compare(object, parent) >= 0) break;
|
393
|
+
array[parent.index = i] = parent;
|
394
|
+
array[object.index = i = up] = object;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
function down(i) {
|
399
|
+
var object = array[i];
|
400
|
+
while (true) {
|
401
|
+
var right = (i + 1) << 1,
|
402
|
+
left = right - 1,
|
403
|
+
down = i,
|
404
|
+
child = array[down];
|
405
|
+
if (left < array.length && compare(array[left], child) < 0) child = array[down = left];
|
406
|
+
if (right < array.length && compare(array[right], child) < 0) child = array[down = right];
|
407
|
+
if (down === i) break;
|
408
|
+
array[child.index = i] = child;
|
409
|
+
array[object.index = i = down] = object;
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
413
|
+
return heap;
|
414
|
+
}
|
415
|
+
|
416
|
+
function transformAbsolute(transform) {
|
417
|
+
var x0 = 0,
|
418
|
+
y0 = 0,
|
419
|
+
kx = transform.scale[0],
|
420
|
+
ky = transform.scale[1],
|
421
|
+
dx = transform.translate[0],
|
422
|
+
dy = transform.translate[1];
|
423
|
+
return function(point) {
|
424
|
+
point[0] = (x0 += point[0]) * kx + dx;
|
425
|
+
point[1] = (y0 += point[1]) * ky + dy;
|
426
|
+
};
|
427
|
+
}
|
428
|
+
|
429
|
+
function transformRelative(transform) {
|
430
|
+
var x0 = 0,
|
431
|
+
y0 = 0,
|
432
|
+
kx = transform.scale[0],
|
433
|
+
ky = transform.scale[1],
|
434
|
+
dx = transform.translate[0],
|
435
|
+
dy = transform.translate[1];
|
436
|
+
return function(point) {
|
437
|
+
var x1 = (point[0] - dx) / kx | 0,
|
438
|
+
y1 = (point[1] - dy) / ky | 0;
|
439
|
+
point[0] = x1 - x0;
|
440
|
+
point[1] = y1 - y0;
|
441
|
+
x0 = x1;
|
442
|
+
y0 = y1;
|
443
|
+
};
|
444
|
+
}
|
445
|
+
|
257
446
|
return {
|
258
|
-
version: "
|
447
|
+
version: "1.3.0",
|
259
448
|
mesh: mesh,
|
260
|
-
|
261
|
-
neighbors: neighbors
|
449
|
+
feature: featureOrCollection,
|
450
|
+
neighbors: neighbors,
|
451
|
+
presimplify: presimplify
|
262
452
|
};
|
263
453
|
})();
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: topojson-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vlad Gorodetsky
|
@@ -11,25 +11,25 @@ cert_chain:
|
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIDSDCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA1MQowCAYDVQQDDAF2MRMw
|
14
|
-
|
15
|
-
|
14
|
+
EQYKCZImiZPyLGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wHhcNMTMwNTIz
|
15
|
+
MjA0MTI3WhcNMTQwNTIzMjA0MTI3WjA1MQowCAYDVQQDDAF2MRMwEQYKCZImiZPy
|
16
16
|
LGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wggEiMA0GCSqGSIb3DQEBAQUA
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
A4IBDwAwggEKAoIBAQCtb8+GfjqcYl6M4IhIGomKsGgWEC4mwTXIq/Yl+jJAdP7s
|
18
|
+
bdV3lWnZybUPKtdHSQIJcxbm8GZspTqSqDgsECI/laTyLj7Srqcbyivf/ov50Tg1
|
19
|
+
CxMtt8STA6wNmY0ljO4SK72Pr8uQwFZIgNHBB9LcvrpmRn/TWDXlcqaq0db6QJKk
|
20
|
+
jGOv74ukiQun+saqthpxwNN6wm0rj1GDulrDuMeeMj/XDgu0piNHhBtsgQ6KrN94
|
21
|
+
cs0XGgwKihL0LdqWiOG9L8tZKeksKk72EcTpvaw1EYUfJ/rAcC8l6SluN2+BDMA0
|
22
|
+
/4LU70O+wTwHcHv2HimtKdlcpS936qOez3lXUD+3AgMBAAGjYzBhMAkGA1UdEwQC
|
23
|
+
MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSRvHatldjBIKT5agA2bnkfm4KUxTAT
|
24
24
|
BgNVHREEDDAKgQh2QGdvci5pbzATBgNVHRIEDDAKgQh2QGdvci5pbzANBgkqhkiG
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
9w0BAQUFAAOCAQEAmyGZCL6ISHS6UCkPAie1LZgyc+yS4ckMPtzBJtjODr5kfRTC
|
26
|
+
tLb9W4epJ9Aa2aGkKy/NL8MFS0BwTJmjSfufFDwFZlw0kI9aAvL4Nx9OHWNen9Dm
|
27
|
+
GtEWXXKpB0du12DBjfavJYl0QLcz18M0mtvug634t40H06GussO83uu7wHEvIPBP
|
28
|
+
Z5VMAbKvOmDgaP2I9XxZ2/lDmBKDZkVNqmqYiScw2CWsKxVPx3vhMGprTIz4O8y/
|
29
|
+
JCf887eMZl/8mEIeCLb+gH5sh5yJJpti2HTLnR4Q1QKWR/0T9tASoQPF3kL62n9+
|
30
|
+
m1B90+fEzJsBDQIAsnLPqxjivWbIIfZ7GeGZyA==
|
31
31
|
-----END CERTIFICATE-----
|
32
|
-
date: 2013-
|
32
|
+
date: 2013-09-02 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: railties
|
metadata.gz.sig
CHANGED
@@ -1,3 +1 @@
|
|
1
|
-
|
2
|
-
|��J��4�D�{~�S2��n��M�H�!a������}�K LCc�z���J�������
|
3
|
-
�9}��4��S�>g)+�\IS��~�Yc`�5Z���5l�pJT�����e��菪Kߎ��GGw@�u�����=��D���
|
1
|
+
��|�_�=H<�k��N;��^�����V|��L�/��h���P2Fм;���*7�� �@��� �TANҹ�}su^MݷpnѸ��ia�;9զm�"Y�"1���噖&r�*{�N�F^p�t�k&�JU�-��o۔R�K���U/�$Z�Ŏ,���/�]�]VZ)�d�<�Y2�>ɖoos��dl�?�#
|