From 10b7c69719700d30f8d716c3f465161753929bac Mon Sep 17 00:00:00 2001 From: relrelb Date: Mon, 15 Nov 2021 11:52:08 +0200 Subject: [PATCH] avm1: Correct `TextFormat` properties coercion --- core/src/avm1/globals/text_format.rs | 43 +- tests/tests/regression_tests.rs | 1 + tests/tests/swfs/avm1/text_format/output.txt | 1147 ++++++++++++++++++ tests/tests/swfs/avm1/text_format/test.fla | Bin 0 -> 5574 bytes tests/tests/swfs/avm1/text_format/test.swf | Bin 0 -> 1355 bytes 5 files changed, 1176 insertions(+), 15 deletions(-) create mode 100644 tests/tests/swfs/avm1/text_format/output.txt create mode 100644 tests/tests/swfs/avm1/text_format/test.fla create mode 100644 tests/tests/swfs/avm1/text_format/test.swf diff --git a/core/src/avm1/globals/text_format.rs b/core/src/avm1/globals/text_format.rs index 92f5cf53d..3e1a4bd72 100644 --- a/core/src/avm1/globals/text_format.rs +++ b/core/src/avm1/globals/text_format.rs @@ -88,8 +88,7 @@ fn set_size<'gc>( ) -> Result<(), Error<'gc>> { text_format.size = match value { Value::Undefined | Value::Null => None, - // TODO: round up - value => Some(value.coerce_to_i32(activation)?.into()), + value => Some(round_to_i32(value.coerce_to_f64(activation)?).into()), }; Ok(()) } @@ -233,7 +232,7 @@ fn set_align<'gc>( "center" => Some(swf::TextAlign::Center), "right" => Some(swf::TextAlign::Right), "justify" => Some(swf::TextAlign::Justify), - _ => None, + _ => return Ok(()), }, }; Ok(()) @@ -256,8 +255,7 @@ fn set_left_margin<'gc>( ) -> Result<(), Error<'gc>> { text_format.left_margin = match value { Value::Undefined | Value::Null => None, - // TODO: round up - value => Some(value.coerce_to_i32(activation)?.into()), + value => Some(round_to_i32(value.coerce_to_f64(activation)?.max(0.0)).into()), }; Ok(()) } @@ -279,8 +277,7 @@ fn set_right_margin<'gc>( ) -> Result<(), Error<'gc>> { text_format.right_margin = match value { Value::Undefined | Value::Null => None, - // TODO: round up - value => Some(value.coerce_to_i32(activation)?.into()), + value => Some(round_to_i32(value.coerce_to_f64(activation)?.max(0.0)).into()), }; Ok(()) } @@ -299,8 +296,7 @@ fn set_indent<'gc>( ) -> Result<(), Error<'gc>> { text_format.indent = match value { Value::Undefined | Value::Null => None, - // TODO: round up - value => Some(value.coerce_to_i32(activation)?.into()), + value => Some(round_to_i32(value.coerce_to_f64(activation)?).into()), }; Ok(()) } @@ -319,8 +315,7 @@ fn set_leading<'gc>( ) -> Result<(), Error<'gc>> { text_format.leading = match value { Value::Undefined | Value::Null => None, - // TODO: round up - value => Some(value.coerce_to_i32(activation)?.into()), + value => Some(round_to_i32(value.coerce_to_f64(activation)?).into()), }; Ok(()) } @@ -342,8 +337,7 @@ fn set_block_indent<'gc>( ) -> Result<(), Error<'gc>> { text_format.block_indent = match value { Value::Undefined | Value::Null => None, - // TODO: round up - value => Some(value.coerce_to_i32(activation)?.into()), + value => Some(round_to_i32(value.coerce_to_f64(activation)?).into()), }; Ok(()) } @@ -376,8 +370,7 @@ fn set_tab_stops<'gc>( let tab_stops: Result, Error<'gc>> = (0..length) .map(|i| { let element = object.get_element(activation, i); - // TODO: round up - Ok(element.coerce_to_i32(activation)?.into()) + Ok(round_to_i32(element.coerce_to_f64(activation)?).into()) }) .collect(); Some(tab_stops?) @@ -551,3 +544,23 @@ pub fn create_proto<'gc>( define_properties_on(PROTO_DECLS, gc_context, object, fn_proto); text_format.into() } + +/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule. +/// (e.g., both 1.5 and 2.5 will round to 2). +/// This is the rounding method used by Flash for the above coercions. +/// Although this is easy to do on most architectures, Rust provides no standard +/// way to round in this manner (`f64::round` always rounds away from zero). +/// For more info and the below code snippet, see: https://github.com/rust-lang/rust/issues/55107 +/// This also clamps out-of-range values and NaN to `i32::MIN`. +/// TODO: Investigate using SSE/wasm intrinsics for this. +fn round_to_i32(x: f64) -> i32 { + let k = 1.0 / f64::EPSILON; + let a = x.abs(); + let out = if a < k { ((a + k) - k).copysign(x) } else { x }; + // Values outside of i32 range get clamped to i32::MIN. + if out.is_finite() && out >= i32::MIN.into() && out <= i32::MAX.into() { + out as i32 + } else { + i32::MIN + } +} diff --git a/tests/tests/regression_tests.rs b/tests/tests/regression_tests.rs index bb96fa87e..a1475f188 100644 --- a/tests/tests/regression_tests.rs +++ b/tests/tests/regression_tests.rs @@ -324,6 +324,7 @@ swf_tests! { (textfield_background_color, "avm1/textfield_background_color", 1), (textfield_border_color, "avm1/textfield_border_color", 1), (textfield_variable, "avm1/textfield_variable", 8), + (text_format, "avm1/text_format", 1), (error, "avm1/error", 1), (color_transform, "avm1/color_transform", 1), (with, "avm1/with", 1), diff --git a/tests/tests/swfs/avm1/text_format/output.txt b/tests/tests/swfs/avm1/text_format/output.txt new file mode 100644 index 000000000..281894f4c --- /dev/null +++ b/tests/tests/swfs/avm1/text_format/output.txt @@ -0,0 +1,1147 @@ +// format.font = null +// format.font +null +// typeof format.font +null + +// format.font = undefined +// format.font +null +// typeof format.font +null + +// format.font = test +// format.font +test +// typeof format.font +string + +// format.font = [object] +in callback +// format.font +from callback +// typeof format.font +string + +// format.size = null +// format.size +null +// typeof format.size +null + +// format.size = undefined +// format.size +null +// typeof format.size +null + +// format.size = -3.5 +// format.size +-4 +// typeof format.size +number + +// format.size = -3 +// format.size +-3 +// typeof format.size +number + +// format.size = -2.5 +// format.size +-2 +// typeof format.size +number + +// format.size = 0 +// format.size +0 +// typeof format.size +number + +// format.size = 2.5 +// format.size +2 +// typeof format.size +number + +// format.size = 3 +// format.size +3 +// typeof format.size +number + +// format.size = 3.5 +// format.size +4 +// typeof format.size +number + +// format.size = 305419896 +// format.size +305419896 +// typeof format.size +number + +// format.size = 4294967295 +// format.size +-2147483648 +// typeof format.size +number + +// format.size = NaN +// format.size +-2147483648 +// typeof format.size +number + +// format.size = Infinity +// format.size +-2147483648 +// typeof format.size +number + +// format.size = -Infinity +// format.size +-2147483648 +// typeof format.size +number + +// format.size = [object] +in callback +// format.size +3 +// typeof format.size +number + +// format.color = null +// format.color +null +// typeof format.color +null + +// format.color = undefined +// format.color +null +// typeof format.color +null + +// format.color = -3.5 +// format.color +4294967293 +// typeof format.color +number + +// format.color = -3 +// format.color +4294967293 +// typeof format.color +number + +// format.color = -2.5 +// format.color +4294967294 +// typeof format.color +number + +// format.color = 0 +// format.color +0 +// typeof format.color +number + +// format.color = 2.5 +// format.color +2 +// typeof format.color +number + +// format.color = 3 +// format.color +3 +// typeof format.color +number + +// format.color = 3.5 +// format.color +3 +// typeof format.color +number + +// format.color = 305419896 +// format.color +305419896 +// typeof format.color +number + +// format.color = 4294967295 +// format.color +4294967295 +// typeof format.color +number + +// format.color = NaN +// format.color +0 +// typeof format.color +number + +// format.color = Infinity +// format.color +0 +// typeof format.color +number + +// format.color = -Infinity +// format.color +0 +// typeof format.color +number + +// format.color = [object] +in callback +// format.color +3 +// typeof format.color +number + +// format.url = null +// format.url +null +// typeof format.url +null + +// format.url = undefined +// format.url +null +// typeof format.url +null + +// format.url = test +// format.url +test +// typeof format.url +string + +// format.url = [object] +in callback +// format.url +from callback +// typeof format.url +string + +// format.target = null +// format.target +null +// typeof format.target +null + +// format.target = undefined +// format.target +null +// typeof format.target +null + +// format.target = test +// format.target +test +// typeof format.target +string + +// format.target = [object] +in callback +// format.target +from callback +// typeof format.target +string + +// format.bold = null +// format.bold +null +// typeof format.bold +null + +// format.bold = undefined +// format.bold +null +// typeof format.bold +null + +// format.bold = false +// format.bold +false +// typeof format.bold +boolean + +// format.bold = 0 +// format.bold +false +// typeof format.bold +boolean + +// format.bold = +// format.bold +false +// typeof format.bold +boolean + +// format.bold = true +// format.bold +true +// typeof format.bold +boolean + +// format.bold = 0.5 +// format.bold +true +// typeof format.bold +boolean + +// format.bold = test +// format.bold +true +// typeof format.bold +boolean + +// format.bold = [object] +// format.bold +true +// typeof format.bold +boolean + +// format.italic = null +// format.italic +null +// typeof format.italic +null + +// format.italic = undefined +// format.italic +null +// typeof format.italic +null + +// format.italic = false +// format.italic +false +// typeof format.italic +boolean + +// format.italic = 0 +// format.italic +false +// typeof format.italic +boolean + +// format.italic = +// format.italic +false +// typeof format.italic +boolean + +// format.italic = true +// format.italic +true +// typeof format.italic +boolean + +// format.italic = 0.5 +// format.italic +true +// typeof format.italic +boolean + +// format.italic = test +// format.italic +true +// typeof format.italic +boolean + +// format.italic = [object] +// format.italic +true +// typeof format.italic +boolean + +// format.underline = null +// format.underline +null +// typeof format.underline +null + +// format.underline = undefined +// format.underline +null +// typeof format.underline +null + +// format.underline = false +// format.underline +false +// typeof format.underline +boolean + +// format.underline = 0 +// format.underline +false +// typeof format.underline +boolean + +// format.underline = +// format.underline +false +// typeof format.underline +boolean + +// format.underline = true +// format.underline +true +// typeof format.underline +boolean + +// format.underline = 0.5 +// format.underline +true +// typeof format.underline +boolean + +// format.underline = test +// format.underline +true +// typeof format.underline +boolean + +// format.underline = [object] +// format.underline +true +// typeof format.underline +boolean + +// format.align = null +// format.align +null +// typeof format.align +null + +// format.align = undefined +// format.align +null +// typeof format.align +null + +// format.align = left +// format.align +left +// typeof format.align +string + +// format.align = center +// format.align +center +// typeof format.align +string + +// format.align = right +// format.align +right +// typeof format.align +string + +// format.align = justify +// format.align +justify +// typeof format.align +string + +// format.align = invalid +// format.align +justify +// typeof format.align +string + +// format.align = [object] +in callback +// format.align +left +// typeof format.align +string + +// format.leftMargin = null +// format.leftMargin +null +// typeof format.leftMargin +null + +// format.leftMargin = undefined +// format.leftMargin +null +// typeof format.leftMargin +null + +// format.leftMargin = -3.5 +// format.leftMargin +0 +// typeof format.leftMargin +number + +// format.leftMargin = -3 +// format.leftMargin +0 +// typeof format.leftMargin +number + +// format.leftMargin = -2.5 +// format.leftMargin +0 +// typeof format.leftMargin +number + +// format.leftMargin = 0 +// format.leftMargin +0 +// typeof format.leftMargin +number + +// format.leftMargin = 2.5 +// format.leftMargin +2 +// typeof format.leftMargin +number + +// format.leftMargin = 3 +// format.leftMargin +3 +// typeof format.leftMargin +number + +// format.leftMargin = 3.5 +// format.leftMargin +4 +// typeof format.leftMargin +number + +// format.leftMargin = 305419896 +// format.leftMargin +305419896 +// typeof format.leftMargin +number + +// format.leftMargin = 4294967295 +// format.leftMargin +-2147483648 +// typeof format.leftMargin +number + +// format.leftMargin = NaN +// format.leftMargin +0 +// typeof format.leftMargin +number + +// format.leftMargin = Infinity +// format.leftMargin +-2147483648 +// typeof format.leftMargin +number + +// format.leftMargin = -Infinity +// format.leftMargin +0 +// typeof format.leftMargin +number + +// format.leftMargin = [object] +in callback +// format.leftMargin +3 +// typeof format.leftMargin +number + +// format.rightMargin = null +// format.rightMargin +null +// typeof format.rightMargin +null + +// format.rightMargin = undefined +// format.rightMargin +null +// typeof format.rightMargin +null + +// format.rightMargin = -3.5 +// format.rightMargin +0 +// typeof format.rightMargin +number + +// format.rightMargin = -3 +// format.rightMargin +0 +// typeof format.rightMargin +number + +// format.rightMargin = -2.5 +// format.rightMargin +0 +// typeof format.rightMargin +number + +// format.rightMargin = 0 +// format.rightMargin +0 +// typeof format.rightMargin +number + +// format.rightMargin = 2.5 +// format.rightMargin +2 +// typeof format.rightMargin +number + +// format.rightMargin = 3 +// format.rightMargin +3 +// typeof format.rightMargin +number + +// format.rightMargin = 3.5 +// format.rightMargin +4 +// typeof format.rightMargin +number + +// format.rightMargin = 305419896 +// format.rightMargin +305419896 +// typeof format.rightMargin +number + +// format.rightMargin = 4294967295 +// format.rightMargin +-2147483648 +// typeof format.rightMargin +number + +// format.rightMargin = NaN +// format.rightMargin +0 +// typeof format.rightMargin +number + +// format.rightMargin = Infinity +// format.rightMargin +-2147483648 +// typeof format.rightMargin +number + +// format.rightMargin = -Infinity +// format.rightMargin +0 +// typeof format.rightMargin +number + +// format.rightMargin = [object] +in callback +// format.rightMargin +3 +// typeof format.rightMargin +number + +// format.indent = null +// format.indent +null +// typeof format.indent +null + +// format.indent = undefined +// format.indent +null +// typeof format.indent +null + +// format.indent = -3.5 +// format.indent +-4 +// typeof format.indent +number + +// format.indent = -3 +// format.indent +-3 +// typeof format.indent +number + +// format.indent = -2.5 +// format.indent +-2 +// typeof format.indent +number + +// format.indent = 0 +// format.indent +0 +// typeof format.indent +number + +// format.indent = 2.5 +// format.indent +2 +// typeof format.indent +number + +// format.indent = 3 +// format.indent +3 +// typeof format.indent +number + +// format.indent = 3.5 +// format.indent +4 +// typeof format.indent +number + +// format.indent = 305419896 +// format.indent +305419896 +// typeof format.indent +number + +// format.indent = 4294967295 +// format.indent +-2147483648 +// typeof format.indent +number + +// format.indent = NaN +// format.indent +-2147483648 +// typeof format.indent +number + +// format.indent = Infinity +// format.indent +-2147483648 +// typeof format.indent +number + +// format.indent = -Infinity +// format.indent +-2147483648 +// typeof format.indent +number + +// format.indent = [object] +in callback +// format.indent +3 +// typeof format.indent +number + +// format.leading = null +// format.leading +null +// typeof format.leading +null + +// format.leading = undefined +// format.leading +null +// typeof format.leading +null + +// format.leading = -3.5 +// format.leading +-4 +// typeof format.leading +number + +// format.leading = -3 +// format.leading +-3 +// typeof format.leading +number + +// format.leading = -2.5 +// format.leading +-2 +// typeof format.leading +number + +// format.leading = 0 +// format.leading +0 +// typeof format.leading +number + +// format.leading = 2.5 +// format.leading +2 +// typeof format.leading +number + +// format.leading = 3 +// format.leading +3 +// typeof format.leading +number + +// format.leading = 3.5 +// format.leading +4 +// typeof format.leading +number + +// format.leading = 305419896 +// format.leading +305419896 +// typeof format.leading +number + +// format.leading = 4294967295 +// format.leading +-2147483648 +// typeof format.leading +number + +// format.leading = NaN +// format.leading +-2147483648 +// typeof format.leading +number + +// format.leading = Infinity +// format.leading +-2147483648 +// typeof format.leading +number + +// format.leading = -Infinity +// format.leading +-2147483648 +// typeof format.leading +number + +// format.leading = [object] +in callback +// format.leading +3 +// typeof format.leading +number + +// format.blockIndent = null +// format.blockIndent +null +// typeof format.blockIndent +null + +// format.blockIndent = undefined +// format.blockIndent +null +// typeof format.blockIndent +null + +// format.blockIndent = -3.5 +// format.blockIndent +-4 +// typeof format.blockIndent +number + +// format.blockIndent = -3 +// format.blockIndent +-3 +// typeof format.blockIndent +number + +// format.blockIndent = -2.5 +// format.blockIndent +-2 +// typeof format.blockIndent +number + +// format.blockIndent = 0 +// format.blockIndent +0 +// typeof format.blockIndent +number + +// format.blockIndent = 2.5 +// format.blockIndent +2 +// typeof format.blockIndent +number + +// format.blockIndent = 3 +// format.blockIndent +3 +// typeof format.blockIndent +number + +// format.blockIndent = 3.5 +// format.blockIndent +4 +// typeof format.blockIndent +number + +// format.blockIndent = 305419896 +// format.blockIndent +305419896 +// typeof format.blockIndent +number + +// format.blockIndent = 4294967295 +// format.blockIndent +-2147483648 +// typeof format.blockIndent +number + +// format.blockIndent = NaN +// format.blockIndent +-2147483648 +// typeof format.blockIndent +number + +// format.blockIndent = Infinity +// format.blockIndent +-2147483648 +// typeof format.blockIndent +number + +// format.blockIndent = -Infinity +// format.blockIndent +-2147483648 +// typeof format.blockIndent +number + +// format.blockIndent = [object] +in callback +// format.blockIndent +3 +// typeof format.blockIndent +number + +// format.tabStops = null +// format.tabStops +null +// typeof format.tabStops +null + +// format.tabStops = undefined +// format.tabStops +null +// typeof format.tabStops +null + +// format.tabStops = [object] +in callback +// format.tabStops +-4,-3,-2,0,2,3,4,5 +// typeof format.tabStops +object + +// format.tabStops = [object] +// format.tabStops +3 +// typeof format.tabStops +object + +// format.bullet = null +// format.bullet +null +// typeof format.bullet +null + +// format.bullet = undefined +// format.bullet +null +// typeof format.bullet +null + +// format.bullet = false +// format.bullet +false +// typeof format.bullet +boolean + +// format.bullet = 0 +// format.bullet +false +// typeof format.bullet +boolean + +// format.bullet = +// format.bullet +false +// typeof format.bullet +boolean + +// format.bullet = true +// format.bullet +true +// typeof format.bullet +boolean + +// format.bullet = 0.5 +// format.bullet +true +// typeof format.bullet +boolean + +// format.bullet = test +// format.bullet +true +// typeof format.bullet +boolean + +// format.bullet = [object] +// format.bullet +true +// typeof format.bullet +boolean + +// format.kerning = null +// format.kerning +null +// typeof format.kerning +null + +// format.kerning = undefined +// format.kerning +null +// typeof format.kerning +null + +// format.kerning = false +// format.kerning +false +// typeof format.kerning +boolean + +// format.kerning = 0 +// format.kerning +false +// typeof format.kerning +boolean + +// format.kerning = +// format.kerning +false +// typeof format.kerning +boolean + +// format.kerning = true +// format.kerning +true +// typeof format.kerning +boolean + +// format.kerning = 0.5 +// format.kerning +true +// typeof format.kerning +boolean + +// format.kerning = test +// format.kerning +true +// typeof format.kerning +boolean + +// format.kerning = [object] +// format.kerning +true +// typeof format.kerning +boolean + +// format.letterSpacing = null +// format.letterSpacing +null +// typeof format.letterSpacing +null + +// format.letterSpacing = undefined +// format.letterSpacing +null +// typeof format.letterSpacing +null + +// format.letterSpacing = -3.5 +// format.letterSpacing +-3.5 +// typeof format.letterSpacing +number + +// format.letterSpacing = -3 +// format.letterSpacing +-3 +// typeof format.letterSpacing +number + +// format.letterSpacing = -2.5 +// format.letterSpacing +-2.5 +// typeof format.letterSpacing +number + +// format.letterSpacing = 0 +// format.letterSpacing +0 +// typeof format.letterSpacing +number + +// format.letterSpacing = 2.5 +// format.letterSpacing +2.5 +// typeof format.letterSpacing +number + +// format.letterSpacing = 3 +// format.letterSpacing +3 +// typeof format.letterSpacing +number + +// format.letterSpacing = 3.5 +// format.letterSpacing +3.5 +// typeof format.letterSpacing +number + +// format.letterSpacing = 305419896 +// format.letterSpacing +305419896 +// typeof format.letterSpacing +number + +// format.letterSpacing = 4294967295 +// format.letterSpacing +4294967295 +// typeof format.letterSpacing +number + +// format.letterSpacing = NaN +// format.letterSpacing +NaN +// typeof format.letterSpacing +number + +// format.letterSpacing = Infinity +// format.letterSpacing +Infinity +// typeof format.letterSpacing +number + +// format.letterSpacing = -Infinity +// format.letterSpacing +-Infinity +// typeof format.letterSpacing +number + +// format.letterSpacing = [object] +in callback +// format.letterSpacing +3 +// typeof format.letterSpacing +number + diff --git a/tests/tests/swfs/avm1/text_format/test.fla b/tests/tests/swfs/avm1/text_format/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..5dd475f270f1b98f04b795811ae1e530b28c8dc2 GIT binary patch literal 5574 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 F{sjXnmX`nk literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/avm1/text_format/test.swf b/tests/tests/swfs/avm1/text_format/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..22354d952ebbae0a330a4a5f51e48121a6b0584d GIT binary patch literal 1355 zcmV-R1+@A@S5pXn4FCXmoTXJkbK6u9UO9H+Hffu-l$276>Og=NTb5$Gu_tlsT5%_b zButax00WFHJtt~qJ&p9-IB?(yryf1SFfjZO4*Uwv{RbR4cfvl&mL=J43wUBj-@e^% zcfYsqsSlZN051Ioa9sfP@-hH?e|0$nu<06|+GDjP_Pdtt)evpvju~@ml5}!%QaD*J zQ1?iZtJSJhR3t^oqetF5wVBq>+umxfF8T~A@pRX8m`QDsW35elY%7-=()PPfNNalq z&7f^k&}modYmOuriW28Rr&`k`8l&zZrB=Pcy~LKKdB@^sF6|J{Lwd~;n+Fv!FSdK8 zWr(E>c~eS8M!1NI-?~zit9e<;%hf}X=~`Av`){p{QWX?iCCmdZ04c7 zvM;Zp*E-bgYOJm~j%Df^CzSem@0jXOPqb$w-{DekN@K_WS`v1)yZh=5?{=k;x5pln z&a1t>!&8SykBLWnu1?T>bvQ7)yR{wLW16j#9kq^zf@vDH*29gWyrIgiYN@>4l;y@f zwb5+KjmEvQvc6r}@U@SJj@VSH_qc9DHsfEgMM6hx`>uIp;>b>8t(MkHa&x=VRFv(8 zEN@iTTP?YCPp%Y|a-~=qu}+}~YbCDvj2JDKcKuy&G}j|ssjb{dDlU_+Z_S*PX`?9@ zi)u?%XErtwI$|@XG}KaC%DP;sY|mw2hyRZX#msO2aGx%y4pwV7!HnU5AR5uG7)c5o`V>-K{E`zP93c76b?zBwSpcx z)Mmq~gDS(?J@Z>KT-ob&+r$l5bZSu-@Ycc9?h#?orj{{ueTX+P(d^LIWLTpPJ=-9z zW!gi=25&9&;VteWlW7MX4xdeo!Qzn4;Oez4ys>ryTafE;*my|P?qRPCo)XvQ5%`R% z9XOiK(evBM-AO_E4hRma0x6UdzJmdpQY!vtq4P@$&Ig8{QjpXo(=2ix2$fnZ5 zBW{`Fzv;P0YaFC+;!;{jr}jrKBQyF4du!a9Nm^AO&96PrP2UF0I4bgM7@P;BT}a`J zJiD;9f^aSh7a^OCVkAEIGrsNtmi+q9`?(hDgA6PPXl)M8LBu~SA+g_)621^#Q^FOP z$83M_oKf>dSa^v?Y{D}=;pv-$&!qQ*DZF#jJeQ_<_CGIONqC-}{nY??ah6bR>1JFR zZo81QEsiV2#l^{pi-Go+M%rhBVrR;~I^zsQ^#A?!BanF$IdM|v6Jf$c*o*s9!jc1a zabmzS!pshDOgsJnsXOqi-&poitg$G>)XNEcIf1Vv@YMuOih|IUiURj3(*W0@ERMRfp;Ek@(OPF>9X(QI-;8a zdM`k?V(9&trx-)G1C$HUY7BiaM$t3)VX(Ru%kfbReH=rd#L%5Fin87fRzHnZkdL84 N7zup0{sBna8J)Edqk;ec literal 0 HcmV?d00001