-
Notifications
You must be signed in to change notification settings - Fork 0
/
ravu-r4-gath.hook
637 lines (636 loc) · 116 KB
/
ravu-r4-gath.hook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//!DESC RAVU (step1, luma, r4)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_lut4
//!SAVE ravu_int11
//!WHEN HOOKED.w OUTPUT.w / 0.707106 < HOOKED.h OUTPUT.h / 0.707106 < *
vec4 hook() {
vec4 gathered0 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, -3), 0);
vec4 gathered1 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, -1), 0);
vec4 gathered2 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, 1), 0);
vec4 gathered3 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, 3), 0);
vec4 gathered4 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, -3), 0);
vec4 gathered5 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, -1), 0);
vec4 gathered6 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 1), 0);
vec4 gathered7 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 3), 0);
vec4 gathered8 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, -3), 0);
vec4 gathered9 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, -1), 0);
vec4 gathered10 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, 1), 0);
vec4 gathered11 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, 3), 0);
vec4 gathered12 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, -3), 0);
vec4 gathered13 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, -1), 0);
vec4 gathered14 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, 1), 0);
vec4 gathered15 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, 3), 0);
vec3 abd = vec3(0.0);
float gx, gy;
gx = (gathered4[0]-gathered0[0])/2.0;
gy = (gathered1[2]-gathered0[2])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (gathered5[3]-gathered1[3])/2.0;
gy = (-gathered2[2]+8.0*gathered1[1]-8.0*gathered0[1]+gathered0[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered5[0]-gathered1[0])/2.0;
gy = (-gathered2[1]+8.0*gathered2[2]-8.0*gathered1[2]+gathered0[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered6[3]-gathered2[3])/2.0;
gy = (-gathered3[2]+8.0*gathered2[1]-8.0*gathered1[1]+gathered1[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered6[0]-gathered2[0])/2.0;
gy = (-gathered3[1]+8.0*gathered3[2]-8.0*gathered2[2]+gathered1[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered7[3]-gathered3[3])/2.0;
gy = (gathered3[1]-gathered2[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (-gathered8[0]+8.0*gathered4[1]-8.0*gathered0[1]+gathered0[0])/12.0;
gy = (gathered5[3]-gathered4[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered9[3]+8.0*gathered5[2]-8.0*gathered1[2]+gathered1[3])/12.0;
gy = (-gathered6[3]+8.0*gathered5[0]-8.0*gathered4[0]+gathered4[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered9[0]+8.0*gathered5[1]-8.0*gathered1[1]+gathered1[0])/12.0;
gy = (-gathered6[0]+8.0*gathered6[3]-8.0*gathered5[3]+gathered4[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered10[3]+8.0*gathered6[2]-8.0*gathered2[2]+gathered2[3])/12.0;
gy = (-gathered7[3]+8.0*gathered6[0]-8.0*gathered5[0]+gathered5[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered10[0]+8.0*gathered6[1]-8.0*gathered2[1]+gathered2[0])/12.0;
gy = (-gathered7[0]+8.0*gathered7[3]-8.0*gathered6[3]+gathered5[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered11[3]+8.0*gathered7[2]-8.0*gathered3[2]+gathered3[3])/12.0;
gy = (gathered7[0]-gathered6[0])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered8[1]+8.0*gathered8[0]-8.0*gathered4[0]+gathered0[1])/12.0;
gy = (gathered5[2]-gathered4[2])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered9[2]+8.0*gathered9[3]-8.0*gathered5[3]+gathered1[2])/12.0;
gy = (-gathered6[2]+8.0*gathered5[1]-8.0*gathered4[1]+gathered4[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered9[1]+8.0*gathered9[0]-8.0*gathered5[0]+gathered1[1])/12.0;
gy = (-gathered6[1]+8.0*gathered6[2]-8.0*gathered5[2]+gathered4[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered10[2]+8.0*gathered10[3]-8.0*gathered6[3]+gathered2[2])/12.0;
gy = (-gathered7[2]+8.0*gathered6[1]-8.0*gathered5[1]+gathered5[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered10[1]+8.0*gathered10[0]-8.0*gathered6[0]+gathered2[1])/12.0;
gy = (-gathered7[1]+8.0*gathered7[2]-8.0*gathered6[2]+gathered5[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered11[2]+8.0*gathered11[3]-8.0*gathered7[3]+gathered3[2])/12.0;
gy = (gathered7[1]-gathered6[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered12[0]+8.0*gathered8[1]-8.0*gathered4[1]+gathered4[0])/12.0;
gy = (gathered9[3]-gathered8[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered13[3]+8.0*gathered9[2]-8.0*gathered5[2]+gathered5[3])/12.0;
gy = (-gathered10[3]+8.0*gathered9[0]-8.0*gathered8[0]+gathered8[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered13[0]+8.0*gathered9[1]-8.0*gathered5[1]+gathered5[0])/12.0;
gy = (-gathered10[0]+8.0*gathered10[3]-8.0*gathered9[3]+gathered8[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered14[3]+8.0*gathered10[2]-8.0*gathered6[2]+gathered6[3])/12.0;
gy = (-gathered11[3]+8.0*gathered10[0]-8.0*gathered9[0]+gathered9[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered14[0]+8.0*gathered10[1]-8.0*gathered6[1]+gathered6[0])/12.0;
gy = (-gathered11[0]+8.0*gathered11[3]-8.0*gathered10[3]+gathered9[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered15[3]+8.0*gathered11[2]-8.0*gathered7[2]+gathered7[3])/12.0;
gy = (gathered11[0]-gathered10[0])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered12[1]+8.0*gathered12[0]-8.0*gathered8[0]+gathered4[1])/12.0;
gy = (gathered9[2]-gathered8[2])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered13[2]+8.0*gathered13[3]-8.0*gathered9[3]+gathered5[2])/12.0;
gy = (-gathered10[2]+8.0*gathered9[1]-8.0*gathered8[1]+gathered8[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered13[1]+8.0*gathered13[0]-8.0*gathered9[0]+gathered5[1])/12.0;
gy = (-gathered10[1]+8.0*gathered10[2]-8.0*gathered9[2]+gathered8[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered14[2]+8.0*gathered14[3]-8.0*gathered10[3]+gathered6[2])/12.0;
gy = (-gathered11[2]+8.0*gathered10[1]-8.0*gathered9[1]+gathered9[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered14[1]+8.0*gathered14[0]-8.0*gathered10[0]+gathered6[1])/12.0;
gy = (-gathered11[1]+8.0*gathered11[2]-8.0*gathered10[2]+gathered9[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered15[2]+8.0*gathered15[3]-8.0*gathered11[3]+gathered7[2])/12.0;
gy = (gathered11[1]-gathered10[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered12[1]-gathered8[1])/2.0;
gy = (gathered13[3]-gathered12[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (gathered13[2]-gathered9[2])/2.0;
gy = (-gathered14[3]+8.0*gathered13[0]-8.0*gathered12[0]+gathered12[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered13[1]-gathered9[1])/2.0;
gy = (-gathered14[0]+8.0*gathered14[3]-8.0*gathered13[3]+gathered12[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered14[2]-gathered10[2])/2.0;
gy = (-gathered15[3]+8.0*gathered14[0]-8.0*gathered13[0]+gathered13[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered14[1]-gathered10[1])/2.0;
gy = (-gathered15[0]+8.0*gathered15[3]-8.0*gathered14[3]+gathered13[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered15[2]-gathered11[2])/2.0;
gy = (gathered15[0]-gathered14[0])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
float a = abd.x, b = abd.y, d = abd.z;
float T = a + d, D = a * d - b * b;
float delta = sqrt(max(T * T / 4.0 - D, 0.0));
float L1 = T / 2.0 + delta, L2 = T / 2.0 - delta;
float sqrtL1 = sqrt(L1), sqrtL2 = sqrt(L2);
float theta = mix(mod(atan(L1 - a, b) + 3.141592653589793, 3.141592653589793), 0.0, abs(b) < 1.192092896e-7);
float lambda = sqrtL1;
float mu = mix((sqrtL1 - sqrtL2) / (sqrtL1 + sqrtL2), 0.0, sqrtL1 + sqrtL2 < 1.192092896e-7);
float angle = floor(theta * 24.0 / 3.141592653589793);
float strength = clamp(floor(log2(lambda * 2000.0 + 1.192092896e-7)), 0.0, 8.0);
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
float coord_y = ((angle * 9.0 + strength) * 3.0 + coherence + 0.5) / 648.0;
float res = 0.0;
vec4 w;
w = texture(ravu_lut4, vec2(0.0625, coord_y));
res += (gathered0[3] + gathered15[1]) * w[0];
res += (gathered0[0] + gathered15[2]) * w[1];
res += (gathered1[3] + gathered14[1]) * w[2];
res += (gathered1[0] + gathered14[2]) * w[3];
w = texture(ravu_lut4, vec2(0.1875, coord_y));
res += (gathered2[3] + gathered13[1]) * w[0];
res += (gathered2[0] + gathered13[2]) * w[1];
res += (gathered3[3] + gathered12[1]) * w[2];
res += (gathered3[0] + gathered12[2]) * w[3];
w = texture(ravu_lut4, vec2(0.3125, coord_y));
res += (gathered0[2] + gathered15[0]) * w[0];
res += (gathered0[1] + gathered15[3]) * w[1];
res += (gathered1[2] + gathered14[0]) * w[2];
res += (gathered1[1] + gathered14[3]) * w[3];
w = texture(ravu_lut4, vec2(0.4375, coord_y));
res += (gathered2[2] + gathered13[0]) * w[0];
res += (gathered2[1] + gathered13[3]) * w[1];
res += (gathered3[2] + gathered12[0]) * w[2];
res += (gathered3[1] + gathered12[3]) * w[3];
w = texture(ravu_lut4, vec2(0.5625, coord_y));
res += (gathered4[3] + gathered11[1]) * w[0];
res += (gathered4[0] + gathered11[2]) * w[1];
res += (gathered5[3] + gathered10[1]) * w[2];
res += (gathered5[0] + gathered10[2]) * w[3];
w = texture(ravu_lut4, vec2(0.6875, coord_y));
res += (gathered6[3] + gathered9[1]) * w[0];
res += (gathered6[0] + gathered9[2]) * w[1];
res += (gathered7[3] + gathered8[1]) * w[2];
res += (gathered7[0] + gathered8[2]) * w[3];
w = texture(ravu_lut4, vec2(0.8125, coord_y));
res += (gathered4[2] + gathered11[0]) * w[0];
res += (gathered4[1] + gathered11[3]) * w[1];
res += (gathered5[2] + gathered10[0]) * w[2];
res += (gathered5[1] + gathered10[3]) * w[3];
w = texture(ravu_lut4, vec2(0.9375, coord_y));
res += (gathered6[2] + gathered9[0]) * w[0];
res += (gathered6[1] + gathered9[3]) * w[1];
res += (gathered7[2] + gathered8[0]) * w[2];
res += (gathered7[1] + gathered8[3]) * w[3];
res = clamp(res, 0.0, 1.0);
return vec4(res, 0.0, 0.0, 0.0);
}
//!DESC RAVU (step2, luma, r4)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_lut4
//!BIND ravu_int11
//!SAVE ravu_int10
//!WHEN HOOKED.w OUTPUT.w / 0.707106 < HOOKED.h OUTPUT.h / 0.707106 < *
vec4 hook() {
vec4 gathered0 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-2, -1), 0);
vec4 gathered1 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 1), 0);
vec4 gathered2 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(0, -3), 0);
vec4 gathered3 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(0, -1), 0);
vec4 gathered4 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, 1), 0);
vec4 gathered5 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(2, -1), 0);
vec4 gathered6 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-3, -1), 0);
vec4 gathered7 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-1, -3), 0);
vec4 gathered8 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-1, -1), 0);
vec4 gathered9 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-1, 1), 0);
vec4 gathered10 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(1, -2), 0);
vec4 gathered11 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(1, 0), 0);
float sample0 = HOOKED_texOff(vec2(-3.0, 0.0)).x;
float sample2 = HOOKED_texOff(vec2(-2.0, 1.0)).x;
float sample32 = HOOKED_texOff(vec2(-1.0, -2.0)).x;
float sample6 = HOOKED_texOff(vec2(0.0, 3.0)).x;
float sample15 = HOOKED_texOff(vec2(1.0, 3.0)).x;
float sample59 = HOOKED_texOff(vec2(2.0, -2.0)).x;
float sample47 = HOOKED_texOff(vec2(3.0, 1.0)).x;
float sample63 = HOOKED_texOff(vec2(4.0, 0.0)).x;
float sample24 = ravu_int11_texOff(vec2(-2.0, -2.0)).x;
float sample3 = ravu_int11_texOff(vec2(-2.0, 1.0)).x;
float sample56 = ravu_int11_texOff(vec2(0.0, -4.0)).x;
float sample7 = ravu_int11_texOff(vec2(0.0, 3.0)).x;
float sample58 = ravu_int11_texOff(vec2(1.0, -3.0)).x;
float sample23 = ravu_int11_texOff(vec2(1.0, 2.0)).x;
float sample62 = ravu_int11_texOff(vec2(3.0, -1.0)).x;
float sample55 = ravu_int11_texOff(vec2(3.0, 0.0)).x;
vec3 abd = vec3(0.0);
float gx, gy;
gx = (gathered6[2]-gathered6[0])/2.0;
gy = (gathered6[1]-gathered6[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (gathered0[1]-sample2)/2.0;
gy = (-gathered9[3]+8.0*gathered1[3]-8.0*gathered0[0]+gathered6[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered8[0]-sample3)/2.0;
gy = (-gathered1[1]+8.0*gathered9[3]-8.0*gathered6[1]+gathered0[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered1[2]-gathered1[0])/2.0;
gy = (-gathered9[1]+8.0*gathered1[1]-8.0*gathered1[3]+gathered6[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered9[2]-gathered9[0])/2.0;
gy = (-sample15+8.0*gathered9[1]-8.0*gathered9[3]+gathered1[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered4[0]-sample6)/2.0;
gy = (sample15-gathered1[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (-gathered7[0]+8.0*gathered0[2]-8.0*gathered0[0]+gathered6[0])/12.0;
gy = (gathered0[1]-gathered0[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered3[3]+8.0*gathered8[3]-8.0*gathered6[1]+sample2)/12.0;
gy = (-gathered1[2]+8.0*gathered8[0]-8.0*gathered6[2]+gathered0[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered8[2]+8.0*gathered3[0]-8.0*gathered1[3]+sample3)/12.0;
gy = (-gathered9[2]+8.0*gathered1[2]-8.0*gathered0[1]+gathered6[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered3[1]+8.0*gathered8[1]-8.0*gathered9[3]+gathered1[0])/12.0;
gy = (-gathered4[0]+8.0*gathered9[2]-8.0*gathered8[0]+gathered0[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered11[3]+8.0*gathered4[3]-8.0*gathered1[1]+gathered9[0])/12.0;
gy = (-sample23+8.0*gathered4[0]-8.0*gathered1[2]+gathered8[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered4[2]+8.0*gathered11[0]-8.0*gathered9[1]+sample6)/12.0;
gy = (sample23-gathered9[2])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered2[0]+8.0*gathered7[0]-8.0*gathered6[2]+gathered0[0])/12.0;
gy = (gathered8[3]-sample24)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered7[1]+8.0*gathered3[3]-8.0*gathered0[1]+gathered6[1])/12.0;
gy = (-gathered8[1]+8.0*gathered3[0]-8.0*gathered0[2]+sample24)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered3[2]+8.0*gathered8[2]-8.0*gathered8[0]+gathered1[3])/12.0;
gy = (-gathered4[3]+8.0*gathered8[1]-8.0*gathered8[3]+gathered0[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered10[0]+8.0*gathered3[1]-8.0*gathered1[2]+gathered9[3])/12.0;
gy = (-gathered11[0]+8.0*gathered4[3]-8.0*gathered3[0]+gathered8[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered5[0]+8.0*gathered11[3]-8.0*gathered9[2]+gathered1[1])/12.0;
gy = (-gathered4[1]+8.0*gathered11[0]-8.0*gathered8[1]+gathered3[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered11[2]+8.0*gathered4[2]-8.0*gathered4[0]+gathered9[1])/12.0;
gy = (gathered4[1]-gathered4[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered7[2]+8.0*gathered2[0]-8.0*gathered0[2]+gathered6[2])/12.0;
gy = (gathered3[3]-sample32)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered2[1]+8.0*gathered7[1]-8.0*gathered8[3]+gathered0[1])/12.0;
gy = (-gathered3[1]+8.0*gathered8[2]-8.0*gathered7[0]+sample32)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered10[3]+8.0*gathered3[2]-8.0*gathered3[0]+gathered8[0])/12.0;
gy = (-gathered11[3]+8.0*gathered3[1]-8.0*gathered3[3]+gathered7[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered5[3]+8.0*gathered10[0]-8.0*gathered8[1]+gathered1[2])/12.0;
gy = (-gathered4[2]+8.0*gathered11[3]-8.0*gathered8[2]+gathered3[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered10[1]+8.0*gathered5[0]-8.0*gathered4[3]+gathered9[2])/12.0;
gy = (-gathered11[1]+8.0*gathered4[2]-8.0*gathered3[1]+gathered8[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered5[1]+8.0*gathered11[2]-8.0*gathered11[0]+gathered4[0])/12.0;
gy = (gathered11[1]-gathered11[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered2[2]+8.0*gathered7[2]-8.0*gathered7[0]+gathered0[2])/12.0;
gy = (gathered7[1]-gathered7[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-sample58+8.0*gathered2[1]-8.0*gathered3[3]+gathered8[3])/12.0;
gy = (-gathered10[0]+8.0*gathered3[2]-8.0*gathered2[0]+gathered7[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-sample59+8.0*gathered10[3]-8.0*gathered8[2]+gathered3[0])/12.0;
gy = (-gathered5[0]+8.0*gathered10[0]-8.0*gathered7[1]+gathered2[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered10[2]+8.0*gathered5[3]-8.0*gathered3[1]+gathered8[1])/12.0;
gy = (-gathered11[2]+8.0*gathered5[0]-8.0*gathered3[2]+gathered7[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered5[2]+8.0*gathered10[1]-8.0*gathered11[3]+gathered4[3])/12.0;
gy = (-sample47+8.0*gathered11[2]-8.0*gathered10[0]+gathered3[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-sample62+8.0*gathered5[1]-8.0*gathered4[2]+gathered11[0])/12.0;
gy = (sample47-gathered5[0])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered2[2]-gathered2[0])/2.0;
gy = (gathered2[1]-gathered2[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (sample58-gathered7[1])/2.0;
gy = (-gathered5[3]+8.0*gathered10[3]-8.0*gathered7[2]+gathered2[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (sample59-gathered3[2])/2.0;
gy = (-gathered10[1]+8.0*gathered5[3]-8.0*gathered2[1]+gathered7[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered10[2]-gathered10[0])/2.0;
gy = (-gathered5[1]+8.0*gathered10[1]-8.0*gathered10[3]+gathered2[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered5[2]-gathered5[0])/2.0;
gy = (-sample55+8.0*gathered5[1]-8.0*gathered5[3]+gathered10[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (sample62-gathered11[2])/2.0;
gy = (sample55-gathered10[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
float a = abd.x, b = abd.y, d = abd.z;
float T = a + d, D = a * d - b * b;
float delta = sqrt(max(T * T / 4.0 - D, 0.0));
float L1 = T / 2.0 + delta, L2 = T / 2.0 - delta;
float sqrtL1 = sqrt(L1), sqrtL2 = sqrt(L2);
float theta = mix(mod(atan(L1 - a, b) + 3.141592653589793, 3.141592653589793), 0.0, abs(b) < 1.192092896e-7);
float lambda = sqrtL1;
float mu = mix((sqrtL1 - sqrtL2) / (sqrtL1 + sqrtL2), 0.0, sqrtL1 + sqrtL2 < 1.192092896e-7);
float angle = floor(theta * 24.0 / 3.141592653589793);
float strength = clamp(floor(log2(lambda * 2000.0 + 1.192092896e-7)), 0.0, 8.0);
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
float coord_y = ((angle * 9.0 + strength) * 3.0 + coherence + 0.5) / 648.0;
float res = 0.0;
vec4 w;
w = texture(ravu_lut4, vec2(0.0625, coord_y));
res += (sample0 + sample63) * w[0];
res += (gathered6[0] + sample62) * w[1];
res += (sample2 + gathered5[2]) * w[2];
res += (sample3 + gathered10[2]) * w[3];
w = texture(ravu_lut4, vec2(0.1875, coord_y));
res += (gathered1[0] + sample59) * w[0];
res += (gathered9[0] + sample58) * w[1];
res += (sample6 + gathered2[2]) * w[2];
res += (sample7 + sample56) * w[3];
w = texture(ravu_lut4, vec2(0.3125, coord_y));
res += (gathered6[3] + sample55) * w[0];
res += (gathered0[0] + gathered5[1]) * w[1];
res += (gathered6[1] + gathered10[1]) * w[2];
res += (gathered1[3] + gathered5[3]) * w[3];
w = texture(ravu_lut4, vec2(0.4375, coord_y));
res += (gathered9[3] + gathered10[3]) * w[0];
res += (gathered1[1] + gathered2[1]) * w[1];
res += (gathered9[1] + gathered7[2]) * w[2];
res += (sample15 + gathered2[3]) * w[3];
w = texture(ravu_lut4, vec2(0.5625, coord_y));
res += (gathered0[3] + sample47) * w[0];
res += (gathered6[2] + gathered11[2]) * w[1];
res += (gathered0[1] + gathered5[0]) * w[2];
res += (gathered8[0] + gathered10[0]) * w[3];
w = texture(ravu_lut4, vec2(0.6875, coord_y));
res += (gathered1[2] + gathered3[2]) * w[0];
res += (gathered9[2] + gathered7[1]) * w[1];
res += (gathered4[0] + gathered2[0]) * w[2];
res += (sample23 + gathered7[3]) * w[3];
w = texture(ravu_lut4, vec2(0.8125, coord_y));
res += (sample24 + gathered11[1]) * w[0];
res += (gathered0[2] + gathered4[2]) * w[1];
res += (gathered8[3] + gathered11[3]) * w[2];
res += (gathered3[0] + gathered3[1]) * w[3];
w = texture(ravu_lut4, vec2(0.9375, coord_y));
res += (gathered8[1] + gathered8[2]) * w[0];
res += (gathered4[3] + gathered3[3]) * w[1];
res += (gathered11[0] + gathered7[0]) * w[2];
res += (gathered4[1] + sample32) * w[3];
res = clamp(res, 0.0, 1.0);
return vec4(res, 0.0, 0.0, 0.0);
}
//!DESC RAVU (step3, luma, r4)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_lut4
//!BIND ravu_int11
//!SAVE ravu_int01
//!WHEN HOOKED.w OUTPUT.w / 0.707106 < HOOKED.h OUTPUT.h / 0.707106 < *
vec4 hook() {
vec4 gathered0 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, 0), 0);
vec4 gathered1 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, -2), 0);
vec4 gathered2 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 0), 0);
vec4 gathered3 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 2), 0);
vec4 gathered4 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, -1), 0);
vec4 gathered5 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, 1), 0);
vec4 gathered6 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-3, -1), 0);
vec4 gathered7 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-2, 1), 0);
vec4 gathered8 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-1, -3), 0);
vec4 gathered9 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(-1, -1), 0);
vec4 gathered10 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(0, 1), 0);
vec4 gathered11 = ravu_int11_mul * textureGatherOffset(ravu_int11_raw, ravu_int11_pos, ivec2(1, -1), 0);
float sample24 = HOOKED_texOff(vec2(-2.0, -1.0)).x;
float sample3 = HOOKED_texOff(vec2(-2.0, 2.0)).x;
float sample56 = HOOKED_texOff(vec2(0.0, -3.0)).x;
float sample7 = HOOKED_texOff(vec2(0.0, 4.0)).x;
float sample58 = HOOKED_texOff(vec2(1.0, -2.0)).x;
float sample23 = HOOKED_texOff(vec2(1.0, 3.0)).x;
float sample62 = HOOKED_texOff(vec2(3.0, 0.0)).x;
float sample55 = HOOKED_texOff(vec2(3.0, 1.0)).x;
float sample0 = ravu_int11_texOff(vec2(-4.0, 0.0)).x;
float sample2 = ravu_int11_texOff(vec2(-3.0, 1.0)).x;
float sample32 = ravu_int11_texOff(vec2(-2.0, -2.0)).x;
float sample6 = ravu_int11_texOff(vec2(-1.0, 3.0)).x;
float sample15 = ravu_int11_texOff(vec2(0.0, 3.0)).x;
float sample59 = ravu_int11_texOff(vec2(1.0, -2.0)).x;
float sample47 = ravu_int11_texOff(vec2(2.0, 1.0)).x;
float sample63 = ravu_int11_texOff(vec2(3.0, 0.0)).x;
vec3 abd = vec3(0.0);
float gx, gy;
gx = (gathered0[2]-gathered0[0])/2.0;
gy = (gathered0[1]-gathered0[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (gathered6[1]-sample2)/2.0;
gy = (-gathered3[3]+8.0*gathered7[3]-8.0*gathered6[0]+gathered0[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered2[0]-sample3)/2.0;
gy = (-gathered7[1]+8.0*gathered3[3]-8.0*gathered0[1]+gathered6[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered7[2]-gathered7[0])/2.0;
gy = (-gathered3[1]+8.0*gathered7[1]-8.0*gathered7[3]+gathered0[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered3[2]-gathered3[0])/2.0;
gy = (-sample15+8.0*gathered3[1]-8.0*gathered3[3]+gathered7[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered10[0]-sample6)/2.0;
gy = (sample15-gathered7[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (-gathered1[0]+8.0*gathered6[2]-8.0*gathered6[0]+gathered0[0])/12.0;
gy = (gathered6[1]-gathered6[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered9[3]+8.0*gathered2[3]-8.0*gathered0[1]+sample2)/12.0;
gy = (-gathered7[2]+8.0*gathered2[0]-8.0*gathered0[2]+gathered6[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered2[2]+8.0*gathered9[0]-8.0*gathered7[3]+sample3)/12.0;
gy = (-gathered3[2]+8.0*gathered7[2]-8.0*gathered6[1]+gathered0[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered9[1]+8.0*gathered2[1]-8.0*gathered3[3]+gathered7[0])/12.0;
gy = (-gathered10[0]+8.0*gathered3[2]-8.0*gathered2[0]+gathered6[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered5[3]+8.0*gathered10[3]-8.0*gathered7[1]+gathered3[0])/12.0;
gy = (-sample23+8.0*gathered10[0]-8.0*gathered7[2]+gathered2[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-gathered10[2]+8.0*gathered5[0]-8.0*gathered3[1]+sample6)/12.0;
gy = (sample23-gathered3[2])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-gathered8[0]+8.0*gathered1[0]-8.0*gathered0[2]+gathered6[0])/12.0;
gy = (gathered2[3]-sample24)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered1[1]+8.0*gathered9[3]-8.0*gathered6[1]+gathered0[1])/12.0;
gy = (-gathered2[1]+8.0*gathered9[0]-8.0*gathered6[2]+sample24)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered9[2]+8.0*gathered2[2]-8.0*gathered2[0]+gathered7[3])/12.0;
gy = (-gathered10[3]+8.0*gathered2[1]-8.0*gathered2[3]+gathered6[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered4[0]+8.0*gathered9[1]-8.0*gathered7[2]+gathered3[3])/12.0;
gy = (-gathered5[0]+8.0*gathered10[3]-8.0*gathered9[0]+gathered2[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered11[0]+8.0*gathered5[3]-8.0*gathered3[2]+gathered7[1])/12.0;
gy = (-gathered10[1]+8.0*gathered5[0]-8.0*gathered2[1]+gathered9[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered5[2]+8.0*gathered10[2]-8.0*gathered10[0]+gathered3[1])/12.0;
gy = (gathered10[1]-gathered10[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered1[2]+8.0*gathered8[0]-8.0*gathered6[2]+gathered0[2])/12.0;
gy = (gathered9[3]-sample32)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered8[1]+8.0*gathered1[1]-8.0*gathered2[3]+gathered6[1])/12.0;
gy = (-gathered9[1]+8.0*gathered2[2]-8.0*gathered1[0]+sample32)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered4[3]+8.0*gathered9[2]-8.0*gathered9[0]+gathered2[0])/12.0;
gy = (-gathered5[3]+8.0*gathered9[1]-8.0*gathered9[3]+gathered1[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered11[3]+8.0*gathered4[0]-8.0*gathered2[1]+gathered7[2])/12.0;
gy = (-gathered10[2]+8.0*gathered5[3]-8.0*gathered2[2]+gathered9[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04933151482066013;
gx = (-gathered4[1]+8.0*gathered11[0]-8.0*gathered10[3]+gathered3[2])/12.0;
gy = (-gathered5[1]+8.0*gathered10[2]-8.0*gathered9[1]+gathered2[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered11[1]+8.0*gathered5[2]-8.0*gathered5[0]+gathered10[0])/12.0;
gy = (gathered5[1]-gathered5[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (-gathered8[2]+8.0*gathered1[2]-8.0*gathered1[0]+gathered6[2])/12.0;
gy = (gathered1[1]-gathered1[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (-sample58+8.0*gathered8[1]-8.0*gathered9[3]+gathered2[3])/12.0;
gy = (-gathered4[0]+8.0*gathered9[2]-8.0*gathered8[0]+gathered1[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-sample59+8.0*gathered4[3]-8.0*gathered2[2]+gathered9[0])/12.0;
gy = (-gathered11[0]+8.0*gathered4[0]-8.0*gathered1[1]+gathered8[0])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered4[2]+8.0*gathered11[3]-8.0*gathered9[1]+gathered2[1])/12.0;
gy = (-gathered5[2]+8.0*gathered11[0]-8.0*gathered9[2]+gathered1[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.03841942237242872;
gx = (-gathered11[2]+8.0*gathered4[1]-8.0*gathered5[3]+gathered10[3])/12.0;
gy = (-sample47+8.0*gathered5[2]-8.0*gathered4[0]+gathered9[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02992107622879854;
gx = (-sample62+8.0*gathered11[1]-8.0*gathered10[2]+gathered5[0])/12.0;
gy = (sample47-gathered11[0])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (gathered8[2]-gathered8[0])/2.0;
gy = (gathered8[1]-gathered8[3])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
gx = (sample58-gathered1[1])/2.0;
gy = (-gathered11[3]+8.0*gathered4[3]-8.0*gathered1[2]+gathered8[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (sample59-gathered9[2])/2.0;
gy = (-gathered4[1]+8.0*gathered11[3]-8.0*gathered8[1]+gathered1[2])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered4[2]-gathered4[0])/2.0;
gy = (-gathered11[1]+8.0*gathered4[1]-8.0*gathered4[3]+gathered8[1])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.0233025575973275;
gx = (gathered11[2]-gathered11[0])/2.0;
gy = (-sample55+8.0*gathered11[1]-8.0*gathered11[3]+gathered4[3])/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.018148050104365175;
gx = (sample62-gathered5[2])/2.0;
gy = (sample55-gathered4[1])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.011007348802298533;
float a = abd.x, b = abd.y, d = abd.z;
float T = a + d, D = a * d - b * b;
float delta = sqrt(max(T * T / 4.0 - D, 0.0));
float L1 = T / 2.0 + delta, L2 = T / 2.0 - delta;
float sqrtL1 = sqrt(L1), sqrtL2 = sqrt(L2);
float theta = mix(mod(atan(L1 - a, b) + 3.141592653589793, 3.141592653589793), 0.0, abs(b) < 1.192092896e-7);
float lambda = sqrtL1;
float mu = mix((sqrtL1 - sqrtL2) / (sqrtL1 + sqrtL2), 0.0, sqrtL1 + sqrtL2 < 1.192092896e-7);
float angle = floor(theta * 24.0 / 3.141592653589793);
float strength = clamp(floor(log2(lambda * 2000.0 + 1.192092896e-7)), 0.0, 8.0);
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
float coord_y = ((angle * 9.0 + strength) * 3.0 + coherence + 0.5) / 648.0;
float res = 0.0;
vec4 w;
w = texture(ravu_lut4, vec2(0.0625, coord_y));
res += (sample0 + sample63) * w[0];
res += (gathered0[0] + sample62) * w[1];
res += (sample2 + gathered11[2]) * w[2];
res += (sample3 + gathered4[2]) * w[3];
w = texture(ravu_lut4, vec2(0.1875, coord_y));
res += (gathered7[0] + sample59) * w[0];
res += (gathered3[0] + sample58) * w[1];
res += (sample6 + gathered8[2]) * w[2];
res += (sample7 + sample56) * w[3];
w = texture(ravu_lut4, vec2(0.3125, coord_y));
res += (gathered0[3] + sample55) * w[0];
res += (gathered6[0] + gathered11[1]) * w[1];
res += (gathered0[1] + gathered4[1]) * w[2];
res += (gathered7[3] + gathered11[3]) * w[3];
w = texture(ravu_lut4, vec2(0.4375, coord_y));
res += (gathered3[3] + gathered4[3]) * w[0];
res += (gathered7[1] + gathered8[1]) * w[1];
res += (gathered3[1] + gathered1[2]) * w[2];
res += (sample15 + gathered8[3]) * w[3];
w = texture(ravu_lut4, vec2(0.5625, coord_y));
res += (gathered6[3] + sample47) * w[0];
res += (gathered0[2] + gathered5[2]) * w[1];
res += (gathered6[1] + gathered11[0]) * w[2];
res += (gathered2[0] + gathered4[0]) * w[3];
w = texture(ravu_lut4, vec2(0.6875, coord_y));
res += (gathered7[2] + gathered9[2]) * w[0];
res += (gathered3[2] + gathered1[1]) * w[1];
res += (gathered10[0] + gathered8[0]) * w[2];
res += (sample23 + gathered1[3]) * w[3];
w = texture(ravu_lut4, vec2(0.8125, coord_y));
res += (sample24 + gathered5[1]) * w[0];
res += (gathered6[2] + gathered10[2]) * w[1];
res += (gathered2[3] + gathered5[3]) * w[2];
res += (gathered9[0] + gathered9[1]) * w[3];
w = texture(ravu_lut4, vec2(0.9375, coord_y));
res += (gathered2[1] + gathered2[2]) * w[0];
res += (gathered10[3] + gathered9[3]) * w[1];
res += (gathered5[0] + gathered1[0]) * w[2];
res += (gathered10[1] + sample32) * w[3];
res = clamp(res, 0.0, 1.0);
return vec4(res, 0.0, 0.0, 0.0);
}
//!DESC RAVU (step4, luma, r4)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_int01
//!BIND ravu_int10
//!BIND ravu_int11
//!WIDTH 2 HOOKED.w *
//!HEIGHT 2 HOOKED.h *
//!OFFSET -0.500000 -0.500000
//!WHEN HOOKED.w OUTPUT.w / 0.707106 < HOOKED.h OUTPUT.h / 0.707106 < *
vec4 hook() {
vec2 dir = fract(HOOKED_pos * HOOKED_size) - 0.5;
if (dir.x < 0.0) {
if (dir.y < 0.0)
return HOOKED_texOff(-dir);
return ravu_int01_texOff(-dir);
} else {
if (dir.y < 0.0)
return ravu_int10_texOff(-dir);
return ravu_int11_texOff(-dir);
}
}
//!TEXTURE ravu_lut4
//!SIZE 8 648
//!FORMAT rgba16hf
//!FILTER NEAREST
010c8894c4929a12f81137937d946f0ce995e01e2c9cee164917429cef1ed1967f938f9e4221631f171e24211e9f1e92ec12b81b1c24b73214332925c31c3815330a9b900c9897194018d796218de809ea966c1ede9d3b1f681d88a00b1d7c955a9cb0a13620c9269b261e1d50a412a0aa1c0320f7239530d931c92bee2892231c030d057a0c541ab9196d8c128dac013905ed9b0e9cc1276b2663a46aa54691c997dfaa869c152d5e2d79a2fda8539aa8947ea618a5d42db32f5e2efd304724c906ae92f40a7d900c929f0cbd9249061c95281a3098421b041cc398661a8795938a5c9a9e1f29a55da5a21f459af284dd0fcf1ad6a251346c3482a27a1b5811f708be9091922a07270761930a914d096198891d089c1c17ff162a9d821d50992a9c55a10e1e1219b418771d1ba2379c8f17491ee125b732403339280722571c0809419005959c14d211b99657923109ef985819e19faf203321f59fa612df9a9c9e83a20b1d6b27aa27c41cdda341a0a61dc520db25d03029315f2a632aa2260a09109142109395c894be02ac8f2307e3925a1a8299071f141f3698271a0c912895a59b0b1cb2a8cca848197c9acb985a8d7b1f31a8e234f93414a8b71f4c1584086e8ff20ed7925f8cc18e0c87b1031b8eff190e94121b841d2698a11c2e939e9cde9f89190ca756a7cb9436a0639e0418f61baca06134a334de990320aa1d2607a3885d8c4d0dbd10ec8f01016106e0907219cd99ed18d81b049de61afe94f69f5ba2ca9b86913b955ba025a4daa18817d61bea26e8327533bf29c1243f23b509578e6d89d5979595c593f68ba701fe93ce1c3498a0218721108e941ced8ddb936b98de8a70aa8eaaa09a3098bf98939976225caa44355f3528aa3d23d593260a9490510f60924492368dd98f270a2808f8195d953b1dc11e7d0cd11c50172d98d39dac14aca80da9e89deda009a1ec9a071c91a7ce34113584a55623a7206b0661891601298e2a8f298e53847e0984075a16978dac1bf41dee8d041d0319149e8f9f4d9b5fa5ffa5cfa108a498a497986a84559427347b341d246a2425258100e088ce09de9aaf9bae8d6f8a458b2896931b19923423cb2372109a1c3294470e0c14821798abf0abb3967b0caa94879e7d24fdab7235943596abf624059c300d3e922d1123945e96cd897c958c0e188d0f18ac94f41e4d209019fd1d5e1942103b96ba1665a936aaa7a00aa27ca17e9f441b4baa0e35603541a87525c62130031484ad0129897492f090588cb30b8e89ae971596600ff41d658333207420771b771a99190da5faa6e2a2cca5b9a879a64fa39fa65d34d53410174d28222a5291d7938e1b839e1d9e001af796f58ff59bdf93631626229522521ad212139c4221568d3c2411ac48acec216983d61fdfa2482432ac68359c35eaab8224a9a00b0fd19623197898ba98f811ee984b0c8e8530952615fd1c29202c20a01a281b8118c394bc2211aa56ab5d9f0da3b8a005a0c70dc8ab0c35973545a87426ba206689980534075706439011902a0e6595d911cd9cf99bdd99ab1ca9960d21be24e51f3a246a22eea2bba632a57da79fab4ea9b1a803ab5534283502187b2bad2c0c0e7b983516899ce29c170c2699c781a58c44183b14d4239b24781cc31afa101618279b142032ac97ac4c91979b35904e9f7e25cbac8a35d83552ac3926849ccd85c09309150495879655933f9840964b16510a1d930c1b8721c11f1c1f771ee798980d1b2352a984ab7da421a378a27c9dad1f4ead0535d13551a86c28921ea2916b0fe70a0011f30c2e12b015849deb18c09e539d16a0111c279c1420b827bc8025282d262f143ea70ea712a81aadfda86fab82ae32344d35d9270d2d972ddd8ed194418c8099e998fa989e95dd93ce14181b6c171722eb23941e981c54182b97a79b261755ab49ac78a0499cca9a1a9b6525a5ac6c35dd3501ac2e26f199e991678e2d0e698bda8fb89ba396079ca7195c196c9a3519b521e820b620ae20cb9e570e8521cfa7b4abbea691a3eca2ab90062205aedc34ff3537a79d28411cc38d9f14df14d213ba159a0878199aa135153b9da7a2a09e791b3019a7170629729e0a298b28e51f50a84caa6ca62eadd3a514aca4b00234b7353f2a542e652c8299a315009ef19e5da1e99bce92c99512185f1d9e19f0274b28271d5a2031112d9cb39f732123add7ad3f19b5a0a494689f152861adaa350f36c7ac5e27759daa99119b5398ac9af79fc99f329a609c7d20811e8e1c7d21ba250925a3207f2270a17da0de0862a881ac01a866a4cea1cc1c0324c3aca634e535f69813252517d513bc1763162e1cdf0db4997199e4a34e9faf0eff9fdfa0201c9d23f7184729201d2a1eef29da2853a750ae59a948a940182daa33b26a3110365931a02eec20290df89411924d10230d3f903395f90dde96561f589a9505b711b59a551fed987792d19d4f22e11c140c3f21ce9f130fda8bd216e7216232bd336c26b11beb10f50cd48e959624176a12ba93c593740cc99897205598751c1a124ca02120049ab39b1ca14b210525f6240d187ca68c9ebf990119220ff42d9e32e62ff72a9b219c000c04bf93071c98931798b5913380c995492000a2b02172258ba4459dfe9c78949096381d1a2053268c250ca594a2e4a170a0eba7b02b952d36306832372a4e07a192da1058921e9099822f92c8047e950e1a8b98321b1c1ce998071bea95ae01099a1a203ea5b9a5e21f7f9a06846689881acfa33b348d345da2661b14142c0adc91ec92c50451092a921b94eb0a0d97711ead9a38120511079f981e309b7c9a89a01e211797cf96bd20f1a20798e694730895223d32fe339229a5227519870df2934d991e193d13cd9af6941f0a9999da1f479fd11efc1daea17a1c1f9e9b9d89a0fb2367245a250c20c9a50ca2cea1899fff224c301b31032e142d0a28bf0b4d93a3149c97e7917491338b7202aa942a1b089cb11f491f8996691937900b901a9cfd1db6a8fba87017ff9816982495811f82a8d234143517a8941f8d15c10cd994d9170b99b41448971711ca855b803d15128994153620bd9c071f3d99f790f39fe420f7a729a8779ac39efa9c13987d1207a5383402350296a620ea1c3a0d3c953b15c39717193498bf14408c2914290f8c186b9c8a1e21a21b21259e8a97fca14621c5a0179d139feda2b6a0e29e53a164208c322f345f2bfb25bb21280c1391710edb974f96ea95808c71838a94b01c209b0922c721a6143f1c110eaa0b7c99961982aad4aa6c9d8798a39a129c1f22b2aa33357d3515aa9d23600cd70c5c935717c79676093298ac80460015930d17cc9ae61cbe20b5168e1e5818bf1b309de5212da9c0a910a333a116a2f7a0319396a9a534783514a58f251722320d7095fc18be981e1686996b0ca40a6915899c1d1d019e172418a05c234f97fa1cf4a0fe24b5a8cfa662a656a0bea4cba161a270a6e7332f35f824f4265b24a3099a8da10d1e9aa29b729490927d01e3931c1b21985c2352248e17d51dba8e7209370ec41a7eab29accf9d5295a499319e412431ac5d35bb3576ab59252b98dd0aa1916414718896963f94ea98cd0591902e18439e121eb220b81ed220cf1db0192f186423fda80bab16a503a55ba4e8a2ad9b76accb34c33576a55d289f24e90811915e12480d65145195aa94a9900110b094129b689d7d1ef79488228a22021bd11d22264ca581a842a6f4a67aa944a6b3a6e7ab12348d351122a22ab8297281eb90c114239c049d62957d964d8f9791e9195099eb2358257719d11e79120417f294f22005aca0ac4c9ee398e89a4ca00925cbac5d35f43522acc126409a8e0d7896f0176e93b48c279805991897f3124117a29ea619d42084206e22d120139494195a2643a89aabc0a75ea62ea540a0b39d21ae9f341a3675a2e629a123350c299150896d90bb105d173018769cbc145f17d698979c759bdf9fa01c4227d49d03209c27fe11e4a40ca67fa834acdca1c4a925ae4233a8353f283e2d8f2a5d05ac95fa127e9ab69cc799a9983992cd14a81b0a9a9f23cf25861ee71e4d1b0a9796998521ddabf3acada27f9b829e2a9d37253bad50352a3620ac8b27f79873867e94b011e6842b15df9881987e9cf718cf17289cfb9c2521941f41240723489e070cdb2790a430ab00aa8da6a5a67c98381801b03d347036cc1de82ac021be10dd91a78fdb97a5880719a41c7b9e3c156819371bbc9b819c35a47b9cc5285aa2ff19b3267e247e195da63da837ad672177aa2bb00c328735102da72e522914089f962e15a096419a2c9c0698dc969312ce1b0e99c120b024a621d41d971bc0988c9c412142aad5ace7a41b9d0d9cfb95ed240fadfa344f360aab0d273a9dfe8c4995071014119a16b89a9496559f901b081bb09cbf9da51e86226923542441a12e9a8327f51010acd1aa4fa6bda6681b31215bb07633c536cb26ad29e120c6119d057b9711993910fe140a20cfa0fb0e3c1dd71bf0998d9cc1a387a29c2918a4150d9326bd26ba1dcda839a57bad222635a941b16f31bf356d2e162f1827a38c6c94a099309d3ba2469e4d98f48fa7141a215594762636284d233120130acf99f8a0881f99ab67aeb9a23099c49abc9e3b28faac0535773627ac8a2729a0c29521947409560c439bb49ef39d4ba0321e3d1f2d992a16811ecc26ab2449248ea187a21b24052179ac32aca7a362a6021a0627f6ae15314a37442cce1e23216411858e2996c79905123e18a11e16a2d3151f1e141ce48a9d9df9a0a8a5ed2a27a22aa3a7249e282b1ce6a8d5a196adfb262e18fcb1cb2dc7353e32832d3720c50d99951a911811100b508f1f96710f2097a01fac9a8d8dcc0e499b9d1f9d9997921f9d1b23811ce198aa214b9fb1157889a50be51f133225344d26b118808e7a0e34929b9717164f15ed97ea9608103399b221709cd418f994449e8d21f59f9498899da023c422a51f3697a4a5dc21999c1316f212b72c39348e303521a29a3403b90cb097b7140d93971446980502c499652255a0d51a200f9d9f7a24799fb11a97a222269b99d7a2ce28d9a7b616cd9c89a01ca8f1242f32ab341424c422430858938d11bf93b18f2c89a692d004a794f619bc989f1b731c7399301b78953308e39944205da520a65020169af90ae490611a6fa42a34b13437a3511bac126f0bf0922694b7093608ef917a956e0cbc960a204f9bef08e90a99a00820e89c6d98b89fbd23899f0ba00323f2a26d1883994f9c3b19d9317b342d2a5a1fc88cb00e01953096740ebf1373996298650ad4992e22559f231df396cda10b20d0a00e950ca1412669169e1d362336a4102101a1a0a2cc1c3d303c32ca30c025d21b7d0c3394911736996b8d21957185eb820b962f1c099d0320881fec94fc18e98d0711ea9c341fbba825a9861798963098f8983a20c8a8c4342f3546a80a1f7e16bb0eb8977b1bb29c031aaf9bfc16f08c0e85f4111f91ce1530216d9e921fbb9b7c1868a0fd2389a8aaa8669a559b9799b59b1a18c2a719345f35319d0820d4180a10d799c01a539d8c1d299c69182590f519a698071fb1a0b920c8a40c2383a15d18c8a2eb2524a59fa00097049e3e84c39d86a2e49e1832a734112c51240099040e6993d2127d98419623985804f88667950a1dc49c7a22f621c218d41a0e0e2615449cc41daeaafdaad99e7196fe99ac9cb02206ab23359c3543aab8235905660fbf95261aaa99c215589ca513648c2494b716189d291e6c216f1cc21c0612b41d56a05b25fba948aae6a4349dd29e04a0ca19f3aa8834d135cda543256e1c390edf98cd1ba699298e0310b79b7c18961a02a1cf2176a2012641a1c422e49daf21a5a57b2964ab95a45ba9f6200ba10f9fc89fffa85133da35031e34285b9cec0c748f121091999f9bf197639282017693e61a3d9a6723ad242d1ac21df288130f8492be1d82ab48ac45a0ce96ff98509d292446ac4a35da3576ab5825a7986c0f4694c9149d828492ec98c49af8876093051c41a0ef1e3420d222da20341c4318669be02508a9d6abc9a787a42ca0bb9ebe1a2ead93342136bca3b8273f1d5e09b890b600d217098d90138c9e9f106f0e8005479c7e9c441f952183219a1c141c26a0172953a834a90eaa73a4d2a1d49dd8a1e1ac98332f364f24952900197e0b70940815679b8d9c9e9af496568f1f0b991ad89a962304267f1c5a209916d00b0099dd21edabc8ac03a35198bd9d999efb24f8ac3d35263609ac122710995812c497e514579503184f9a079c8a98d010a41b719c009336205722cd24551f7c97bb9fa02740a689ab8daab7a621a1190851200eaf2f3489363a1c70290497180dfc8e4f8f7f9441188b171498f29bd28ce81cab9c9b8654a00320912322237399889e2e272d1612a81cabd8a924a2ad1e38a1bfae78323f36862c882a229d240d8596b2148498c09c989c04995e9352138a1c789dea223126f720fb1f2d1bad96e09bb5234eab3fad17a5a6998f9eff9b14255dad0e3572360eac0528519cca13f99521838297db1a97980d98e49de10f6b1c540b6f9e1b1c71217925ed21bf9911a3e226719181aa62ac02a8dfa13219142625b0d43208370227c9292f9f590bc5086e9176960391d21a2019159f278a231a31131418efa0d69c4b22bd25fd9860a0fd20cc253f9f66ab1aac21a3d020391e73afa5302a365330ff2952a28b0f67992318e690119b439d4e9b0791d013151d429d2520e324ec23341ff619e6986d9f262489a930ad2ba75a9b0b9b310be9241bad9534b536c0aa12274f9f6d13f89305957795f9188f923b933da0b284c41d4e15079db49a3323ff243d2331998ea4ca246f2599aa96acc3a885a1bb183f2816b02d3179374c2a6728d49c03066214f29405989697e4193c1ed9a0318eec16621deb113e9e0fa2ac217726da94fda1ec18f527f51c28ac54ab88a5cc1e14262ab0732f38364a31622813a0879035955d95e599d8a3029af09c1913bd12ae21119a152523285825341f6e999e9c72a10b1faaa9ddaefca4cf95650b7797fa27c2ac7634f9361eacae27bba23d14ca984998821534989e99419c89a001184a20991c389ba99bc425ff25d6217a9c06a5031a252831aac9accca876a03a9251295dae302d0c38e82c731f1413b910cf118696b094b496a612421fb2a1c2943117641aed1c7a9975a2411ca4277f1989a07aa1de264024dfaa15ab01a8cf9ea82a2bafc7282436bc332a9e7819ce0d20960191c6101a071d91e796a1101697b61f499bdd92a80d159ce01f5c9924932d9c6d23cb1b159d49238c9ed01546015393db1dd2316c34ea24b512959360101c94ee986115e31189982796f210c39a1223029e968a0e98f593571d24a05e9ab09b86252220069edc1473a07724d7994f9deb1a4b2c2235f12e2ba0079d4407c2180ca00f1b9c9d501ef59e2f084fa0ce27f4a4881d579f669c6227b1a3c09761a22c2a8fa568aac82911a9522aa11f5ea691a3282c9a34f131f9a20aa2b4081d94d91361946c8d2a8bb6923107c094b21aae99791bae1c0c9af21b92952c0f059a6c206ca590a62321549a8c0c8c93b81ae9a41a34d53461a4291bd7113b0c7a937d949905368ce488a697c50e559764204e9b5e8db9080da14720739d5496d69e042548a22ba44b2571a1a31a8898019eab9da73107352d28c2182a94020f83910b9c2114498b9390289cd910659c9524019fac836a97c9a2802053a1d29ae3a0fa2851a286a17f27b91b3023fa9a70a466967a303e34422d3d21e19f330eac959a18029ab8091d98320b83860497a71c169e60209b1fd8935218ea82d4168b9d5520cea84fa95b18aa906f98389bbc20fca8b834493589a8281e4217980f9b97041c7a9d8d1a839c8118ab8e6c94161a509c591d4d20a99c8a1c3b998a1a70a0b724d0a863a99f185099c495059dfd1ddca80c34aa3531a3bd1cbe169c0c0e9699898b980d193d931e900010bb106a1c3a0ef69a60170da453200aa1701188a07d26f5a4a4a597251c9dea1d0f9cbba003a4e731223570293a1cdb9ded0ffd9484152a9964943a9a6a11d78bcb95771dcd9dbf221822b0192c198c11bd16839dbb1fc7aa28ab849ecd8a769aee9c51231cab1635b53591aae822db0f65107e95171afb9a6717009e74196d9108970d1c41a07b219520422021941e0a601d92a1212661aa23abe4a3dc85b795509ec621afab7a341336d5a7a1225890b206a58ef608be14089de917b2907a15570dbc98308f6a192320011d519f51991f2107a56929ddaa6ba8aaa4dc1e141bce9edd1c1aaa3233373647a1a4244ba11d0f9b939314aa9a8e9a3a999592a60c4e93491b359b8423bc24671cd41cc18d9c105a988d1f7aab68acc5a06e895b98759c372441ac3235fa35b3ab1a25be999f106f9447154c911080e09c00984b0c0d96e41c7ca050208820c324651ca6110b1afaa0bd2664a956ac3ea8859f2307a89a66232fad65347a36eca5bc243e9ba084ea103397a41cc39b06973f9968154292f1161c9f7a1b061bac26369fb595751e7ca474294da9ceaa7ca9f313ca1fde94a02089ac3233c0364ea07b255da3080f00964217f79bfe9bc49c3195148e5801a61b699c86233526521e4e2035156610609cf922d3abe2ac75a4fa8f5d9d9d9d1b25ebac1735503619ace5263f9b4b147c98a518c09b6a1d1ca0ec9bea8ee78d0f1afb951199e521dc24d6246a9002177aa2a626aca55bacdaabbca23411bf94cf2564aeac33ff36e096ac250ba0ee8566121796ac0e251a9499359d23106994841a6a9c141990a0a6272121269b351b95a304275ba15baab2aceca123228a1556241badd0311e37c128ae1d18a3a70c09974114f395ff9c6c9d3199f688720f7a1d589e66227026d52107205a185193fa9d622412ab5bad50a63b0eb79d489a34252eadd734ac3635acc127039ef8113393190f6199d91b0f9a709e8898a79026191917f79b11172e251c26ae18bb1988a30a24c81b4cab72ad4ea45b10419a65288faeb931a7371e246f255ca1698dbe15509734101090761c3a9f7d961b93ed169195401dfda3c424d2254103231a33a16720c72157a713aeaea5d7203b95ff2594accd2f5437e62d76a4279f730c3099d716ed05139b1a9e389c11107f12bd1d139e4a1f19259824fc1ea5170d97a3a05f240ea965ad40a8d30e219b1715e524baac4734053754abba2650a0f7127e8ff78d6399e518108fc69d639dd3959d1ad4186489259e9a254326901c761b7da30c1c76258eaadead49a66d1bca9a952888add22f1238ce27e32371a1f20a370591104a999314141c859ab29d7a92e61326122519b5a1001cd227091c38165299189f552775a52eaefaa74b1ce49c4327b7acdf2d5c370d3005a8ec177014e5984c96ab8a10a4669c8e9c0617328c1b22549b59242728b625661da79bf29c4aa16c1fdea8e8aed2a6dc1cf01086134b274aac0b34643794acb62718a449124e8148980a981c123996c29e329fd38e431b041ee2167a9f13262d26191d88166aa102a02127cca8f7ad34a7bf1c649e0328caaa7e295f38bc299a1b329def0d6a0f078f3d919f9016198510a9a0b9940a13d596131e9d9f209c4f2716218d1737180fa22725680f8cad40aabc16c39e3d2560a8d11fde37cf3011a99a1f4b0eb396cd8f28114b8cb28e0498d6113d97d41f939b7c950a80d09c54201e99f7902f9c7e23bc1bc39da0242a9e64123610f5957d1ca431a8344a2197006894d8108794b2994015aa90ea98be888b0caf99b222da9c1a9cfc13129bdd180c00149b499c0226c81ef7a26323881d9c16b30c7e9e0b1b952cf7354329149fb499ff091a0c129e4f8565155f986b19c8814e9ce425a29d5aa1f49ab69a019a7022b2a0e29b3129d317e6a88f242725219e461533a6451ace2acb365f23a51c01981d0936944114a694448d3b88ef938408a994f11afa997b1bf81c5a9ba51c169538113a9a862067a5e9a63322149bf20b3b94911a25a50a34f63482a5ed1b2710930c41944694e28f7b907a0d00996c103f963e205f9b4294c715a1a1c1202d9cd794ae9d42253aa3d7a5aa2790a13e174796949c4fa188318d351e1d0316ef922610c195609cc5880496f890f99c4f113a9ace247a9cd89d669ce6a15820491c079d9ea0a429daa1b6a45129bd1f109b979844a262940c3087357a21521c35a0380fce96cc19b69b50126299be11968b0298411dbe9ef1201a1f86907117860daf186d9ecc20dfa85fa9b71929818399339c152101a9ad345c35e4a8ee1de417a4104797341c5f9e781b269d9c188e90aa98ab1dbe9fb220cd1ee29afa18dc89311cc5a0d724faa8fea9b6201499e3998d9e1c2136a90334ea3544a77319921a570ded91d99517974818f50def9ab114e4956a203e9c899052994ca459206f9df788dc9e72268ea473a70b2a6ea1d4155499579e9aa4bd319535b7214a9cc292eb105f97af18949a9f8c2b9c9814ca8d0b968e1e4e9fed2203227a1a8719911100171e9fb920c3aa44abfa9d57108f9bf79ce62322ab0a35c735e2aa5e2234147712b8963d1ba69c7619c59f6a1c12954a991e1e62a10b234c203c20039c2d18251d2da2102687aac5abfb9faf1b7a9b019f6e24afab7634403695a9fd1ea117070fcb053010c89b111b2c9d611e5998a099ab1db3a0dd217a184f94729fdb07a01d79a13f271ea90bab3324fb915118c99eaa2011aa72334536fba58295600ccf11db956815e999209b29991592370e0c95871c9b9c9523bd24a71c3a1c329129148e9b91208bab6eac9aa0fa132b97339c3e241fac2135113611ace924189a4813c19520183a986e14a79f2d1656872499131ee3a0b621f92029252b9cb514881c3da21926aca9b0ac16a78c1e5e97c69d952589ac3d34cc36bca9bb205095e10cad0f618c4f94091b0da20d212a99fd98511c76a06420791f522437a4e617071e03a3c127b9a8a8ac77a22223a810eb9d972491ab4033f836b3a803932e9827149498bd18969c079bdf9d7191a48120944f1db29dd9238026ae1e0e204f0b1e16489eeb2300acf5ac6ba43113d19c9b9d1325b8acfe34703666ace426b59b33154298ab1a389d591e29a25d911716fd97d6180697f592c822f726b71ccf9b251d20a29a2514a619ad34ab9a205513d29d5d26f5ac25336b3755a7b91e9f9abb0a370e0101cd97b71eaba20f1d9189e4960f184c9ae212311cf2277ca26b917f1cf8a09124a1a2dcac98aaf7263e9a9d9dc224acaab631a93785a528a2ae1804126a98541526976e9dff9d0298ee112f90661ed69ead22d2260d22d21e470ac60ac09f8b2433ab76ad66a6f71bb89cf8992225c7acb334d736a3ac7227859eea0fda90ae105798751b159f6f9ec71871946218750375915b1b5b281a21569b111b63a02d201294bdac6aad54229d92e29de82644ac4a31173853a6bc1f989c6e07e80eb9084798891db59e009afe155295d51448979017229e822809975697441a889c401d2a1e1fac58ad9527759ecd9dcf23fda806301338c6152aa5ae1ed512bb996215ae0f4a9cf69e4e9afd16da90061f8c9e07207125c324531d5b90c4853da1232422a974ad85a82e1ec19a7a1097241fac1434403743ac552620a0e0123b940f84dd9888193e9bd6a06f18dc942b1acd139218979a67283624b29d0f19fd9e689489212aac55ae2720441a099bac2535aa802f5338cca3191cc09df60de38c4f143c99151b7287f59f7216de92660ac68822153da18127d521f19a0b175989a19bee24c3aa55ae0b25549c3e9d192378a8af2d3b38a0240fa5781ee8121e9704992417c5a3a79c279d711b7e94cf21379d6d24112820256e1ce99d2b9cc3a0571fb9a8d4aef6a60c21f110c519202662aba833a4374faded2772a42d109a91df949a8e1c8a5b95f2a1521239929416e01b2417299c9a27d324899d4118129ddc9da62428aa95aec01d911afb9a94233aa7412b8a38679c27147b991e0fe189e80e0994f9137819e29e0e995093c61192979f1cc6a2d5247d25bf93751292145a9d762416a6d3aef78c00927f97b91d30a34f25833823276ba14819f90e41973c8e40112d90288c81987b123e970020f39bd497b90bcf9db320fc98748fe59b7523731c949b56252c9eda00d6102297721c8031cd345e170982f19362108b96cd9779149a96989706956f10e997f2217c9c749d9316549eb11f3a15fa99f89c7b25921cdba02028ed9b39994a163b9d4a19ea2c3a36df1ca59143967008f6892c9a5b14499601011096e4827493b32065982da1bc0bd79aed1c1d1f4f9ce2935026c61829a051276d9cde98750ebfa07b983c274337ec9dd214ab969c0a2795b31467950b0a458e319481090095bf1baa9a9f1ba91cf49b4f1d159472138d9ab7205ea5f2a60823009c048ba2942f1b4ea5fd330c3579a61c1cde0ff40c5194d192e2927e8f2211c39a84124395fe1f0a9cfc953519a9a200226d9b5594949cbc24d2a283a6c528bca266141994cc9816a25d31ed3599a4b1183890440bbd901c9c87021f98ff8a7a9c8b14db946d22b599de9ebc9831a2882394959d9c969a2627389c72a4422b60a16e94b090b39e399ae32d6036b2a1e194fb99471012987e1a5c9c2a16b49a3312388c6098f01d959f37217a1e4b8a4f1897113a1a5e9f5721f2a861a9d71b6d00ca9ab19c6b21fca8a634673536a9071ee9176812d298ef1cb19ff31c569e2919e492e799691fffa0e121971d4b9a301902180c1d11a1c324f8a846aa7523d299e19df99f1a2209a9eb331b3692a9971b441d1c0d599293951a958c144e13cd9d8318d2940a202a9c4597019569a4f322bd9dd092a29c852501a4fca71b2b33a471106a97039bbaa32d312c3685a5739693149e11eb9723190d9cfa10959c0b13f38c2797b31f4da07123f5211a18341b6513271860a08121deaa45ab159c3013919cab9cec23f6aa0435ce352eabf321bc15fa14a499d21c769e3b1dbda0d11c99976a9a8120baa20624cd1f181e909a0a1d191d29a3f62599aafaab3681f31cc0a0ec9fcc2406ab7134593666ab231e5c1e231411955618f29ddd1d4a9d591a1098069b861f7ea00a212f19ca9fc914a51a481ca9a0c225c2a8faaae4275d9eda9dea9ed620f4a845336c36dfa9b90a651e9513f49641159e9af2999099b290d50ea497121eba9dda23fa2469197a1ca6915716119ed521ccab76aca09e9616c698169c4b24fdab153522365cace1243c994316869aa71cfd9c901c7aa14a1d0d98a89a3420dca15f226721f8236e9f5e1d3e1d99a24625d0a9c1ac52a4472214a117a0f72405ab2034f63654ac6b20fd1dea1441911c17d89cb91d0aa16820409c1d9c0c1d4c9f04208b21bb18aba03520671eafa08125c1a8ccacf921731d42a175a0f42168a942330d373cacbc1dcf1f4d16c299f118019c9f9c559dae0f91904299b22079a14b24d0276a096a20e30ce218b5a16e2672ac38ad299f11987b9c979cd524beac07357d36f9ace227d99c0c19819ba01db99d431deda2d91e94964d9c511c4e9f2c18bb24d8252ca2dc1b611faca12d27b4a874adeda7e12407a05a9f7e2209ab1b33983757ace821b01a2e13af8a4b14b598e61a0ea14f20109bb099f1153598418e8d2485204ea2f31ee01c249d6a221ea5d3ad1f9ab322c9a0949ea01f0ea81c32bd37bbaca91e731e2517529aaf15c6939f9f019d858f740b6a99fb2051a1ab232328971d051f83860d16b5a1062616acabad10a48f181e9c60978c2480acb234ed3663ad462801a0271807995b150596171913a3c81cab93aa9a2c1eed9cba142b243e2815a14b1bfe1a47a0112468a5bfad44ab7e261ea1bb9b0f2282a9ca312638aeac3f24918c63136c8e631323983b1c9ba1271fde994498f4108f8da299572304259ea25d1e181b1d998a1ea09fd9ada8a693249ba03d9d941de3a5e430263886ac891e121dce15b9990a1498114d9e019eae9833196598ff1fa69f152159261624631a2b970114eda02424f3a968ad63a8cb21139cac10372304ab04346037fdac8426ce9f8b16179837058889d8164ca13798031a44986d1c6097d80fec20e428229a29987d15559c331d699f48ad39ad9d27ef9f8a947c1fe9a66230693849ac3122b1939716b69570145798a01c82a0a5180791a0980116d78d6d9a791fd62638a0ce1981180595d91b62174aad50aa0625139f9b9ac7196fa4782f5b38cfab531ea61add13d39af60e6d1234a42e96fb9c571bc99b4223f9a07b2530284e248717b19d838e34a2e520f4a9c1aecfa51523770e331668261fab0134a4372eae02287aa4c3159c982892121a0d9a25a01b9dcb1c42985c1cfd947995422238288884f79c4d161b9d9a1d478d0aadf9acf1263a9e0f82011f31a61b2f7f3807acd223849cba1504961d12cb910118aa9a349a2b140997471767923f98f60aed25d013df923415fc931919291fcbaa6dacc922d49a7a9553147fa1d92b803830a84d1c6b13f60e3e97448f0f1107948100fc9877124297f81fe59b0197df81319eb3208098118ef39b6f23721c3a175525d59d408c7811ae97741c8131cd34a49bba0b4a906310e597fd993f1630964199351570108896ef21ee9c3c9d8d91e89bb91f0d95d097739c78254c19ee1c1f28569ea9976d14749d911ceb2c3936d6a0951687963e07d191769cb7102197ca98581efb07a2849d202493c6a0e4144b9d771e8f97849a4198502672983c9e7f27929bc40ae21446a1e518392744372da0340d00979b0a00957213a294de0f048b159480092795bf1b8d9a2f1b1c1c009c4f1d3194b314aa9ab7204ea579a60823f49b458e67959f1b5ea5fd330c35f2a6a91c0b0af40c439556941994389066146d9b84125194fe1f949ccc98b218bca20022c39ad2920a9cbc2417a299a4c528a9a22211e192fc95d2a25d31ed3583a635197e8f200bc894a59c50900a9a29949696fc14a3906a22829abd9ea89482a1c923af9c229ca3992327119acba14c2b4fa28688fa04ed9e219ce12d62367ea491983798471060983a1ab19ce917ca9a9711388c1298f01d5e9f6b21071e6d004f1834127e1a959f5721fca836a9d71b4a8ab49a5c9c3721f2a8a634673561a97a1e2a166812e7990c1df99f441de19d0218e492d298691f11a11a22971bd29930192919ef1cffa0c32409a992a975234b9a569eb19fe121f8a8eb331b3646aa971df31c160dca94e09260978614a910ca9d9218549209209f9c0a9b5a9636a4fd22d99d9a95289c8425b7a388a51d2b6ca485131095549700a42c312c36ffa7e7947f149e1127972718ab9cbc15919c6513f38ceb97b31f60a0ec23f3213013341b0c1323194da08121f6aa2eab159c1a18959c0d9c7123deaa0435ce3545abf521fa10fa146a9a191dec9f5c1ec0a00a1d9997a499812029a3cc24231ef31c909ad11cd21cbaa2f62506ab66ab3681181ebda0769e062499aa71345936faabcd1f3b1d2014049b461ce89e641ed89da01a0d980d95851fa8a0d520f40a609ed714541a53187ea0c225f4a8e0a9e427cd9f489df09d0921c2a845336c36faaa3219db1d9513a4975716169c3c99c698a691d40ef496121e119e4b24e12496167a1cb2904115ba9dd521fdab5caca09e691990999e9ada23ccab1535223676acfa24f2994316a89a3e1d17a0fd1d14a15e1d0d98869a342099a2f7246b2047226e9f4a1da71cdca1462505ab54ac52a4f8237aa1fd9c5f22d0a92034f636c1ac6721901ce9141d9c651e73a0cc1f41a13420409c41910b1dafa0f321be1d711daaa067201b174b9f802567a93cacf921b81809a1d69c0320c1a841330d37ccac8c21b61d4d164299e218979cd99c7b9ce30c9190c299b220b5a1d524e22711986a20ae0ff11879a16e26beacf9ac299f6a09559d019c4b2472ac07357d3638add0279f9c0c194d9c611f5a9fb01a07a0dc1b9496819b511caca17e22e821e1242ca2d91ea01d4e9f2d2709ab57aceda7d825eda2b99d2c18b4a81b33983774adbb24431d2e13af99e01c929e701ec7a0ee1e0b9bb68af115249d9f1fad1eb1224ba24d204c14359869220ea8bbac169a83200ca1b598538e1da51c32bd37d3ad8d24e31a25176a990d16609701a01e9c8386740b529afb20b5a18c2446288f18051f858faf1551a1062680ac63ad10a4971d019dc693ab2316acb234ed36abad23289f9f2718aa9afe1abb9b918c1ea14b1bab9307992c1e47a00f223f247e2615a1c81c5b15ed9c112482a9aeac44ab3e2813a30596ba1468a5ca312638bfad2b24171963134498171b3c9d111d9aa05c1edd996c8ef4101d99941d8a1e93249da2261f63138e8d8a1ee3a586aca8a604259ba12298a299a09fe4302638d9ad57233a1cce1565980114ac10ce9f139c2b973319b999ff1feda037238426cb21631aae980a14a69f242404abfdac63a81624019e98111521f3a90434603768ad59264d9e8b1644987d158a94b193ef9f2998031a17986d1c559c7c1f31229d27229a379837056097331de9a649ac39ade4284ca18889d80f699f6230693848adec20d8169616a09881189a9aa61a129fce190691b69501160595c719541e062538a0a4187014d68dd91b6fa4cfab50aad62682a057986d9a6317782f5b384aad7a1fa01cdd13c99b838e33167aa4770eb19d571bd39a422334a26826022815238717fb9cf60ef9a0e5201fab2eaecfa54e242e966d127b25f4a90134a437c1ae302834a4c31542984d160f82849c3a9ef79ccb1c9c985c1c1b9d011fd223f12688841b9d2892fd949a1d31a607acf9ac382825a0121a7995478d1b2f7f380aad42220d9ab915089734157a956b13d49ae0922c1403964717fc9352144d1cc922d113349a1c12679219197fa130a86daced25a99aca913f98291fd92b8038cbaaf80a01184b0e3d97f7903610689464121e99d611b396d41f2f9cf59597002a9e54200498cd8f939b7e237d1c4a21a024d09cb28e28117c95bc1ba431a834c39d0a804b8cd810af99149bb30cb4999c160c008b0c8794b222499c7e9e149f881ddd18be88b299da9c02260b1b43296323129bea9840151a9cc81e952cf735f7a2fc13aa90ff094e9cb2a046150198219e7022c8811a0ce425e29b33a6a51c2725019a6b19129ea29d3129451a5f238f24b69a5f984f855aa1d317ce2acb36e6a8f49a65151d09a99438113b942710f20b169584083694f11a3a9a911aed1b149ba51cef934114fa99862025a582a533225a9b3b88a6947b1b67a50a34f634e9a6f81c448d930c3f96d7944796ef923e172d9c6c1041943e20ae9d949c031690a1c120009946945f9b42254fa11e1daa27a1a17a0de28f42943aa388318d35d7a5c7157b9026103a9a079d979835a0109b491c4f11c195ce249ea044a2521cbd1f5820f99c609c7a9ca42962947a215129e6a1f890c588d89ddaa10c308735b6a4669c0496380f0298af18339ce4178399860d968bce96411d6d9e1521ee1d29817117be11cc19be9ecc2001a9e4a8b71986906299b69bf120dfa8ad345c355fa91a1f5012a410aa98311c8d9e921ae399dc898e904797ab1dc5a01c2173191499fa189c18341cbe9fd72436a944a7b620e29a269d5f9eb220faa80334ea35fea9cd1e781b570de495f7885499c292d4156f9db114ed916a20dc9e579e4a9c6ea15920ef9ad9953e9c72269aa4b7210b2a4ca4f50d179789908ea4bd31953573a752994818eb100b960017f79c34148f9b9111ca8d5f978e1e1e9fe6235e22571087199814af184e9fb92022abe2aafa9d7a1a2b9c949aed22c3aa0a35c73544ab03229f8c77124a99251d019fa1177a9b2d181295b8961e1e2da26e24fd1eaf1b039c6a1c3d1b62a11026afab95a9fb9f3c20c59fa69c0b2387aa76344036c5ab4c207619070fa099a01dc99e600c5118db075998cb05ab1d79a1aa208295fb91729f611e3010b3a03f2711aafba533244f942c9dc89bdd211ea9723345360bab7a18111bcf110c952914339c189a2b973291370edb95871c8e9b3e24e924fa133a1c159268159b9c91201fac11ac9aa0a71c2999e99995238bab213511366eacbd24209b48132499881cc69d50955e97b5145687c195131e3da29525bb208c1e2b9c2d162018e3a0192689acbca916a72925a79f3a98b621aca93d34cc36b0acf9206e14e10cfd98071eeb9d2e98a810e6172a99ad0f511c03a397240393222337a40d21618c76a0c12791abb3a877a252240da24f946420b9a84033f836a8ac791f091b271420941e169b9db59bd19c4f0ba48194984f1d489e1325e42631130e207191bd18b29deb23b8ac66ac6ba4ae1edf9d969cd92300acfe347036f5ac8026079b3315fd97251dd29d9f9a5513cf9b17164298d61820a25d26b91e9a20b71c5d91ab1a06979a25f5ac55a734abf72629a2389df59214a625336b3719adc822591ebb0ae4967f1c9d9dae183e9a6b919189370e0f18f8a0c22428a2f7267ca20f1d01014c9a9124acaa85a598aaf227aba2cd97e212a1a2b631a937dcac311cb71e04122f90c60af899859eb89c470aee116a98661ec09f22257227f71bd21e02985415d69e8b24c7aca3ac66a60d22ff9d2697ad2233abb334d73676add2266e9dea0f7194111be29d989c9d92569bc718da90621863a0e826bc1f54221a216f9eae1075032d2044ac53a66aad5b28159f5798759112944a311738bdac5b1b751b6e075295441acd9dae1e759e5697fe15e80ed514889ccf232aa595270997009ab9084897401dfda8c61558ad8228b59e479890172a1e063013381fac229e891dd512da90c4857a1020a0c19a5b90fd16bb99061f3da1972455262e1e531d4e9a62158c9e23241fac43ac85a8c324f69eae0f072022a91434403774ad71254a9ce012dc940f19099bc09d441ab29d6f183b942b1afd9eac25191c27203624d6a00f84cd13689435aacca355ae67283e9bdd9892188921802f53382aac979a8819f60dde920b173e9d781e549cf19a7216e38c660a598919230fa50b25d521f59f4f14c688a19b78a8a02455ae812772873c992215ee24af2d3b38c3aa3da1151be8127e942b9cc51972a4f110e99d711b1e97cf21c3a02026ed270c216e1c279d0499379d571f62ab4fadf6a62025a79c24176d24b9a8a833a437d4ae1128c5a32d1039924118fb9a7b99911a899d52129a919416129d94232714c01dd324f2a1df94e01bdc9d3aa7679c95ae9a275b959a8e2417a624412b8a3828aa299c1c8a1e0f509375127f9748190092bf930e99e189c6119214b91d6ba1f78c7d25e29ee80e92975a9d30a32327d3aed524781909949f1c76244f25833816a6c6a2f913ce0d1697249346019593d0155c99a1102096b61f2d9c5393b5128c9ee01fe7960191499b6d23db1dea244923159c1d91c610dd92cb1bd2316c34159da80d1a076010c39a5e9ad799079d772424a0f2101c941223b09b4f9d2ba073a0571d2796ee98029e8625eb1af12edc14f59389986115968a22204b2c2235069e0e98e31144074fa0c097a11f0aa2522ab1a32f08c218ce2761a25ea6f9a211a96227f59e0ca0f4a42c2a91a3f131c829669c501e0f1b881d8fa5282c9a3468aa579f9c9db408c0942c0f8c93d7118c0c929531071d94b21a059ab81a291b549af21bb692d913ae996c20e9a461a423210c9a2a8b6194791b6ca51a34d53490a6ae1c6c8d3b0c5597549688982a94a31a739dc50e7a936420d69e019ec21871a14720a6977d944e9b0425ab9d2d284b250da1e48899055e8d48a2a73107352ba4b908368c020f659cd29afa9ae19f302353a1d91083919524e3a070a43d21b91b8020289c0b9c019ffa286696422d7f27c9a293902114ac8351a27a303e3486a16a97498b330e0497d416389b42176f98ea828386ac95a71c8b9dbc20281eaa905218320b9a18169e5520fca889a85b18d8931d98029a6020cea8b83449354fa99b1fb809980f6c948a1a059dbe16c4953b99ab8e9b97161a70a0fd1dbd1c50998a1c8118041c509cb724dca831a39f18a99c839c7a9d591dd0a80c34aa3563a94d208d1a9c0cbb1070110f9cdb9dea1d0aa100100e966a1c88a0bba03a1c1c9d53201e9099893a0e7d2603a4702997250da43d938b98f69af5a4e7312235a4a560170d19ed0fcb95bd16ee9cdb0f769a8c11d78bfd94771d839d5123e822cd8a2c196a118415cd9dbb1f1cab91aa849eb0193a9a2a99bf22c7aa1635b53528ab1822649465100897601d509e5890b7951e0a6d917e950d1c92a1c621a122dc8521947419171a41a02126afabd5a7e4a34220009efb9a7b2161aa7a34133623ab95206717b206570d1f21ce9e4ba1141b51997a15a58ebc9807a5dd1ca424dc1e519fb290f608308f69291aaa47a1aaa4011de917be146a19ddaa323337366ba82320089d1d0f4e939c10759cbe995b98c18da60c9b93491b5a9837241a256e89d41c95929314359b8d1f41acb3abc5a0671c3a99aa9a84237aab3235fa3568acbc248e9a9f100d960b1aa89a3e9b2307a6114b0c6f94e41cfaa06623bc24859f651c009847157ca0bd262fadeca53ea8c324e09c4c91502064a965347a3656ac88201080a0844292751ede945da3ca1fb5956815ea10f1167ca4a0207b25f313369f3f9933971c9f742989ac4ea07ca9ac260697a41c7a1b4da93233c036ceaa061bc39b080f580166109d9d3f9b5d9d3515148e0096a61b609c1b25e526fa8f4e2031954217699cf922ebac19ac75a4521ec49cf79b8623d3ab17355036e2ac3526fe9b4b14e78d0217bf940ba034116a90ea8e7c980f1a7aa2cf25ac25bca2d624ec9ba518fb95a62664aee096daabdc241ca0c09b1199aca5ac33ff365bace5216a1dee856994351b8a1518a32322269b23106612841a95a35624ae1deca12121359d17966a9c04271badc128b2aca6279499ac0e14195ba1d0311e375baa90a0251aa70c720f5193489a039eb79d5a18f68809977a1dfa9d3425c1273b0e072031994114589e62242ead35ac50a6d5216c9df395662212abd734ac365bad7026ff9cf811a790bb19419a5ca15b10ae1888983393261988a365286f254ea41c26709e190f19170a248fae1e2472ad2e250f9a6199f79bc81bb931a7374cab1117d91b698d1b93231a3b95279fd72041037d96be15ed1633a1ff2576a4aea5d2253a9f50979195672094ace62d13aec424761c3410401dc721cd2f543757a7fda31090730c7f120d97171550a0219ba51711103099bd1da3a0e524ba26d30efc1e389cd716139e5f24baac54ab40a898241a9eed054a1f0ea94734053765ad1925139bf712d395761bca9a71a16d1b901c639d7e8f9d1a7da39528e32349a64326c69df78dd4180c1c88adce27dead9a25108f639964897625d22f12388eaa259ee518f20a7a923816e49cec174b1c091cb29d3705e6135299432705a8faa7d227859a91102612189fb7ac0d302eae001c141c4a9925195527df2d5c3775a5b5a193147014328cf29c861318a4f010a79b0617e5981b224aa14b27b627dc1c661d8e9c4c96549b6c1f4aac94acd2a6b625669cab8a5924dea80b346437e8ae272810a44912d38e8816649e329dbf1c191d329f4e81431b6aa103289a1b34a72d26c29e4898041e02a0caaabc29f7ad132639960a98e21621277e295f38cca87a9f1c12ef0db9948d17c39e9a1fbc161621a9a06a0f0a1337183d2511a940aa4f278510078fd5960fa260a8cf308cad209c16193d91131e2725d11fde37680f9d9f9f90c50d209797927889808eb1159d99710f9995a01f1f9da50bb1184b9f9d1f1f961a91ac9a1b23e51f4d26aa21499b508f18118d8d811c13322534e198cc0e0f0b7a0e33999498999ca29adc21f59f08103492b221899d13163521a4a58d21ea969b97709ca023f2128e303697449eed971716d418c422b72c3934a51ff9944f153403c499b11acd9cc422b616799f0502b90c652297a289a01424d9a77a244698b09755a022261ca8ab34ce289d9f9714b714d51a9b99f1242f32d7a2200f0d934308a7943308e490ac12f90a7895d0045893f619e399611a511b169a301ba6928d11bc9844206fa437a3502073992c89bf939f1b5da52a34b13420a6731cb18f6f0bbc966d988399c88c6d18e89c6e0cf0920a20b89f4f9c5a1ff2a208207a9526944f9bbd233b192d2a032399a0ef91b709ef08899fd9317b340ba0e90a3608b00ed4990e9501a1d21b1021d0a0650a01952e220ca1a0a2c02536a40b2062983096559f4126cc1cca303623cda17399740e231d69163d303c329e1df396bf137d0c0b960711f8987e163098e98deb8233942f1cea9c3a200a1f9896fc1871859117099d341fc8a846a88617ec94219536990320bba8c4342f3525a9881f6b8dbb0e0e857c18b59bd4189799bb9bf08cb897f41168a01a180820559b921ffc167b1b1f91fd23c2a7319d669a6d9eaf9bb29cce1589a819345f35aaa83021031a0a10f5195d18c39d00993e8483a12590d799a698c8a286a25124049e0c236918c01a071feb25e49e112c0097c8a4299c539db1a024a51832a7349fa0b9208c1d040e67952615ac9c5905fe990e0ef88669930a1d449cb022b8237196d41a5804d212c49cc41d06ab43aad99ec21823987d987a22aeaa23359c35fdaaf6214196660f2494b41d04a06e1cd29e0612648cbf95b71656a0ca194325349dc21ca513261a189d5b25f3aacda5e6a46f1c589caa99291efba98834d13548aa6c21c215390e961aaf210f9f5b9c0ba1e49d7c18df9802a1a5a5c89f3428f620c422b79bcd1bcf217b29ffa8031e5ba941a10310a69976a264ab5133da3595a40126298eec0c7693130f509da798ff98f2888201748fe61a849229245825ce96c21d639212103d9abe1d46ac76ab45a02d1af1979199672382ab4a35da3548acad249f9b6c0f60934318bb9e3f1d2ca0341cf8874694051c669bbe1ab82787a4da20c49ac91441a0e0252eadbca3c9a7d222ec989d82ef1e08a993342136d6ab342084925e096f0e141cd49d0019d2a19a1c9f10b890800526a0d8a1952973a483218c9eb600479c1729e1ac4f240eaa95219013d2177e9c53a898332f3634a9441f098d7e0b1f0bd00b999e1099bd9d9916568f7094991a0099fb24122751985a20f4960815d89add21f8ac09ac03a37f1c9e9a679b9623edab3d352636c8ac04268d9c5812d0107c971908049721a1551f8a98c497a41bbb9f51207029b7a6cd24079ce514719ca0270eaf3a1c8daa57224f9a5795009340a62f34893689ab36200318180dd28c7399ad1e229d24a22223f29bfc8ee81c889e38a1882ad8a9912314984f8fab9c2e27bfae862c1cab03208b177f949b862d1678323f3612a854a04118240d5213ad96ff9b519c8f9e2d1b5e9385968a1ce09b14250528a699fb1f0499b214789db5235dad0eac17a5f720989c8498ea224eab0e3572363fad3126c09cca13e10fbf9932192f9fdfa1ed21e49df9956b1c11a31426c92902a879250d982183540be22625b0022762ac7121979882976f9e7191d432083781aa1b1cdb1a590b278afd98d02052a221a3bd25159fc508231a60a0391eff291aac4b2220196e913113fd2073af533066abd69cd21a76961418cc25a5302a363f9fefa003918b0fd013e698310b4f9f0b9bf61907916799151d6d9fe92412275a9b341f4e9b2318429d26241badc0aa2ba7ec23439de690252089a99534b53630ade324119b6d13b2843199bb18d49c85a13d233da0f893c41d8ea43f286728c3a8ff243b9305954e15ca2416b04c2a96ac33238f927795079d6f252d31793799aab49af9180306318eda94cc1e13a088a57726d9a06214ec16fda11426622854abac213c1ef294621dec182ab04a3128ac0fa2e4190598eb11f527732f3836f51c3e9e96978790bd129e9c7797bba2650b6e9919133595ae2172a1fa27ae27cf95341ff09c5d95119a0b1fc2ac1eacfca45825029ae5991525aaa97634f936ddae2328d8a33d1401187a9c3a92141376a0d62189a0ca984a2006a55129731fcca8ff25419c4998991c031a5daee82cc9acc4259e998215389b2528302d0c3831aaa99b3498b910c2947f19cf9e781901a8a427b2a1cf11311789a0a82a2a9e15ab411c421f8696641a7aa12bafbc33dfaa75a2a612b094ed1cde26c728243640247a99b496290dde967792da8beb10130fed98f90df894561fd19dd216b11bce9f551f33951192589a4f22e7216c263f21b59a3f904d109505e11c6232bd33140cb711230df50cc998b39bbf999b218c9e049a740cd48e97201ca10119f72a7ca62120c593959655984b21220fe62f0d184ca0ba932417751c0525f42d9e32f6241a126a129c00c9957894e4a1372a94a2fe9c33800c044920909670a068320ca5459db591bf9300a2381deba736308c258ba41798071cb0211a20b02b952d5326722598934e077e95ae01668914140684ea95c804a1920e1a099a881a661b7f9a071b2f92da108b981a20cfa35da2e21fe99899825892321b3ea53b348d34b9a51c1c1e902c0a0d977c9ae69475190798309beb0adc91711e89a07308a522f1a2981e1b94ec92ad9a1e2195229229bd20079f2a92c504381217973d32fe33cf9605115109870d99999b9dcea10a280ca21f9e1f0af293da1f89a0899f142dc9a57a1cf6944d99479ffb23ff22032e0c20aea1cd9a1e19d11e67244c301b315a25fc1d3d13bf0baa940b9024958d151698379072024d932a1b1a9c811f941fff986919338ba314089cfd1d82a817a87017899674919c97b11fb6a8d2341435fba8491fe791c10c5b80f7901398ea1cfa9c3d99ca85d9943d15f39f7d12a620c39e071f1711d9171289e42007a50296779abd9c48970b999415f7a73834023529a83620b4143a0d29148a97e29ebb21b6a0259e408c3c95290ffca153a1fb25eda21b21bf143b158c18462164205f2b139f21a23498c3976b9cc5a08c322f34179d8a1e1719280c8a94aa0b129c600ca39a110e71831391b01c7c991f229d2387983f1c808c710e219b9619b2aa15aa6c9da614ea95db97092282aa33357d35d4aac7214f96d70c1593bf1bf7a0172216a2581846005c930d17309d31938f2533a18e1eac805717cc9ae52196a914a510a3b5163298c796e61c2da9a5347835c0a9be207609320d6915fa1ccba15b24bea44f97a40a7095899cf4a061a2f42656a05c236b0cfc181d1dfe2470a6f82462a618a08699be98019eb5a8e7332f35cfa617241e16a309e3937209319e2b98a499ba8e7d019a8d1c1b370e412459255295d51d9092a10d2198c41a31ac76abcf9d8e1772941e9a5c237eab5d35bb3529ac5224a29bdd0a9190b019e8a29f245ba4cf1dcd05a1912e182f18ad9b5d2803a5d220ea986414439e642376ac76a516a5b81e3f947188121efda8cb34c3350babb2209696e9080110021b44a6b8297aa98a22a9901191b094d11db3a6a22af4a68822aa945e12129b2226e7ab112242a6f7945195480d689d4ca512348d3581a87d1e65147281979104174ca0409ae89a79124d8feb90e919f2940925c126e398d11e7d96c1145099f220cbac22ac4c9e77196295239ceb2305ac5d35f435a0ac5825049d8e0df312139440a0a1232ea5d1201897789641179419b39de6295ea66e220599f017a29e5a2621ae75a2c0a7842027986e93a61943a89f341a369aabd420b48c350cbc14d49ddca18f2a34ac4227769c29915f170320c4a93e2d7fa8a01c30185089d6989c2725ae3f280ca6df9f5d176d90979cfe114233a835e4a4759bbb105d05cd140a972a9df798829e4d1b3992ac95a81b969937258b277f9be71ea998fa120a9a85213bad20acada2861ec7997e9a9f23ddab50352a36f3accf25b69c7386f718489e7c98c021a5a607237e9c7e94cf17070c3818e82a8da641248198b011289cdb2701b0cc1d00aa941fdf98e684fb9c90a43d34703630ab25212b15be103c155aa26721522937adc5287b9edd916819ff1977aaa72e3da87b9ca41ca78f371bb3262bb0102d5da635a40719db97bc9b7e240c3287357e19819ca58814089312c098fb953a9d0d9c971bdc969f96ce1b8c9ced240d271b9dd41d06982e150e9941210fad0aabe7a4a6212c9ca096c12042aafa344f36d5acb024419afe8c901b41a1681be120bda65424559f4995081b2e9a3121ad294fa6692394960710b09c83275bb0cb26d1aa8622b89a1411bf9df5107633c53610aca51e9a16c611fb0e18a4222618277bad9c29cfa09d053c1d150d35a9162f39a587a20a207b97d71b932641b16d2ecda8c1a3fe141199f099bd266f31bf35ba1d8d9c3910a38ca714cf99bc9e29a0c49a130af48f6c941a21f8a03b288a27309931204d98a0995594881ffaac27acb9a24d23469e309d762699ab0535773667ae36283ba2c295321e8ea1021a232162a649244ba021943d1f87a20627ce1ea7a3ab24f39d74092d991b24f6ae442c32accc26b49e560c2a16052115314a3779ac811e439b6411d31527a2fb26372096aded2a16a2858e1f1e2aa32e18832dd5a1a8a5a11e2996141ca724fcb13e32e6a8f9a03e18c799e48a9e28cb2dc7352b1c9d9d0512b00c4397bc929c0e1414f2904a98790df6943b1fcd9e251b611cb99f4d1ffe949f90919acc211b247e258021899a1691170f9810c81cbb323a33c1194314b00dcb0ba3982d9d1a1c1724dea0db97a20be08e841f65a1c91f33295fa4e61d058a7796689b6d22db24522c9220149f9a948717d91bd4256030be31ae25e2183c156b070098aba1b69ecb2dcc9dd79fcd0119107a216ca6c09572303fa45b9fab92c68f7181941ef511a52ea99ad5a2b793381964237a2a0529c12c1c2b53220115ab063995f48a2b10ad118485a9951606a3922e1a6e9acd1a691b559a6e1ab092580b2698ad1fbea265a2ae1fbb98d10ca7903c1b35a550346d346ca50d1c4792e00876983b9c6117581c4a9c6c99300988909f1d49a1501e122215a2991dd1901d92859b641ef8254928c91de59cd6926b01da150a18b3323f336517e1155d02a208c49c22a1f0200a29cba26f9e1207c48d081c1ea2db1fb729d5a3611828923c95629f991dfe25432a3d1d8d9ffd96e9146e205527cd3027319027132163110b09ee9233954d8d6715d99811911a071191641aad9b7f1fba1f7f9a301aa58f551086990e1c31a814a84519369801039b95081fb3a8e234f934cda8161fce948f08478ea49cff17ae1d6e9e6b93a3037f8f071add9fea1b012035a0ab1cf586580f9093ca199ea09a9963940498618e0993ea1a14a76134a3345da7751daa8cbe0512957ca03e17ad2384a2729810032484f71afda1211cb924e2a37b1cd10664890f98cb992e27de29b49f1c9c5c8d8c083f16f396df326c33ae98151a300fc209fd93da939899e093c198e28dbd01588ecf1c689877223e232c98941cf28b528933986b8b5caa28aaad9af68dc393da97a02170aa44355f358eaa87219895260a27083498ef9aa9200da15217290a9390f819d09d051c5623eca0d21cda8f590f4795cc1490a783a5e19ddb0c2c8d6692351dada8ce3411350ea9bd1e489200060a86889e18994b25d7a4b1184f0997887d17169fa6055f24b3a3511dad83a502af816b9a219133248da1bd84558d078fe11a79a5253479341aa68e1dd38f620025962c0e859e039cb2942e94588bbe88921b0d147d24f5247f0c991c4a8a9b0917928917fcab95abae967510ca8ddb9a332398ab71359435f0abcb23ac9b310d198d48107f9fc6217ca15e198e0e40920e183b96451b75250ba2fd1d7e953211a694be164baa40a8a7a09419b5892594f31e65a90e35603536aa4d206096e1029a89621ba5a64c2ae0a89120180c6c839d97e41a20a3342895a52e20b68c5e016c95a01987a6a616b3a2ee84bb901b89a90b10a55c34d43409a7dc1da3925691f49b4221dfa2a9a0d61f139cfc8fd293ec935d8d482482248283c512f4968e1b65163d2432aceaabec21531a001a839e252211ac68359c3548ac95221d9e0d0f8e85811805a0ba20b8a0281b4c0cd1962f95c494c40d74260da3a01aee9823192715bc22c8ab45a85d9f2c20f8117998fd1c11aa0c35973556ab2920ba989f890312f91f6ca9c82ccfabda2466957506e39c40249da84f2b2ca7df20de0dcb064c9b6b22edaae7170ea56196788f7906799afaa252342735d9a6951c7c90080e9f8c15184e9f849c3990fe10dc817a984318269b7e253a26969bc31a259934163c141420cbac53ac5291781c0f0c899cd42332ac8a35d83597ac9b24e29cd2854c16e7987c9d921e78a2771e4096bf93410a9e0dae1f6c2821a31b1f3f98091518931b234ead51a87da4c11f559304950b1b52a90535d13584ab87218896a991e218188909a9a42d28adc127829dc20fa49e32285eab032ddca71220ab15450a4d9d21267faed22710a7369c5412041124a0b01331344d354fa7051c9a0cdd8ece142b971a9bf199ca9a5418dd93d294181ba79b65252e26499c981c9f953f8c6c172517a5ac01ac78a0931efa988099172255ab6c35dd3549aceb23e998e791a619cb9eac90411ceca2ae20069c6a8e5c19580e06229d2891a3b620a4962e0e6b9a852105ae37a7bea6e820b89b698b3519cfa7dc34ff35b4abb521da8f248ec814b19ee2a5652c34ad04299fa11015f69c1c290bac582e3ea64118a919b2149ca29028a2b0482a47aa741946087513e29e6c1f0034b53560a8f21a8b15829912182d9c689f759da4943111c995a3155f1db39f15285e27b5a05a20ce92009e9e19732161adc7ac3f19271de99bf19ef02723adaa350f36d7ad4b285da1aa997d2070a1cc1c2517cea17f22609c119b811e7da00324132566a4a320329a53988f1cd308c3acf69801a80925c99fac9a7d2162a8a634e53581acba25f79f06145a9ff71ce717dc204aa94829e3a303180a10371e2caaa02e59a9f0185c99c816529f282a22b26a3136aee4238599d61b43a1a3285a310836b4a74a1b890c790d4a98f29014149c0ebc924397b00cfe944d1fb99f611c251bcd9e3b1ff6941691899a80217e251b24cc21919a9f90b00d4314c1193a33bb32c81c9810170fa20bdb97dea017241a1c2d9da398cb0b058ae61d5fa43329c91f65a1841fe08e9a94149f9220522cdb246d22689b77963c15e218ae25be316030d425d91b8717cd01d79fcc9dcb2db69eaba100986b07ab925b9f3fa47230c0956ca67a211910b793d5a2a99aa52ef511941e7181c68f011553221c2bc12c05297a2a642338191606a9958485ad112b10f48a3995ab06b0926e1a559a691bcd1a6e9a2e1aa392d10cbb98ae1f65a2bea2ad1f2698580b47920d1c6ca56d34503435a53c1ba79030096c994a9c581c61173b9c7698e008d190991d15a21222501e49a19f1d8890d692e59cc91d4928f825641e859b1d925d02e11565173f33b3320a18da156b0112076f9ecba20a29f02022a1c49ca20828926118d5a3b729db1f1ea2081cc48dfd968d9f3d1d432afe25991d629f3c956311132190272731cd3055276e20e9141a071191d99867154d8d3395ee920b09a58f301a7f9aba1f7f1fad9b641a119101033698451914a831a80e1c86995510ce94161fcda8f934e234b3a8081f9b95a3036b936e9eae1dff17a49c478e8f08f586ab1c35a00120ea1bdd9f071a7f8f618e049863949a999ea0ca199093580faa8c751d5da7a334613414a7ea1a09931003729884a2ad233e177ca01295be05d1067b1ce2a3b924211cfda1f71a24845c8d1c9cb49fde292e27cb990f986489300f151aae986c33df32f3963f168c08bd01e28dc198e0939899da93fd93c209f28b941c2c983e2377226898cf1c588ec393f68dad9a28aa5caa6b8b33985289989587218eaa5f35443570aaa021da97290a52170da1a920ef9a34982708260ada8fd21ceca05623051cd09df81993902c8ddb0ce19d83a590a7cc144795590f4892bd1e0ea91135ce34ada8351d66924f09b118d7a44b251899889e0a860006ad83511db3a35f24a605169f7d179788558dbd848da1332421916b9aaf81a502d38f8e1d1aa67934253479a5e11a078f588b2e94b294039c859e2c0e259662004a8a991c7f0cf5247d240d14921bbe88ca8d7510ae9695abfcab891717929b09ac9bcb23f0ab9435713598ab3323db9a8e0e5e197ca1c6217f9f4810198d310d7e95fd1d0ba27525451b3b960e184092b5899419a7a040a84baabe16a694321160964d2036aa60350e3565a9f31e2594180c9120e0a84c2aa5a6621b9a89e102b68c2e2095a5342820a3e41a9d976c83bb90ee84b3a2a61687a6a0196c955e01a392dc1d09a7d4345c3410a5a90b1b89fc8f139cd61fa9a0dfa24221f49b5691f496c5128283822448245d8dec93d293001a531aec21eaab32ac3d2465168e1b1d9e952248ac9c35683511ac2522839e4c0c281bb8a0ba2005a081188e850d0fee98a01a0da37426c40dc4942f95d196f8112c205d9f45a8c8abbc2227152319ba98292056ab97350c3511aafd1c79986695da24cfabc82c6ca9f91f03129f89de0ddf202ca74f2b9da84024e39c7506788f61960ea5e717edaa6b224c9bcb067c90951cd9a627355234faa2799a7906dc81fe103990849c4e9f15189f8c080e2599c31a969b3a267e25269b43187a980f0c781c529153accbac14203c143416e29c9b2497acd8358a3532acd423899c4096771e78a2921e7c9de7984c16d2853f981b1f21a36c28ae1f9e0d410abf935593c11f7da451a84ead1b23189309158896872184abd135053552a90b1b0495829dc12728ada42d09a91889e218a991ab151220dca7032d5eab3228a49ec20f5412369c10a7d2277fae21264d9d450a9a0c051c4fa74d353134b01324a00411dd935418ca9af1991a9b2b97ce14dd8e9f95981c499c2e266525a79b181bd294fa98931e78a001aca5ac25176c173f8ce998eb2349acdd356c3555ab17228099069cae20eca2411cac90cb9ea619e791a496b62091a39d280622580e5c196a8eb89be820bea637a705ae85216b9a2e0eda8fb521b4abff35dc34cfa73519698b9fa1042934ad652ce2a5b19ec814248ea91941183ea6582e0bac1c29f69c10154608741947aa482aa2b090289ca2b2148b15f21a60a8b53500346c1fe29e7513c9953111a494759d689f2d9c12188299ce925a20b5a05e271528b39f5f1da315e99b271d3f19c7ac61ad73219e19009e5da14b28d7ad0f36aa3523adf027f19e609c7f22cea12517cc1c70a17d20aa99329aa32066a4132503247da0811e119bc99f092501a8f698c3acd3088f1c5398f79fba2581ace535a63462a87d21ac9ae3a348294aa9dc20e717f71c5a9f06145c99f01859a9a02e2caa371e0a1003188599e42336ae6a3122b2282a529fc816890c4a1bb4a708365a31a32843a1d61bf90ded98130feb10da8b7792de96290d3395551fce9fb11bd216d19d561ff8943f90b59a3f216c26e7214f22589a1192230db711140cbd336232e11c95054d10740c049a8c9e9b21bf99b39bc998f50cc59321207ca6f72a01191ca19720d48eba934ca00d18e62f220f4b21559895966a121a12f6249e32f42d0525751c24173380fe9c94a2372ae4a17894c9959c00b591459d0ca5683270a0909649200c0417988ba48c253630eba7381d00a2bf93989372255326952db02b1a20b021071cc804ea95068414146689ae017e954e072f92071b7f9a661b881a099a0e1aa1929982e998e21f5da2cfa31a208b98da101e901c1cb9a58d343b343ea5321b5892eb0a309b07987519e6947c9a0d972c0a1b94981ef1a2a522730889a0711edc912a92079fbd20922995221e21ad9aec9251090511cf96fe333d3217973812c5041f0a1f9e0ca20a28cea19b9d9999870df6947a1cc9a5142d899f89a0da1ff293cd9aaea10c20032eff22fb23479f4d993d13fc1d5a251b314c306724d11e1e197202379016988d1524950b90aa94bf0b338b6919ff98941f811f1a9c2a1b4d9374918996701717a882a8fd1d089ca314e791491ffba81435d234b6a8b11f9c97ca853d99fa9cea1c1398f7905b80c10c1711071fc39ea6207d12f39f3d15d9944897bd9c779a029607a5e4201289d917b414362029a802353834f7a794150b99408c259eb6a0bb21e29e8a9729143a0dbf141b21eda2fb2553a1fca1290f3c95349821a2139f5f2b642046218c183b1517198a1e179d2f348c32c5a06b9cc3977183110ea39a600c129caa0b8a94280c808c3f1c87989d231f227c99b01c1391ea95a6146c9d15aab2aa9619209b710e4f96c721d4aa7d35333582aa0922db974600581816a21722f7a0bf1b1593d70cac808e1e33a18f253193309d0d175c933298b51610a314a596a9e521cc9a57177609be20c0a97835a5342da9e61cc796a40a4f97bea45b24cba1fa1c6915320d6b0c5c2356a0f42661a2f4a0899c7095869918a062a6f82470a6fe241d1dfc181e161724cfa62f35e733b5a8019ebe987d01ba8ea4992b98319e7209e393a3099092d51d529559254124370e1c1b9a8d72948e17cf9d76ab31acc41a2198a10da29b522429acbb355d357eab5c231e9acd05cf1d5ba49f24e8a2b0199190dd0aea98d22003a55d28ad9b2f182e18a1913f94b81e16a576a576ac6423439e64149696b2200babc335cb34fda8121e7188a9908a227aa9b82944a6021b0110e908aa948822f4a6a22ab3a6d11db09411915195f79442a61122e7ab2226129b5e1265147d1e81a88d3512344ca5689d480d4d8f7912e89a409a4ca00417979172817d96d11ee398c1260925f294e919eb90629577194c9e22accbacf2205099c114049d5825a0acf4355d3505aceb23239c1897d1202ea5a12340a01394f3128e0d05996e225ea6e629b39d94194117789627988420c0a775a221ae5a26a29ef017b48cd4209aab1a369f3443a8a6196e93769c422734ac8f2adca1d49dbc14350c3018a01c7fa83e2dc4a903205f1729915d17df9f0ca63f2825ae9c27d6985089bb10759be4a4a8354233fe11979c6d9039924d1b829ef7982a9d0a97cd145d05a998e71e7f9b8b2737259699a81bac95c799861eada220ac3bad85210a9afa12b69ccf25f3ac2a365035ddab9f237e9a7e9c0723a5a6c0217c98489ef7187386819841248da6e82a3818070ccf177e94df98941f00aacc1d01b0db27289cb0112b15252130ab70363d3490a4fb9ce6847b9ec52837ad522967215aa23c15be10a41c7b9c3da8a72e77aaff196819dd91071935a45da6102d2bb0b326371ba78fa588819c7e1987350c327e24bc9bdb97dc96971b0d9c3a9dfb95c098931214080698d41d1b9d0d27ed248c9cce1b9f962c9ca621e7a40aab0fad41210e992e15419ab024d5ac4f36fa3442aac120a096559f5424bda6e120681b41a1901bfe8c949669234fa6ad2931212e9a081b4995b89a8622d1aacb265bb08327b09c07109a16a51e10acc5367633f510bf9d1411cfa09c297bad1827222618a4fb0ec6110a2087a239a5162f35a9150d3c1d9d05fe14c1a3cda86d2e41b19326d71b7b9739108d9cba1dbf356f31bd26f0991199f48f130ac49a29a0bc9ecf99a714a38c4d98312030998a273b28f8a01a216c94469e4d23b9a227acfaac881f5594a0993ba2362867ae7736053599ab7626309d4ba0492462a62321021a8ea1321ec295f39dab24a7a3ce1e062787a23d1f2194b49ecc2632ac442cf6ae1b242d997409439b811e79ac4a37153105212a16560c16a2ed2a96ad3720fb2627a2d3156411a11ea8a5d5a1832d2e182aa31f1e858e3e18f9a0e6a83e32fcb1a724141c299605129d9d2b1cc735cb2d9e28e48ac799710f9d99b115808e788997922097c50d1f969d1f4b9fb118a50b1f9da01f9995508f499baa214d26e51f1b23ac9a1a91100bcc0ee19825341332811c8d8d18110810f59fdc21a29a999c949833997a0eea968d21a4a535211316899db2213492ed97449e36978e30f212a023709c9b974f15f994a51f3934b72cc422d41817160502799fb616c422cd9cb11ac499340346987a24d9a7142489a097a26522b90c97149d9fce28ab341ca8222655a0b0970d93200fd7a22f32f1249b99d51ab714d0047895f90aac12e4903308a7944308a692301b169a511b611ae399f61958932c897399502037a36fa44420bc988d11b18f731c20a6b1342a345da59f1bbf936e0ce89c6d18c88c83996d98bc966f0b7a950820f2a25a1f4f9cb89f0a20f092ef9199a003232d2a3b19bd234f9b26943608e90a0ba07b34d931899fef08b709650ad0a01021d21b01a10e95d499b00e62980b2036a4c025a0a20ca12e2201957399cda13623ca30cc1c4126559f3096bf13f3969e1d3c323d306916231d740eeb82e98d30987e16f89807110b967d0c7185fc1898960a1f3a20ea9c2f1c33942195ec94861746a8c8a8341f099d91176b8d881f25a92f35c434bba803203699f08cbb9b9799d418b59b7c180e85bb0efc16921f559b08201a1868a0f411b897af9b6d9e669a319dc2a7fd231f917b1b031a3021aaa85f35193489a8ce15b29c259083a13e840099c39d5d18f5190a1069180c23049e512486a2c8a2a698d799299cc8a40097112ce49eeb25071fc01a8c1db9209fa0a734183224a5b1a0539df8860e0efe995905ac9c26156795040e5804d41a7196b823b022449c0a1d69932398c218d99e43aa06abc41dc49cd2124196f621fdaa9c352335aeaa7a227d98648c0612d29e6e1c04a0b41d2494660fa513c21c349d4325ca1956a0b716bf95589c6f1ce6a4cda5f3aa5b25189d261ac2156c2148aad1358834fba9291eaa997c18e49d0ba15b9c0f9faf21961a390eb79bc422f6203428c89fa5a502a1df98031041a15ba9031effa87b29cf21cd1b298e012695a4da35513364ab76a2a6998201f288ff98a798509d130f7693ec0c6392c21dce96582529248492e61a748ff1972d1a45a076ab46acbe1d3d9a12109f9bad2448acda354a3582ab67239199f887341c2ca03f1dbb9e431860936c0fc49ada2087a4b827be1a669b051c4694ec98d222c9a7bca32eade02541a0c91484923420d6ab2136933408a9ef1e9d829f109a1cd2a10019d49d141c6f0e5e098c9e832173a49529d8a126a08005b890901395210eaa4f24e1ac1729479cb600098d441f34a92f36983353a87e9cd217568f9916bd9d1099999ed00b1f0b7e0bf4965a2051981227fb240099991a70949e9a7f1c03a309acf8acdd21d89a08158d9c0426c8ac26363d35edab9623679b8a98551f21a1049719087c97d0105812079ccd24b7a670295120bb9fa41bc4974f9a57228daa3a1c0eafa027719ce5140318362089ab89362f3440a600935795f29b222324a2229dad1e7399d28c180d14989123d8a9882a38a1889ee81cfc8e8b1703201cab862cbfae2e27ab9c4f8f411854a012a83f3678322d169b867f945e932d1b8f9e519cff9bad965213240d0499fb1fa69905281425e09b8a1c8596989cf72017a50eac5dadb523789db214c09c31263fad72360e354eabea228498e49ded21dfa12f9f3219bf99e10fca130d98792502a8c929142611a36b1cf9959798712162ac022725b0e226540b2183db1a1b1c81aa0837d43271916f9e8297159fbd2521a352a2d020fd98278a590b20194b221aacff29391e60a0231ac508d21ad69c66ab533073affd2031136e910391efa03f9f2a36a530cc25141876960791f6190b9b4f9f310be698d0138b0f4e9b341f5a9b1227e9246d9f151d6799439dec232ba7c0aa1bad2624429d2318119be32430adb536953489a92520e6903da03d2385a1d49cbb183199b2846d133b93ff24c3a867283f288ea4c41df8938f92332396ac4c2a16b0ca244e150595f918b49a99aa79372d316f25079d7795d9a0772688a513a0cc1eda94318e03063c1eac2154ab62281426fda1ec166214e4190fa228ac4a312ab0ec18621df29496973e9ef51c3836732ff527eb11059819136e99650bbba277979e9cbd128790f09c341fcf95ae27fa2772a1ae213595029a5825fca41eacc2ac0b1f119a5d95d8a32328ddaef9367634aaa91525e59989a0d62176a014133a927a9c01183d14419cff25cca8731f512906a54a20ca989e99c425c9ace82c5dae031a991c49983498a99b31aa0c38302d2528389b8215b2a1a42701a87819cf9e7f19c294b910421f411c15ab2a9ea82a89a03117cf11a61275a2dfaabc332baf7aa1641a8696b4967a9940242436c728de26ed1cb094a1105c99d0159593460124931697ce0de796e01f8c9eb51253932d9cb61f20961d91159c4923ea24db1d6d23499b01911a07a80d159d6c34d231cb1bdd92c610f21024a07724079dd7995e9ac39a60102796571d73a02ba04f9db09b12231c948998f593dc14f12eeb1a8625029eee98e3110e98069e22354b2c2220968a61152f08b1a3522a0aa2a11fc0974fa04407f59e622711a9f9a25ea661a2ce27c218501e669cc829f13191a32c2af4a40ca09c9d579f68aa9a34282c8fa5881d0f1b310792958c0cd7118c932c0fc094b408b692f21b549a291bb81a059ab21a1d942a8b0c9a232161a4e9a46c20ae99d9136c8dae1c90a6d5341a346ca5791b6194c50e739da31a2a948898549655973b0ca697472071a1c218019ed69e64207a93e4880da14b252d28ab9d04254e9b7d94368cb9082ba40735a73148a25e8d9905d91053a13023e19ffa9ad29a659c020f289c8020b91b3d2170a4e3a0952483919390c9a27f27422d6696fa28019f0b9c498b6a9786a13e347a3051a2ac8321148386ea826f984217389bd4160497330e320b5218aa90281ebc208b9da71cac951d98d8935b1889a8fca85520169e9a18b8099b1f4fa94935b834cea86020029aab8e3b99c495be16059d8a1a6c94980f81188a1c5099bd1cfd1d70a0161a9b97839ca99c9f1831a3dca8b724509c041c8d1a4d2063a9aa350c34d0a8591d7a9d00100aa1ea1ddb9d0f9c7011bb109c0c1e9053201c9d3a1cbba088a06a1c0e963d930da49725702903a47d263a0e99890d196017a4a52235e731f5a4f69a8b98d78b8c11769adb0fee9cbd16cb95ed0f6a112c19cd8ae8225123839d771dfd943a9ab019849e91aa1cabbb1fcd9d84156494182228abb5351635c7aabf222a996d911e0ab7955890509e601d0897651074192194dc85a122c62192a10d1c7e95009e4220e4a3d5a7afab212641a0171a6717952023ab13367a3461aa7b21fb9a7a155199141b4ba1ce9e1f21570db206b290519fdc1ea424dd1c07a5bc98a58ee917011daaa447a11aaa6929308ff608089d23206ba837363233ddaa6a19be14a60cc18d5b98be99759c9c104e931d0f9592d41c6e891a2537245a98491b9b933a99671cc5a0b3ab41ac8d1f359b93148e9abc2468acfa3532357aab8423aa9a4b0ca61123073e9ba89a0b1a0d969f100098651c859fbc246623faa0e41c6f94e09cc3243ea8eca52fadbd267ca047151080882056ac7a36653464a950204c916815b595ca1f5da3de94751e4292a0843f99369ff3137b25a0207ca4f116ea100697ac267ca94ea089ac74291c9f3397c39b061bceaac03632334da97a1ba41c148e35155d9d3f9b9d9d66105801080f31954e20fa8fe5261b25609ca61b0096c49c521e75a419acebacf922699c4217fe9b3526e2ac50361735d3ab8623f79bea8e6a9034110ba0bf940217e78d4b14ec9bd624bca2ac25cf257aa20f1a7c981ca0dc24daabe09664aea626fb95a5186a1de5215bacff36ac33aca51199c09b2310269b232218a38a15351b6994ee85359d2121eca1ae1d562495a3841a66129499a627b2acc1281bad04276a9c1796251a90a05baa1e37d0315ba11419ac0ef6885a18b79d039e489a5193720fa70c319907203b0ec1273425fa9d7a1d09976c9dd52150a635ac2ead6224589e4114ff9c70265badac36d73412ab6622f3958898ae185b105ca1419abb19a790f811709e1c264ea46f25652888a3261933930f9a2e2572ad1e248fae0a241917190fd91b11174caba737b931c81bf79b61997d964103d720279f3b95231a1b93698d3a9fd225aea576a4ff2533a1ed16be15761cc42413aee62d94ac6720919550971090fda357a75437cd2fc721401d34101110a517219b50a017150d977f12730c389cfc1ed30eba26e524a3a0bd1d30991a9e982440a854abbaac5f24139ed716139b192565ad053747340ea94a1fed05639d901c6d1b71a1ca9a761bd395f712c69d432649a6e32395287da39d1a7e8f108f9a25deadce2788ad0c1cd418f78de518259e8eaa1238d22f762564896399b29d091c4b1cec17e49c38167a92f20a859ad227faa705a843275299e6133705141c001c2eae0d30b7ac189f261291109314b5a175a55c37df2d552725194a990617a79bf01018a48613f29c328c70148e9c661ddc1cb6274b274aa11b22e598669cb625d2a694ac4aac6c1f549b4c9610a42728e8ae64370b34dea85924ab8a329f191dbf1c329d649e8816d38e4912c29e2d2634a79a1b03286aa1431b4e8139961326f7adbc29caaa02a0041e48981c127a9fcca85f387e292127e2160a98a9a01621bc169a1fc39e8d17b994ef0d85104f2740aa11a93d2537180a136a0f1619209c8cadcf3060a80fa2d596078f9f909d9f680fde37d11f2725131e3d91d6111e99641268943610f7903d974b0e049854202a9e9700f5952f9cd41fb396b28ed09ca0244a217d1c7e23939bcd8f4b8c0a80c39da834a431bc1b7c9528118b0c0c009c16b499b30c149baf99d810be88dd18881d149f7e9e499cb2228794ea98129b632343290b1b0226da9cb299aa90fc13f7a2f735952cc81e1a9c4015c8817022219e01984615b2a04e9cff096b19019a2725a51c33a6e29be4251a0c5f98b69a8f245f23451a3129a29d129e6515f49ae6a8cb36ce2ad3175aa14f8584081695f20b27103b943811a9941d09ef93a51c149bed1b911a3a9af11a36943b885a9b332282a525a58620fa994114448df81ce9a6f6340a3467a57b1ba6946c102d9c3e17ef924796d7943f96930c0099c12090a10316949cae9d3e2041947a0da1a1aa271e1d4fa142255f9b46947b90c715d7a58d3588313aa34294e28f4f11491c109b35a09798079d3a9a2610f99c5820bd1f521c44a29ea0ce24c195f890e6a151297a216294a4297a9c609c0496669cb6a487350c30daa1d89dc588968b860d8399e417339caf180298380fbe1171172981ee1d15216d9e411dce9662998690b719e4a801a9cc20be9ecc1950121a1f5fa95c35ad34dfa8f120b69b8e90dc89e399921a8d9e311caa98a4109c18fa18149973191c21c5a0ab1d4797269de29ab62044a736a9d724be9f341c781bcd1efea9ea350334faa8b2205f9eb1146f9dd415c2925499f788e495570def9a59206ea14a9c579edc9e6a20ed91f50d4ca40b2ab7219aa472263e9cd9954818529973a79535bd318ea489901797ca8d91118f9b3414f79c00170b96eb109814871957105e22e6231e9f8e1e5f972b9c7a1afa9de2aa22abb9204e9faf189f8c032244abc7350a35c3aaed22949a12952d187a9ba117019f251d4a9977126a1c039caf1bfd1e6e242da21e1eb896c59f3c20fb9f95a9afab102662a13d1b76194c20c5ab4036763487aa0b23a69c5998db075118600cc99ea01da099070f611e729ffb918295aa2079a1ab1dcb052c9d4f943324fba511aa3f27b3a03010111b7a180bab453672331ea9dd21c89b370e32912b97189a339c29140c95cf1115923a1cfa13e9243e248e9b871cdb952999a71c9aa011ac1fac91209b9c6815209bbd246eac113621358bab9523e9995687b5145e975095c69d881c249948132d162b9c8c1ebb2095253da2131ec195a79f292516a7bca989ac1926e3a020186e14f920b0accc363d34aca9b6213a982a99e617a8102e98eb9d071efd98e10c0d2137a422230393972403a3511cad0f0da2522477a2b3a891abc12776a0618c091b791fa8acf8364033b9a864204f94a4814f0bd19cb59b9b9d1e162094271471910e203113e4261325489e4f1d9498df9dae1e6ba466acb8aceb23b29dbd18079b8026f5ac7036fe3400acd923969c1716cf9b55139f9ad29d251dfd9733155d91b71c9a20b91e5d2620a2d618429829a2f72634ab55a7f5ac9a250697ab1a591ec82219ad6b37253314a6f592389d91896b913e9aae189d9d7f1ce496bb0a0f1d7ca2f72628a2c224f8a00f18370eaba2f22798aa85a5acaa91244c9a0101b71e311cdcaca937b631a1a2e212cd97ee11470ab89c859ef899c60a2f9004120298d21ef71b72272225c09f661e6a98ff9d0d2266a6a3acc7ac8b24d69e54156e9dd22676add736b33433abad222697c718569b9d92989ce29d111b7194ea0f6f9e1a215422bc1fe82663a06218da90159f5b286aad53a644ac2d207503ae10751b5b1bbdac17384a31129475915798fe155697759eae1ecd9d441a52956e07009a099795272aa5cf23889cd514e80eb59e822858adc615fda8401d4897b908891d229e1fac133806302a1e90174798fd165b90c19a20a07a10c485da90d5124e9a531d2e1e552697243da1061fbb99f69ec32485a843ac1fac23248c9e62154a9c712574ad4037143422a90720ae0f6f18b29d441ac09d099b0f19dc94e012d6a036242720191cac25fd9e2b1a3b943e9b672855aecca335aa6894cd130f848819979a2aac5338802f89219218dd987216f19a549c781e3e9d0b17de92f60df59fd5210b250fa519235989660ae38c7287812755aea02478a8a19bc6884f14151b3da1c3aa3b38af2dee2422153c99711be99df11072a4c5192b9c7e94e812279d6e1c0c21ed272026c3a0cf211e97a79c2025f6a64fad62ab571f379d0499c5a31128d4aea437a833b9a86d2424175212899d911a7b99fb9a411839922d10f2a1d324c01d27149423129d94169a915b959a2795ae679c3aa7dc9de01bdf941c8a299c28aa8a38412ba62424179a8e0e99bf93009248197f97751250931e0fe29e7d25f78c6ba1b91d9214c611e1897819d524d3ae232730a35a9d9297e80ef913c6a216a683384f2576249f1c09947b12fc98da00f193d610748f3e97f90e8198b3202c9e09822297e59b00204197288ccf9d56255e17721c7523f39b3c8e2d90b90b949bcd348031731cd49740116f103a15399943964a16fa99e99762100695b11fed9ba5913b9df89cf2218b969897549e2028df1c4a197b257c9ccd979a969316dba03a36ea2c921c749d7914e4821d1fde98ab96750e4f9c749370081096ed1c6d9cd214bfa0e293b320f6890101d79a5127ec9d7b98502665982c9a4996bc0b29a043373c27c6182da15b1481091594048bde0fa294721300959c0a31944f1d009c1c1c2f1b8d9abf1b2795458ef49b082379a64ea5b720aa9ab3140b0aa91cf2a60c35fd335ea59f1b679584126d9b66143890199455944395f40cc39a0022bca2b118cc98949cfe1f51942211a9a2c52899a416a2bc240a9cd1927e8f351983a6ed355d31d2a2fc95e2928b1494956e94fb99b0909d9cdb94440b7a9c882360a1e194b39e969a6d22bd90ff8a31a2422bb2a1399a2627b5991c9c1f98bc9872a46036e32d389cde9e8702388c9711ca9ae917b19c3a1a6098471033124f186d00071e6b215e9ff01d1298b49a4b8ad71b36a9fca85721959f7e1a2a167a1e61a96735a634f2a837215c9ce4920218e19d441df99f0c1de799681229193019d299971b1a2211a1691fd298569e4b9a752392a909a9c324ffa0ef1cf31c971d46aa1b36eb33f8a8e121b19f8318bd9d711093146a97d092d2941c0dcd9df32233a47396039ba29c0a2059924e1369a41b2b85a5baa385252a9c93958c140195fca72c362d3101a445971a95f38c6513919cbc15ab9c271827979e110b13341b3013f321ec2360a0b31feb97959c1a18159c2eabf6aa81214da02319fa10f52145abce350435deaa71230d9c99970a1dc0a05c1eec9f191d6a9afa14d11c909af31c231ecc2429a38120a499bda0181e368166ab06abf625baa2d21c3b1dcd1ffaab5936713499aa0624769e1098a51ada9d651eea9e481c069b2314591ac9145d9eb90ad620a9a0861f11954a9dca9fe427dfa9f4a8c2257ea05618dd1d2f19faaa6c364533c2a80a21f29dd50ea691c6983c99169c5716a4979513b2907a1c9616e1244b24119e121ef49690996919a09e5cacfdabd521ba9d4115f299fa2476ac22361535ccabda239e9a0d985e1d14a1fd1d17a03e1da89a43164a1d6e9f47226b20f72499a23420869a7aa1f82352a454ac05ab4625dca1a71c901c6721c1acf6362034d0a95f22fd9c409c352042a1cf1f75a0671e1d9cea146820aba0731dbc1df421afa00c1d41910aa1bb18f9213cac68a981254c9f1c17b91d8b21ccac0d374233c1a80420d89c9190e30c7b9cd99c979ce21842994d16ae0f6a201198e227d524b5a1b220c299559d6a09299ff9acbeac6e2679a1f1189f9cd02738ad7d36073572ac4b24019c9496dc1b07a0b01a5a9f611f4d9c0c19d91e2ca2e124e8217e22aca1511c819beda2d825eda757ac09ab2d274e9fa01d431dbb2474ad98371b33b4a82c18b99d109bf31ec9a0731e949ee01cb0992e134f204ea2b322a91ea01f249df115af8a0ea185201f9abbac0ea86a2235984b14e61a8d24d3adbd371c321ea5418eb598740b83861e9c01a060970d166a992517858f051f8f1846288c24b5a1fb20529a019d971d10a463ad80ac062651a1af159f9f2328abaded36b23416acab23c693ab934b1b1ea1918cbb9bfe1aaa9a2718c81c15a17e263f240f2247a02c1e079913a33e2844abaeac82a91124ed9c5b1517192b24bfad2638ca3168a5ba140596de995d1e9ba0121d3d9d181b44986313271f9ea29324891e941d1d99f4106c8e9ba10425a8a686ace3a58a1e8f8d63133b1c5723d9ad2638e430a09fa299239833192b97139cce9fac1001146598ce15ae98631acb2184263723eda0ff1fb999019e162463a8fdac04ab2424a69f0a144d9e592668ad60370434f3a915219811031a2998ef9fb1938a947d1544988b163798229a9d2731227c1f559c6d1c17984ca1e42839ad49ace9a6331d60973705d816ec2048ad69386230699fd80f88890791ce19139fa61a9b9a8118a0989716a51838a00625531ec71905950116b69582a0d62650aacfab6fa4d91bd78d7014a01c791f4aad5b38782f62176d9a5798571bb19d770e7aa43316838ec99bdd13fb9c871715230228682634a24223d39a2e964e24cfa52eae1fabe520f9a0f60e34a43028c1aea4370134f4a97b256d12cb1cf79c3a9e849c0f824d164298c3151b9d8884f126d223011f1b9d5c1c9c9825a03828f9ac07ac31a69a1dfd9428920d9a42220aad7f381b2f478d7995121a2b14df92d49a6b137a9534150997ba15349ad013c9224d1c5314fc9347170496aa9aed256dac30a87fa1191967921d120118f60acbaa8038d92b291f3f98cb9177128098408c4a907811118e4297f60efc98b320d59dba0bae97f39bf81f3e978100319e5525a49b741c6f23e59b448f0794df813a17cd348131721c01970f1170100d95a99787966d14d097889663103515b91f569e9516749d739cef21e5974199e89b1f28d6a0911c7825ee9cfd9930968d91ee1c3936eb2c4c193c9d3f16fb078f97c40a0097e214849aa2843e07581e771e929b340d46a141989d20d191ca984b9d7f272da0e51850262493769c2197e4143c9e443739277298c6a0b71080093194458e0b0a6795b31427959b0a15944f1df49ba91c9f1baa9abf1b0095048b009c0823f2a65ea5b7208d9a7213de0f1c1c79a60c35fd334ea52f1ba2948412c39a22117e8fe192d2925194f40c6d9b0022a9a23519fc950a9cfe1f43956614bca2c52883a6d2a2bc24949c56943890b21899a4ed355d3117a2cc981994fc14af9c86883798fa04229ca390200b9696c9234fa29198ed9ea3996a22c894299482a14c2b7ea4219c2327829aa59c0a9aa894cba16236e12d119abd9e5090388c3412b49a2a165c9c7e1a1298471097114f184a8a7a1e3721959ff01d6098ca9a6d00d71b61a9f2a857215e9f3a1ae917071e36a96735a634fca86b21b19ce4922919569ef31cb19fef1cd2986812021830194b9a971de121ffa0691fe799e19dd299752346aaf8a8c32411a10c1d441d971b92a91b36eb3309a91a22f99f9218d99d85137f1410959a955492160dca9dfd226ca4e7945497289c0920ca94a91036a41d2bffa700a484259f9ce09286145a9688a52c362c31b7a30a9b6097f38c0c13959cfa100d9c2319eb979e116513341b1a18f52171234da0b31f2797919c3013159c45abdeaa812160a02718bc15f3212eabce350435f6aaec23ab9c9997d11cbda03b1d769ed21ca499fa140a1d909a181ecd1f0624baa281206a9ac0a0f31c3681faab99aaf62529a3191d5c1e231e66ab5936713406abcc24ec9f0d98541a489ddb1df09d53180d952014a01ad714cd9f321909217ea0851f049bd89d609ee427faaac2a8c225a8a0461c641ef40ae0a96c364533f4a8d520e89ed40eb2909099f2999e9a4115f4969513a6917a1c6919fa24da23ba9d121ea497c6989616a09e76acccabd521119e57163c99e1245cac22361535fdab4b24169c0d984a1d7aa1901cfd9ca71c869a43165e1d6e9ff82367215f22dca13420a89a14a1472252a4c1acd0a9462599a23e1dfd1d6b2054acf636203405abf72417a0409c672009a1b61dd69c1b174191e9143420aaa0b8188c2103204b9f0b1d1d9c41a1711df921ccacc1a88025afa0651ecc1fbe1d3cac0d37413367a9f32173a09190ae0f559d9f9c019cf118c2994d16e30c6a206a09d0274b2479a1b22042997b9c1198299f38ad72ac6e26b5a1e218d99ce227f9ac7d360735beacd524979c9496d91eeda2431db99da01d819b0c19dc1b2ca2d825bb242c184e9f511c4d9c07a0e124eda774adb4a82d27aca1611fb01ae82157ac98371b3309ab7e225a9f0b9b4d200ca1e31ab5984c14b68a2e13ee1e4ba283208d24538e3598f115af99c7a0b122169ad3ad1da56922249de01c701ead1ebbacbd371c320ea89f1f929e740b858f019d9f9fc693af15529a25178386051f971d2328ab2351a1fb206a991e9c8f1810a4abad16ac0626b5a10d1601a0462863aded36b23480ac8c246097ab93c81c13a3171905965b15079927184b1b15a13e282b24ba14ed9c2c1eaa9a1ea17e2644abbfad68a5112447a0fe1a918c3f24aeac2638ca3182a90f22bb9bdd99261f9ba13a1c229863136c8e63135c1e9da204255723a2998e8df41044989aa09324a8a6d9ada09f8a1e1d99171b111d8a1e86ac2638e430e3a5941d3c9d3319ae98019e4d9e98110a14b999ce152b97631a162459261521a69fff1f6598139ccb2163a868adf3a92424eda00114ce9f8426fdac6037043404ab3723ac10031a37984ca1d8168889370517988b162998229ae428ec20d80f60976d1c4498ef9f9d2739ad48ad699f331d559c7d15b193312249ac69386230e9a67c1f8a940691a41882a0a01c57987014b6959616ce1938a0d6267a1f6d9ad68d0116a098129f062550aa4aad6317d91b05958118a61a541ecfab5b38782f6fa4c7199a9a571bfb9c2e9634a46d12f60ed39add13b19d87174e2430287b25f9a04223c99b770e1523cfa5c1aef4a9e52034a2838e7aa402282eaea43701341fab68263316cb1c1b9d25a00d9a121a28929c98c315f79c8884382842227995fd945c1c42983a9ef126f9ac0aad478d9a1d1b9d4d16849cd22307ac7f381b2f31a6011f0f822c14349aa99a0118ca911c120396b915e092d113ed25f80a3f98679247170897d49ac9226daccbaa291f1919fc9334156b134d1c30a88038d92b7fa152147a95d6110498b28e4b8c2811cd8fb3964b0e1e995420d09c0a807c95939bd41f3d9764122a9ea024c39dbc1b7e232f9cf790689497004a21a834a4317d1cf59536108b0cbe88ea98aa904015b2998794d8100c00dd18129bfc131a9cda9cb222af999c16881d6323f7a2c81e0226499c149bb499149f4329f735952c0b1b7e9eb30cc8816b195f9865154f85129e1a0cff097022019ab69af49a5aa1a29de4254e9c219e27258f24e6a8d3173129e29bb2a00198a51c5f23cb36ce2a451a33a646158408ef933b88448da694411436941d091695a51c5a9bf81c7b1bfa99f11aa994f20b149b3322e9a667a586203a9a38112710ed1b82a5f6340a3425a5911a3b946c1000997a0d7b90e28f46944194930c2d9cc120a1a1c71542945f9b3e203f963e1790a1aa27d7a53aa34225ae9dd794ef9203161e1d8d3588314fa1949c47964f11f99cf8900496c588609cc1952610491c5820e6a1669cd89d7a9cce243a9a109bbd1f5129b6a4daa1a4299ea0079d35a0521c7a2187350c30629444a29798968bbe1162995012b69bcc19ce96380f860d711786901a1ff120be9e411d029883992981b7195fa9dfa8cc206d9eaf18e417ee1de4a85c35ad3401a91521339c8e909c18269d781b5f9e341c4797a410dc89fa18e29acd1eb220be9fab1daa98e3991499b620fea9faa8d724c5a0311c921a731944a7ea35033436a91c218d9eb114ef9af50d48181797d995ed91570d6f9d59204ca4529989903e9c6a20e495d4156ea10b2a73a78ea47226dc9ef788c2924a9cb7219535bd319aa4579e5499ca8d98142b9c9f8c949aaf185f97eb10911187197a1a0322ed224e9f8e1e0b968f9b5710fa9d44abc3aab9201e9f001734145e22e2aac7350a3522abe623f79c12956a1cc59f7619a69c3d1bb89677122d18039c3c204c200b2362a11e1e4a997a9baf1bfb9fc5ab87aa10262da2251da117fd1e95a940367634afab6e24019f5998611e2c9d111bc89b3010cb05070fdb07729f4f947a18dd21b3a0ab1da0995118fb9133240bab1ea93f2779a1a01d600c8295fba54536723311aaaa20c99e370e15922999209be9996815db95cf1132913a1ca71cbd2495239b9c871c0c952b97fa139aa06eac8bab91208e9b2914189ae92411ac113621351fac3e24339c56872d16a79f6e143a982018c1954813b5142b9c2925f920b621e3a0131e24995e978c1e16a7b0acaca919263da2881c5095bb20bca9cc363d3489ac9525c69d2a990d210da2091b4f94618cad0fe10ce61737a45224791f642076a0511cfd98a810222377a2a8acb9a8c12703a3071e2e980393b3a8f836403391ab9724eb9da4817191df9d079b969cbd18949827144f0b0e20ae1e8026d923b29d4f1d2094d19c31136ba4f5ac00aceb23489e1e16b59be42666ac7036fe34b8ac13259b9d17165d9129a2591e389dab1a42983315cf9bb71cf726c822f5920697d618fd9755139a2034ab19ad14a69a2520a2251d9f9ab91e55a76b372533f5ac5d26d29d91890f1daba2b71ecd970101370ebb0a6b917ca2f227311ce2124c9a0f18e4963e9af72698aadcaca1a29124f8a07f1cae1828a285a5a937b631acaac2249d9dee110298ff9d6e9d269754156a980412470ad21e0d22d226ad22d69e661e2f90b89cf71b66a676ad33ab8b24c09fc60a859e7227a3acd736b334c7ac2225f899c7186f9e159f751b5798ae10da90ea0f569b1a215b285b1b75917503621871949d9254226aadbdac12942d2063a0111b989cbc1f53a617384a3144ace826e29dfe15009ab59e891d4798b908e80e6e07569709978228229e90174897d5145295759e952758ad1fac2a1e401d889c441aae1e2aa5c61513380630fda8cf23cd9dfd164e9af69e4a9cae0f6215bb99d5125b90531dc324712507208c9e061fda90c19a2e1e85a874ad22a923243da1c48520a0552643ac403714341fac97247a106f18d6a03e9b8819dd980f843b94e012b29d36246728979a9218cd132b1adc94441a272055ae2aac89216894fd9e0f19c09d191ccca35338802f35aaac25099b7216f59f7287151b3c994f14e38cf60df19ad52181273da12215c688660ade92549c0b2555aec3aaee24a19b59890b17781e0fa5a0243b38af2d78a819233e9d711b279da79cc5a3241704991e97e812e99d6e1c202511286d24379dcf217e94f1100c21f6a6d4aeb9a8571fc3a02b9c72a4ed274fada437a83362ab2026c5195212f2a15b951c8a9a8edf949a912d10899dd3249a27299c2417e01b94163992911ac01d95ae28aaa624dc9d129d41187b992714679c8a38412b3aa79423fb9a0e99e29e7819f9130994e80ee1891e0fbf937d25d524c6a29f1c9297c61150930092f78cd3ae16a676245a9d9214751248196ba1232783384f2530a3b91d7f97a110e7961d911a07c61001912096ce0d5c99e01f159ca80ddd92499bb61f1697d0158c9e4923159dcb1b6d232d9c24939593b512ea246c34d231db1d53934601f21027968998e3116115ee981c94601024a0571df5930e98968a029e1223c39a772473a0dc14069e22208625b09b5e9a079d2ba0f12e22354b2ceb1a4f9dd7992f08f59e501e9c9d0f1b0ca0c2184407b1a36227669c579f881df4a4ce274fa0522a11a9c82968aa8fa52c2a61a2c0970aa2f9a2f1319a34282c91a35ea6a11f3107b6922a8b6c8d6194d9131d94b4089295f21b0c9aae1c791bae99b21ac0948c0c549a232190a66ca56c20059a2c0fd711291b61a4d5341a34e9a4b81a8c93c50ea697e488368c99057d947a933b0c739d47200da1b9085e8d4e9b64205597a31a71a14b252ba448a20425d69e54962a94c2182d280735a731ab9d019e8898d910289c9390498b21140b9c8391020f53a18020c9a26a97ac83019f9524659c3023b91b7f2786a151a2fa28e3a0d29ae19f3d21422d3e347a30669670a4fa9a8386320b1d98b809029a9a18ac95330eea825218d8939b1f6020169ea71c04976f98aa905b184fa9cea855208b9dd4164217281e89a84935b834fca8bc20389bab8e8118839c8d1a7a9d041c9b97980f3b998a1ca99c4d20591d509c161a6c94c49550999f1863a9d0a8b72470a08a1abe16bd1c31a3aa350c34dca8fd1d059d00101e903d930d198b9899890e969c0c0aa153200da46017f69a3a0e6a1cbb10ea1d1c9d9725a4a5f5a47d2688a07011db9d3a1c70292235e73103a4bba00f9cd78b6a113a9a64942a998415fd94ed0f8c112c19b0191822bf22cd9d771dcb95769acd8a849e28abc7aabb1f839dbd16db0fe82291aab53516351cab5123ee9c6d917419009e6717fb9a171a7e9565101e0a2194422095207b2141a00d1c0897b795dc85e4a323ab61aa212692a1601d5890a122d5a713367a34afabc621509e7a15b290e917089dbe14f608a58eb2065199519f011d23206a19308fbc98570d141bdc1eaaa46ba8ddaa692907a51f214ba1a42447a1373632331aaadd1cce9ea60c95923a998e9aaa9a93149b931d0fc18dd41c671cbc248423359b491b4e935b986e89c5a068ac7aab8d1f5a989c10be991a25b3abfa35323541ac3724759c4b0c0098e09c10804c9147156f949f10a611651cc324882050207ca0e41c0d962307859f3ea856ac64a9bd26faa00b1a3e9bbc24eca57a3665342fad6623a89a68153f990697c39ba41c3397ea10a084b595369fac26061b7a1b1c9ff1164292ca1ff3137ca9ceaa4da974297ca4751e5da37b254ea0c036323389aca020de94148e3195c49cfe9bf79b42170096080f35154e20521e35268623699ca61b58015d9dfa8f75a4e2acd3abf922609c66103f9be52619ac50361735ebac1b259d9dea8eec9b1ca06a1dc09ba5187c984b146a90d624dc24e5211199fb950f1ae78d3411bca2daab5bacaca5a6267aa202170ba0ac25e096ff36ac3364aecf25bf942310359d9499251aac0e17966612ee85269b2121a62790a014196a9c841a69942322eca1b2ac5baa5ba1042795a3351b18a3ae1dc1281e37d0311bad56248a15f68831996c9dff9cf39541140997a70c5a180720d52170266622589e7a1d720fb79d3b0e50a65bad12ab6224fa9d5193039ec12735acac36d7342ead3425489a8898709e0f9ad91b6199190f3393f811ae181c262e251117f79b19172619a7905b104ea472ad4cabc81b0a2488a3bb195ca16f251e24a737b9318fae6528419a7d963a9f761c109034105097be15698d4103d225c424fda3401d9195ed161b93d720aea513ae57a7c721672033a1231a279f76a4e62d5437cd2f94acff253b951110389c1a9e139bed05d7163099730ca517fc1e982419254a1f139ebd1d7f12219bd30e40a865ad0ea95f24a3a00d9750a0ba2654ab05374734baace5241715639dc69d108fe5186399f78d7e8ff712901c43269a25259e6489d4189d1ad3956d1b49a6dead8eaa76250c1c7da3761b71a1e323ce271238d22f88ad9528ca9ab29d859a141c93144a9991103705f20a091cd227001cb5a125192612e6137a924b1cfaa72eae75a55527189f52993816ec1705a80d305c37df2db7ac4327e49c06178e9c669c10a4ab8a4c96e5987014a79b661db62527285924549b1b22328cf010dc1cd2a6e8aedea86c1f4aa1f29c18a4b62794ac64370b344aac4b278613329fc29e39961c120a9848984e814912191d2d2613267a9fe216041e431bd38ebf1c34a7f7adcca8212702a06aa18816329d9a1bbc295f387e29caaa0328649ea9a0851016199f903d91078f6a0fef0d16214f27209c9d9f131ed5960a13b994bc1640aa8cad680f27250fa237188d179a1f11a9cf30de37d11f60a83d25c39e710f1f96508f0f0b18111a919995c50d9d999d1f499bcc0e8d8dac9aa01f2097b1154b9faa21e198811c1b231f9d9792808eb1184d2625341332e51fa50b78890810ea96ed974f1517169b9734927a0ef59f8d21449ef994d418709cb2213399dc21a4a53697a51fc422a023899d9498a29a35218e303934b72cf2121316999c0502469897140d93b714b097b90c3403799f7a249d9f200fd51a55a06522c499b616d9a7ce28d7a29b99222697a2b11ac4221424ab342f32f1241ca889a0cd9cd004a6922c89b18fbf938d11589343087895301b7399731c9f1bbc98f619a794f90a169a502020a65da54420e3993308ac12511b37a3b1342a346fa4611ae4906e0c7a95ef913608b7092694f0926f0be89c082099a0e90aef084f9b0a20bc966d18f2a203230ba0899fbd23b89f6d98c88c5a1f2d2a7b34d9313b194f9c8399650a62987399bf13740e30960195b00ed0a00b20cda1f396231d559f2e22d499102136a436239e1d691641260ca10e95d21bc025ca303c323d30cc1ca0a201a1eb82718521956b8d3699911733947d0ce98dfc18ec94881f0320099d2f1c0b9630989896861725a9bba8341fea9c07117e160a1f46a82f35c434c8a83a20f898f08cfc16af9b031ab29c7b1bb897bb0ebb9b921f6d9e3021ce151f91f4110e859799559b669aaaa889a8fd2368a07c18d4180820319d5f351934c2a71a18b59b25906918299c8c1d539dc01ad7990a1083a10c23c8a4b920b1a0071fa698f5193e84049e00979fa024a5eb25c8a25d1800995124112ca7341832e49e86a2c39df8865804239841967d98d2126993040e0e0ed41ac218f6217a22c49c0a1d6795fe997196d99efdaaaeaac41d449c26155905b82343aa9c35233506abb022ac9c648ca513589cc215aa99261abf95660f0612c21c6f1c6c21291e189db7162494d29e349de6a448aafba95b2556a0b41d6e1c4325cda5d1358834f3aaca1904a07c18b79b0310298ea699cd1bdf98390ee49dc42241a1012676a2cf2102a1961a0ba1f6205ba995a464ab7b29a5a5af215b9c3428031eda355133ffa8c89f0f9f82016392f1979f9b91991210748fec0cf288c21d2d1aad2467233d9ae61a7693ff98ce9645a048ac82abbe1d8492130fa798582576abda354a3546ac2924509df887c49aec9884929d82c91446946c0f341cda20d2223420ef1e41a0051c60932ca087a4c9a7d6ab08a9e025669b43183f1db827bca3213693342eadbe1abb9e9f108c9e9013098dd217b600b8905e099a1c83219521441f7e9c479c80056f0ed2a173a40eaa34a953a8172926a0141c001995294f242f369833e1acd8a1d49d568ff4969e9a8d9c679b081570947e0b99165a207f1c04269623d89a991a1f0bbd9d519803a3c8acedabdd210099d00b1099122709ac26363d35f8acfb24999e8a98079c4f9a03185795e514c4975812551fcd24572236200093719ca41bd01021a1b7a68daa89ab40a6a027bb9f7c97049770293a1c89362f340eaf51201908f29b14988b1741187f944f8ffc8e180d22239123032054a09b86ab9ce81cd28c24a2d8a91cab12a82d162e27889e7399229d882a862c3f367832bfae38a1ad1e5e930499989cc09c8498b2148596240d2d1bfb1ff7203126ea22789d8a1c52138f9ea69917a53fad4eabb523e09bad96519c05280eac72360e355dad1425ff9be49d0d989798db1a82972183f995ca13ed21792571211b1c6f9e540b6b1ce10fdfa102a862ac81aa7191e22611a3bf992f9fc92902270837d43225b014263219159f2019d21a039176966e91c508590bbd254b22d69cefa014183113231a278a21a31aac66ab3f9fcc25fd2060a0fd9852a2ff2953302a36a53073af391ed02007914e9b439d119be690231867998b0ff619341fec23e3242520429d151dd0130b9b5a9b2ba730ad89a926246d9fe6984f9f1227c0aab53695341bade924310b3da03b938f92f91877950595f8936d133d23ff243323b49a079d4e15c41db28485a1c3a896ac99aa6f25ca248ea43199d49c67284c2a79372d3116b03f28bb18d9a03c1ee41996970598f294621403067726ac210fa23e9eeb11621dec16318e88a554ab28acf51cf527ec18fda1da9413a062284a313836732f2ab01426cc1e1913f09c029ad8a3e5995d95359587906e99341f582523281525119aae21bd12650bcf95fca4ddaeaaa90b1f72a19e9cbba2ae271eacf9367634c2acfa27779789a0419c9e99349882154998ca983d14d621ff25c425a99b389b991c4a20011876a0cca8c9ac31aa2528031a06a57a9c1413731fe82c0c38302d5dae51293a92b2a1421fa612b496b0948696cf11b910a427411c75a27a99ed1c641a3117c29401a815abdfaa4024de267aa189a07f1978192a9ebc332436c7282bafa82acf9ef90d33953f90230d4d101192f894290ded98551fb59ab7119505589a561fde96130fce9f3f21140ce11c4f22d19d7792eb10b11b6c26bd336232e721d216da8b740cc593ba936a1224179596d48ef50c049a21204ca01a12751c55989720c9988c9e7ca60d18f62405254b211ca1b39b9b21f72ae62f9e32f42d220f0119bf993380b59117989893071cbf930c049c00fe9c459d8ba47225b02100a24920c99594a20ca58c2553261a20381d90967894372a68323630952db02beba770a0e4a1c8042f9299821e905892da10a1924e07ea95071be9981c1c321b8b980e1a7e9506847f9ae21fb9a53ea51a20099aae011414661b5da28d343b34cfa3881a6689eb0a1b942a925109c504ec92dc912c0a309b981e079f05113812ad9a711e0d970798f1a2bd20cf9617971e2189a07c9a7519a5229229fe333d3295227308e6941f0af694cd9a3d131e194d99f293870d1f9e7a1caea1fc1dd11e479fda1f99990ca2c9a50c205a256724fb2389a09b9d0a28142d032e1b314c30ff22899fcea17202338b7491e7919c97a3144d93bf0b379069198996491fb11f089c2a1baa941698ff987017fba8b6a8fd1d1a9c0b908d15941f17a81435d23482a8811f2495ca8517114897b4140b99d917d994c10c3d99071fbd9c3620941512893d155b80fa9cc39e779a29a8f7a7e420f39ff790ea1ca62002960235383407a57d121398408cbf1434981719c3973b153c953a0d259e1b2121a28a1e6b9c8c18290f2914b6a0eda2139f179dc5a04621fca18a97bb21fb255f2b2f348c32642053a1e29e7183808cea954f96db97710e1391280c110e3f1ca614c7210922219bb01c8a94a39a87986c9dd4aa82aa96197c99aa0b600c9d2315aa7d353335b2aa1f22129c4600ac8032987609c79657175c93d70c58188e1eb516be20e61ccc9a0d17159316a233a110a3c0a92da9e521309dbf1b17228f2514a57835a53496a93193f7a0a40a6b0c86991e16be98fc187095320d4f975c2318a01724019e1d1d899c6915bea456a062a6cfa6b5a8fe24f4a0fa1c5b24f426f8242f35e73370a661a2cba17d0190927294a29b1e9aa10d9a8da309ba8ed51d8e1752245c2321981c1be393a4995295cf9d29ac7eabc41a370e72092b98592576abbb355d3531ac4124319ecd05ea983f94969671886414a191dd0acf1dd220b81eb220121e439e2e1891905ba403a516a50babfda864232f18b0199f245d2876a5c335cb3476acad9be8a2a990aa9451956514480d5e121191e9088a228822f7947d1e689d129bb09401107aa9f4a642a681a84ca52226d11d021bb829a22a11228d351234e7abb3a644a64d8f7d966295049d239cc114eb9072817912d11e77195825eb235099e9199791e89ae3984c9ea0ac05acf220f2940417409ac12622acf4355d35cbac09254ca0189705992798b48c6e93f01778968e0dd1206e228420d420a619a29e4117f3122ea55ea6c0a79aab43a85a2694191394a123e62975a21a369f3421aeb39d40a0769c30185d17bb106d9050892991350c4227a01cdf9f759b979cd6985f17bc1434ac7fa80ca6e4a4fe119c270320d49d8f2a3e2d3f28a835423325aec4a9dca13992a998c799b69c7e9afa12ac955d054d1be71e861ecf259f230a9aa81bcd14829e7f9bada2f3acddab852196990a97f7988b2720ac2a3650353bad37252a9d7e9c8198df982b15e684b0117e94738607234124941f2521fb9c289ccf17f718a5a68da600aa30ab90a4db27070c489ec021e82acc1d70363d3401b038187c987b9ea41c0719a588db97a78fdd91be10c5287b9c35a4819cbc9b371b68193c1537ad3da85da67e197e24b326ff195aa25229a72e102d87350c322bb077aa6721dc9606982c9c419aa0962e159f961408971bd41da621b024c1200e99ce1b93120d9c1b9de7a4d5ac42aa41218c9cc0983a9d0d270aab4f36fa340faded24fb95559f9496b89a9a16141107104995fe8c542469238622a51ebf9db09c081b901bbda64fa6d1aa10acf51083272e9a41a1e120ad29cb26c53676335bb03121681bcfa00a20fe14391011997b979d05c6119c2987a2c1a38d9cf099d71b3c1dfb0e7bad39a5cda8ba1dbd269326150d18a41827162f6d2ebf356f3141b135a92226f48f4d98469e3ba2309da0996c94a38c130a31204d233628762655941a21a714c49a3099b9a267ae99ab881ff8a0cf9929a08a2727ac77360535faac3b28bc9e4ba0f39db49e439b560c74092194c2954924ab24cc26811e2a162d993d1f321e62a6a7a332ac79ac05211b2487a28ea12321ce1e442c4a371531f6ae0627021a16a2a11e3e180512c7992996858e6411ed2aa8a5f9a09d9de48a141c1f1ed31596add5a1e6a82b1c9e28a7242aa327a23720832d3e32c735cb2dfcb12e18fb26790dfe941691b00d170f9f90f694b00c4a984d1f899a43149810919a3b1f4397f290b99f8021c119c81ccc21cd9ebc921414611c7e253a33bb321b24251b9c0ea20b058a9a943c1587177796e08ecb0bdb97e61d149fe218d91b689b841fa398dea05fa49220ae25d4256d2265a12d9d17243329522cbe316030db24c91f1a1ccd01ab92b79301153819c68f19106b07d79f5b9fd5a25322642371817a210098cc9d3fa4a99a1c2b7a2a941e6ca6aba1cb2d7230a52ec12c0529f511c095b69e1606b092d10c4792a790580ba392ab06a9956e1abb980d1c3c1b26982e1a39958485559aae1f6ca535a5ad1f6e9af48aad11691b65a26d345034bea2cd1a2b103009d190d6925d026b011d928890e0086c99991de59ce115da15859b9f1d76984a9c15a2c91d65170a18641e49a13b9c581c122249283f33b332f825501e611712072892fd966311e9143c95c48da2086f9e61188d9f13216e20629f081cc49ccba2d5a33d1d90275527991d1ea222a10a29b729432a2731cd30fe25db1ff0201a07a58f0103ce949b95551011910b091191301a3698161f081f8699641aee92d9987f9a4519cda8b3a80e1cad9b33956715ba1f14a8f934e23431a87f1f4d8da303f586618eaa8c0993580f7f8f8f086b93ab1c0498751dea1a9093071a478e6e9e35a063945da714a7ca19dd9fa49cae1d01209a99a33461349ea0ea1bff171003d1065c8d300f8c0864892484be0572987b1c1c9c151a3f160f98f71a129584a2e2a3b49fae98f396cb99fda17ca0ad23b924de296c33df322e27211c3e17bd01f28bc3939895da975289588ec209e28d941cf68d8721a0213398cf1cfd93c1982c98ad9a8eaa70aa6b8b6898da93e0933e2328aa5f3544355caa77229899290ada8f2c8d48926692590f9390260a5217d21cdb0cbd1e351d4795f81927080da1eca0e19d0ea9ada8cc14d09d3498a920562383a51135ce3490a7051cef9a4f09ad83558dd38f078fa50297880006b118511dbd848e1de11aaf817d170a86d7a4b3a38da11aa679a56b9a169f889e4b255f243324793425342191a6051899588b4a8aca8dac9bdb9a9b09be8862002e94991c7510cb2333231792921b2596b2947f0cae96f0ab98ab89170d142c0e039cf52495ab94357135fcab7d24859e8e0e7e95b5896096259432114092310d5e19fd1d94194d20f31ea6940e18198d7ca10ba2a7a036aa65a9be163b964810c621752540a860350e354baa451b7f9f180cb68cbb90a3921b895e016c83e10291202e20ee84dc1da90b6c959d979a89e0a895a5b3a209a710a5a019e41a621b4c2a3428a616d4345c3487a620a3a5a6fc8ff496001a1d9e839e8e1bd2935691139cc512531a952225226516ec93f49bd61f8283ec2148ac11ac3d245d8d4221a9a08224eaab9c35683532ac4824dfa24c0cee98f811ba9879982319d1960d0f281ba01a2c202920fd1c27152f958e85b8a00da35d9f56ab11aabc22c4948118ba20742645a897350c35c8abc40d05a06695de0d788f7c907906cb0675069f89da24df206196951c799a4c9be39c0312cfab2ca70ea5d9a6faa26b224024f91fc82c4f2be71727355234edaa9da86ca9dc8125990f0ce29c899c34167a98080efe10c31a781c9b24d4233c1443189f8c3990969b529197ac32ac1420269b1518849c3a2653acd8358a35cbac7e254e9f40963f985593889604950915bf93d285771e1b1fc11f87210b1b1893410a4c1678a221a37da484ab52a91b239e0de798921e6c2851a8d13505354eadae1f7c9d829dab1554129a0c0411450ac20fa991c1271220369c051c24a04d9da49ee21828addca710a74fa7b013212632281889a42d032dd2274d3531347fae5eab09a9dd939f95fa98e99880993f8cd294dd8e5418981c931eeb2317226c17181bce14ca9a499c78a049ac55ab2517a79b2b97f1992e2601acdd356c35a5ac65251a9b069ca496b89bda8f698b2e0e6a8ee791ae20b620e820b52135196b9a5c19a619eca291a3bea6b4abcfa78521580ecb9e411c9d2837a7ff35dc3405ae0622ac909fa1a91946088b157513b2141015248e042941187419f21ae29e9ca2f69cc81434ad3ea647aa60a86c1f90281c29b19e652c582e482ab5350034a2b00bace2a5c995ce92e99b5da1f19e009ea315829931115a20271d4b28f0279e195f1d1218a494b5a03f19d7ad23ad7321b39f2d9c759d5e27c7ac0f36aa3561ad1528689f609c329ac99ff79fac9a5398119baa997f22a3200925ba257d218f1c811e7d20cea166a401a881ac62a8d3087da070a125171325f698e535a634c3ac0324cc1ce3a35c998599890cd61bc816031806144829f018e4234a1b43a1529f0a105a9f4aa959a936aeb4a7a328282a371ef71cdc20a02e6a3108365a3122b22caae717