275 lines
236 KiB
Plaintext
275 lines
236 KiB
Plaintext
|
// Revised 02/02/2024
|
||
|
// https://github.com/bjin/mpv-prescalers/blob/master/ravu-lite-ar-r4.hook
|
||
|
//
|
||
|
//
|
||
|
// 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/>.
|
||
|
|
||
|
//!PARAM ravu_antiring
|
||
|
//!DESC RAVU Antiring Parameter
|
||
|
//!TYPE float
|
||
|
//!MINIMUM 0.0
|
||
|
//!MAXIMUM 1.0
|
||
|
0.8
|
||
|
|
||
|
//!DESC RAVU-Lite AR 1
|
||
|
//!HOOK LUMA
|
||
|
//!BIND HOOKED
|
||
|
//!BIND ravu_lite_lut4
|
||
|
//!SAVE ravu_lite_int
|
||
|
//!WHEN OUTPUT.w HOOKED.w / 1.41421356 > OUTPUT.h HOOKED.h / 1.41421356 > *
|
||
|
//!COMPONENTS 4
|
||
|
vec4 hook() {
|
||
|
vec4 gather0 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, -3), 0);
|
||
|
vec4 gather2 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, -1), 0);
|
||
|
vec4 gather4 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, 1), 0);
|
||
|
vec2 gather6 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-3, 3), 0).wz;
|
||
|
vec4 gather14 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, -3), 0);
|
||
|
vec4 gather16 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, -1), 0);
|
||
|
vec4 gather18 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 1), 0);
|
||
|
vec2 gather20 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(-1, 3), 0).wz;
|
||
|
vec4 gather28 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, -3), 0);
|
||
|
vec4 gather30 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, -1), 0);
|
||
|
vec4 gather32 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, 1), 0);
|
||
|
vec2 gather34 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(1, 3), 0).wz;
|
||
|
vec2 gather42 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, -3), 0).wx;
|
||
|
vec2 gather44 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, -1), 0).wx;
|
||
|
vec2 gather46 = HOOKED_mul * textureGatherOffset(HOOKED_raw, HOOKED_pos, ivec2(3, 1), 0).wx;
|
||
|
float luma48 = HOOKED_texOff(vec2(3.0, 3.0)).x;
|
||
|
vec3 abd = vec3(0.0);
|
||
|
float gx, gy;
|
||
|
gx = (gather14.x-gather0.x)/2.0;
|
||
|
gy = (gather2.z-gather0.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
gx = (gather16.w-gather2.w)/2.0;
|
||
|
gy = (gather2.y-gather0.y)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather16.x-gather2.x)/2.0;
|
||
|
gy = (gather4.z-gather2.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (gather18.w-gather4.w)/2.0;
|
||
|
gy = (gather4.y-gather2.y)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather18.x-gather4.x)/2.0;
|
||
|
gy = (gather6.y-gather4.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
gx = (gather14.y-gather0.y)/2.0;
|
||
|
gy = (gather16.w-gather14.w)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather16.z-gather2.z)/2.0;
|
||
|
gy = (gather16.x-gather14.x)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (gather16.y-gather2.y)/2.0;
|
||
|
gy = (gather18.w-gather16.w)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (gather18.z-gather4.z)/2.0;
|
||
|
gy = (gather18.x-gather16.x)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (gather18.y-gather4.y)/2.0;
|
||
|
gy = (gather20.x-gather18.w)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather28.x-gather14.x)/2.0;
|
||
|
gy = (gather16.z-gather14.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (gather30.w-gather16.w)/2.0;
|
||
|
gy = (gather16.y-gather14.y)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (gather30.x-gather16.x)/2.0;
|
||
|
gy = (gather18.z-gather16.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06319146241026467;
|
||
|
gx = (gather32.w-gather18.w)/2.0;
|
||
|
gy = (gather18.y-gather16.y)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (gather32.x-gather18.x)/2.0;
|
||
|
gy = (gather20.y-gather18.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (gather28.y-gather14.y)/2.0;
|
||
|
gy = (gather30.w-gather28.w)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather30.z-gather16.z)/2.0;
|
||
|
gy = (gather30.x-gather28.x)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (gather30.y-gather16.y)/2.0;
|
||
|
gy = (gather32.w-gather30.w)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (gather32.z-gather18.z)/2.0;
|
||
|
gy = (gather32.x-gather30.x)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (gather32.y-gather18.y)/2.0;
|
||
|
gy = (gather34.x-gather32.w)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather42.y-gather28.x)/2.0;
|
||
|
gy = (gather30.z-gather28.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
gx = (gather44.x-gather30.w)/2.0;
|
||
|
gy = (gather30.y-gather28.y)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather44.y-gather30.x)/2.0;
|
||
|
gy = (gather32.z-gather30.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (gather46.x-gather32.w)/2.0;
|
||
|
gy = (gather32.y-gather30.y)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (gather46.y-gather32.x)/2.0;
|
||
|
gy = (gather34.y-gather32.z)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
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 = mix(mix(0.0, 1.0, lambda >= 0.004), mix(2.0, 3.0, lambda >= 0.05), lambda >= 0.016);
|
||
|
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
|
||
|
float coord_y = ((angle * 4.0 + strength) * 3.0 + coherence + 0.5) / 288.0;
|
||
|
vec4 res = vec4(0.0), w;
|
||
|
vec4 lo = vec4(0.0), hi = vec4(0.0), lo2 = vec4(0.0), hi2 = vec4(0.0), wg, cg4, cg4_1;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.02, coord_y));
|
||
|
res += gather0.w * w + luma48 * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.06, coord_y));
|
||
|
res += gather0.x * w + gather46.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.1, coord_y));
|
||
|
res += gather2.w * w + gather46.x * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.14, coord_y));
|
||
|
res += gather2.x * w + gather44.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.18, coord_y));
|
||
|
res += gather4.w * w + gather44.x * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.22, coord_y));
|
||
|
res += gather4.x * w + gather42.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.26, coord_y));
|
||
|
res += gather6.x * w + gather42.x * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.3, coord_y));
|
||
|
res += gather0.z * w + gather34.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.34, coord_y));
|
||
|
res += gather0.y * w + gather32.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.38, coord_y));
|
||
|
res += gather2.z * w + gather32.z * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.42, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather2.y * w + gather30.y * w.wzyx;
|
||
|
cg4 = vec4(0.1 + gather2.y, 1.1 - gather2.y, 0.1 + gather30.y, 1.1 - gather30.y);
|
||
|
cg4_1 = cg4;
|
||
|
cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;
|
||
|
hi += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
cg4 *= cg4_1;
|
||
|
hi2 += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo2 += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.46, coord_y));
|
||
|
res += gather4.z * w + gather30.z * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.5, coord_y));
|
||
|
res += gather4.y * w + gather28.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.54, coord_y));
|
||
|
res += gather6.y * w + gather28.z * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.58, coord_y));
|
||
|
res += gather14.w * w + gather34.x * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.62, coord_y));
|
||
|
res += gather14.x * w + gather32.x * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.66, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather16.w * w + gather32.w * w.wzyx;
|
||
|
cg4 = vec4(0.1 + gather16.w, 1.1 - gather16.w, 0.1 + gather32.w, 1.1 - gather32.w);
|
||
|
cg4_1 = cg4;
|
||
|
cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;
|
||
|
hi += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
cg4 *= cg4_1;
|
||
|
hi2 += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo2 += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.7, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather16.x * w + gather30.x * w.wzyx;
|
||
|
cg4 = vec4(0.1 + gather16.x, 1.1 - gather16.x, 0.1 + gather30.x, 1.1 - gather30.x);
|
||
|
cg4_1 = cg4;
|
||
|
cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;
|
||
|
hi += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
cg4 *= cg4_1;
|
||
|
hi2 += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo2 += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.74, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather18.w * w + gather30.w * w.wzyx;
|
||
|
cg4 = vec4(0.1 + gather18.w, 1.1 - gather18.w, 0.1 + gather30.w, 1.1 - gather30.w);
|
||
|
cg4_1 = cg4;
|
||
|
cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;
|
||
|
hi += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
cg4 *= cg4_1;
|
||
|
hi2 += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo2 += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.78, coord_y));
|
||
|
res += gather18.x * w + gather28.x * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.82, coord_y));
|
||
|
res += gather20.x * w + gather28.w * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.86, coord_y));
|
||
|
res += gather14.z * w + gather20.y * w.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.9, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather14.y * w + gather18.y * w.wzyx;
|
||
|
cg4 = vec4(0.1 + gather14.y, 1.1 - gather14.y, 0.1 + gather18.y, 1.1 - gather18.y);
|
||
|
cg4_1 = cg4;
|
||
|
cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;
|
||
|
hi += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
cg4 *= cg4_1;
|
||
|
hi2 += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo2 += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.94, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather16.z * w + gather18.z * w.wzyx;
|
||
|
cg4 = vec4(0.1 + gather16.z, 1.1 - gather16.z, 0.1 + gather18.z, 1.1 - gather18.z);
|
||
|
cg4_1 = cg4;
|
||
|
cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;cg4 *= cg4;
|
||
|
hi += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
cg4 *= cg4_1;
|
||
|
hi2 += cg4.x * wg + cg4.z * wg.wzyx;
|
||
|
lo2 += cg4.y * wg + cg4.w * wg.wzyx;
|
||
|
w = texture(ravu_lite_lut4, vec2(0.98, coord_y));
|
||
|
wg = max(vec4(0.0), w);
|
||
|
res += gather16.y * w;
|
||
|
vec2 cg2 = vec2(0.1 + gather16.y, 1.1 - gather16.y);
|
||
|
vec2 cg2_1 = cg2;
|
||
|
cg2 *= cg2;cg2 *= cg2;cg2 *= cg2;cg2 *= cg2;cg2 *= cg2;
|
||
|
hi += cg2.x * wg;
|
||
|
lo += cg2.y * wg;
|
||
|
cg2 *= cg2_1;
|
||
|
hi2 += cg2.x * wg;
|
||
|
lo2 += cg2.y * wg;
|
||
|
lo = 1.1 - lo2 / lo;
|
||
|
hi = hi2 / hi - 0.1;
|
||
|
res = mix(res, clamp(res, lo, hi), ravu_antiring);
|
||
|
return res;
|
||
|
}
|
||
|
//!DESC RAVU-Lite AR 2 [R4]
|
||
|
//!HOOK LUMA
|
||
|
//!BIND HOOKED
|
||
|
//!BIND ravu_lite_int
|
||
|
//!WIDTH 2 HOOKED.w *
|
||
|
//!HEIGHT 2 HOOKED.h *
|
||
|
//!WHEN OUTPUT.w HOOKED.w / 1.41421356 > OUTPUT.h HOOKED.h / 1.41421356 > *
|
||
|
//!COMPONENTS 1
|
||
|
vec4 hook() {
|
||
|
vec2 dir = fract(HOOKED_pos * HOOKED_size) - 0.5;
|
||
|
int idx = int(dir.x > 0.0) * 2 + int(dir.y > 0.0);
|
||
|
return vec4(ravu_lite_int_texOff(-dir)[idx], 0.0, 0.0, 0.0);
|
||
|
}
|
||
|
//!TEXTURE ravu_lite_lut4
|
||
|
//!SIZE 25 288
|
||
|
//!FORMAT rgba16f
|
||
|
//!FILTER NEAREST
|
||
|
cdd62e37a650b737dd8719b950a8d038d9d96c39bbdc73bafb218d3ad9d79fb95340343ae847f4b99d82a739465c3cbaa8950cbae80da6b9031f4e393097ca39a6660dba43f5453ae07d30bad92c9739ede35fba28a8c2393f0a68b934474c3a05420ab82f19183630e50839a60dd2b8b6ac35394a30273a9ba72cba84c30ab80a59c93a684edeb86f99f5b8b5d887ba3a7f6d397fd63ebba945253b628d633a4d86873b7abe803b80fab83ae447943ae2a33bbbb06a823963e2323a6ce62c3b94e797b80077c53a5cb68cbad42f88b8af334f3a2d613d398aabe3b8e83745ba3344a03a331b3b3a88de74ba3a8a94bacb1d8e3a17c9373baab65bbbdfaaec3890ccff3c64552ebc183348bca30cc3bb2b819a3d84459a3db42dfdbdd1a0fcbdd6172dbcce6cff3c0379c0bb81ae49bc9d8c353bfbfd9d3a0a7178b848105bbbee67413a6265a63a55629dbaaf1778ba3ae50db993168139f162d8b97eb5e4b72e56983be64a5e3ab7aa933bbfe6053addc9993d2f3ffcbdd31b993d072afcbd397e8a3fbc8a8a3fbc8a8a3f397e8a3f6fdc0b3812cb0e39ad3277b8cd9905b96880cbb9642dfc39e4701cb9d3eeb33851d9003bd1096bba8ac8253a10a206bb296de7b99462b5b60aaeaeb9fcb63fb9883df5b9ab10f53a65160fbb9aead83962bb19b9092cc4b93155ee391e29a2384a388a3960eec7380eeedab818528db936fd00bb618ca0baccf97b3a2273163b9ce631bba6435aba809fc23a51ad2a3b025ed2baf54802bc45f70e3ca569103b988f95bac660bcba6f21d63b4a45de3b59c408bcd55108bbd698313b0763173cecab2cbae12e18bba8ba1f3b27b0a03a6681d2bae31b12bb9aaf153bbcfde33a9eee563b34525f3b3a5c55bb0ef95abb81983a3b5c09ef3be90ff4bb3185acba2c67383d932414bc3e4b94bcc2796fbc11cfaf3d92aeab3d43ec07be765808bec7fe00bcd9fa3e3d410484bc5235a0bc5bfa183cb66c723b18b54abb6e3011bcc4df923bdcb9b03b09dca2bbb3dca3bb47064e3a2ec78b3a609c07bb57e38fbaa8916a3b7c0ca33b7ef2533a4dde8f3ac546af3d1d4607bedf76aa3dd98d09bef64c8a3f3e7e8a3f3e7e8a3ff64c8a3f994c47394bd9a6b864912a3633c7d3b8d606fbb900f2943ab01d87ba0e08a439cb2b2b3bf0f1d9b916c265398e2b28bbf1e6423a671eda3a4765f9ba725bbcba8ca253bac1d92d3b6b5a19bbd4bb90398488003b9a123fba1785fd371b75b8ba923477b8eb269339fe4c21b9d6da76b8b16902bbd1b084ba9ed2f23a292a843a2e4ae7bb87c72a39f6a6ac3a955bcd3b8440cd398f2f64bc8235753c07df29b92c11adbb121cdebb4e85263c1878323ce16880bce93b2b3a138f623a3d23833ca93da1ba2a9020bc9513173c8bcd523bd98c26bbb2ee1dbb67e90d3b1ea43b3b8709533be7199b3afddcfeba9c4f07bb63c3723ba4303f3cbcb846bcb669b2ba9381473d6f3806bc241785bc1767a2bcd689ac3dbb2cad3db19f07be614707be0fb205bb4a445b3dae94d8bc8d33afbcfc5ca93c2b6a453c721625bce8e2b1bc230ab13beaf8dc3bf14dd2bb344dbcbb7c31733bdc16f33af8db28bb7d4a90bb5c106c3b791e6a3cee2b1bbc05db1e3ace83c23d966309be6ca8ae3d962b13be45318a3f97848a3f97848a3f45318a3fc5593cbaf82a9cb86fc2973916d7f239fdcf433a23e317ba68d30b39db6088b9d1f8a0b936b85bbaf5aae739ec4724397203fc394c6ec439c514b7baaefd35baf30111b963ad5e384536073990b92cba6e663dbaa894493a438d08baf501ee3920df5b39907902ba4446f639049e83b959b5dbbadc22c438dceab0b813f2f13a68e76bba97207839ebafaf3a375bb8b91dba8fbb9ad294bbfde5ef3b034e243bbb3e05bca9be03bcb157713cbcd5713c0b44c0bb1a18a9bbd940553b6ef2113cea6982391b57cfbabcb6f139eccaa93af5138bba522d06bba45afb3a9f3bc43a5921623b568ee03a5d750fbb41e551bb2dbd82bb2b1ad63b39ff83bb43dc183b0dbe263d01aa81bc176cbbbc37d7b03ae992eb3d1e5ae23d966224be264f23beb1ce80bcc60b3e3d159e06bbb7ecd2bcd3220f3cd0ce29bbbd85933a424ed4bbfc7a5a3bbc379c3b680085bbf40b90bb7abb3f39e835433a480423bbfcda57ba5371e1bbc4f4833cc6940cbc1caa643c4367fe3d4d532bbee08ef03dc2472ebe41c0893f144e8a3f144e8a3f41c0893f0fbc27baccaf9e3699825b3ac8724cb92eadff3ac7c50d3a274bf4baada420ba5a9cfdbaafcfbdbab6ed093b46e18b3a7168043b616eef3a376c3fbbce4d0cbbd81fd6b9a7ce62ba1e723b391caa273ac3cea2395fd10f3ba8da50baa70eefbac80d093a9baf0aba30c7c8b9c2c1a63984fe63ba9e2821b8c9a9faba23dc343bf39299ba76560cbb234bad3b121709bb880d96bbd1ce42babfd2123bdf17653b90be0dbc42e514bc21b38b3c906b5d3cf5dcd6bb989eb4bbf261a63b4af3073c40b01fbb4343d0bb1377203b6bf4e03b468097bb2ab88ebbcf77cf3b53b5513b9f5d4f3ab9de75ba8196213b1d51f3bad1ea02bc1780d93b324496bb8dafe93b538c263d89dc98bcbca5a6bc46e42d3b7c56e93d887fd83d104a22be270d1fbed3a635bc444c593d2e5defbb30b801bdf49f813ca4cb7e3a642e49bb5fc257bc039b1a3cb7725b3c834f50bcff382cbc03b2e33b3cc9e43b905a2bbcbd25ccbb62deaeba8166b13c70124ebcd9fdd83ba089063e824f28be7c55e63d0d7934be7372893f659f8a3f659f8a3f7372893fb48a14b8f6bc93b9ac8b5f3908e6113909083fb9aa93233a645aebb9d8dc01389c95173a90dc60ba8772153ac2d3c2b
|