From de6c8c4e36317017c746a7ba398a85b10186c061 Mon Sep 17 00:00:00 2001 From: otsmr Date: Sun, 7 Dec 2025 16:10:41 +0100 Subject: [PATCH] add dependencies --- .gitignore | 1 + adaptive_number/LICENSE | 11 + adaptive_number/lib/adaptive_number.dart | 6 + adaptive_number/lib/src/int.dart | 120 + adaptive_number/lib/src/int64.dart | 121 + adaptive_number/lib/src/number.dart | 78 + adaptive_number/lib/src/stub.dart | 4 + adaptive_number/pubspec.yaml | 17 + .../test/adaptive_number_test.dart | 128 + config.lock.yaml | 14 + config.yaml | 42 + dots_indicator/LICENSE | 21 + dots_indicator/lib/dots_indicator.dart | 4 + dots_indicator/lib/src/dots_decorator.dart | 156 + dots_indicator/lib/src/dots_indicator.dart | 187 + dots_indicator/pubspec.yaml | 14 + ed25519_edwards/LICENSE | 201 + ed25519_edwards/lib/ed25519_edwards.dart | 204 + ed25519_edwards/lib/src/const.dart | 10162 +++ ed25519_edwards/lib/src/edwards25519.dart | 2127 + ed25519_edwards/lib/src/numbers.dart | 18 + ed25519_edwards/lib/src/util.dart | 16 + ed25519_edwards/pubspec.yaml | 18 + .../test/benchmark/ed25519_benchmark.dart | 38 + .../test/benchmark/rate_benchmark.dart | 64 + ed25519_edwards/test/ed25519_test.dart | 67 + hashlib/LICENSE | 29 + hashlib/lib/codecs.dart | 7 + hashlib/lib/hashlib.dart | 11 + hashlib/lib/random.dart | 8 + hashlib/lib/src/adler32.dart | 41 + hashlib/lib/src/algorithms/adler32.dart | 46 + hashlib/lib/src/algorithms/argon2/argon2.dart | 149 + .../src/algorithms/argon2/argon2_32bit.dart | 516 + .../src/algorithms/argon2/argon2_64bit.dart | 591 + hashlib/lib/src/algorithms/argon2/common.dart | 298 + .../lib/src/algorithms/argon2/security.dart | 110 + hashlib/lib/src/algorithms/bcrypt/bcrypt.dart | 488 + hashlib/lib/src/algorithms/bcrypt/common.dart | 177 + .../lib/src/algorithms/bcrypt/security.dart | 51 + .../lib/src/algorithms/blake2/blake2b.dart | 4 + .../src/algorithms/blake2/blake2b_32bit.dart | 354 + .../src/algorithms/blake2/blake2b_64bit.dart | 323 + .../lib/src/algorithms/blake2/blake2s.dart | 323 + hashlib/lib/src/algorithms/crc/crc16.dart | 246 + hashlib/lib/src/algorithms/crc/crc32.dart | 215 + hashlib/lib/src/algorithms/crc/crc64.dart | 265 + hashlib/lib/src/algorithms/hmac.dart | 70 + hashlib/lib/src/algorithms/keccak/keccak.dart | 42 + .../src/algorithms/keccak/keccak_32bit.dart | 409 + .../src/algorithms/keccak/keccak_64bit.dart | 282 + hashlib/lib/src/algorithms/md2.dart | 119 + hashlib/lib/src/algorithms/md4.dart | 142 + hashlib/lib/src/algorithms/md5.dart | 175 + hashlib/lib/src/algorithms/pbkdf2/pbkdf2.dart | 137 + .../lib/src/algorithms/pbkdf2/security.dart | 90 + .../algorithms/poly1305/poly1305_32bit.dart | 105 + .../algorithms/poly1305/poly1305_64bit.dart | 220 + .../algorithms/poly1305/poly1305_sink.dart | 4 + .../lib/src/algorithms/ripemd/ripemd128.dart | 328 + .../lib/src/algorithms/ripemd/ripemd160.dart | 494 + .../lib/src/algorithms/ripemd/ripemd256.dart | 343 + .../lib/src/algorithms/ripemd/ripemd320.dart | 527 + hashlib/lib/src/algorithms/scrypt/scrypt.dart | 282 + .../lib/src/algorithms/scrypt/security.dart | 95 + hashlib/lib/src/algorithms/sha1.dart | 163 + hashlib/lib/src/algorithms/sha2/sha2.dart | 113 + .../src/algorithms/sha2/sha2_1024_32bit.dart | 305 + .../src/algorithms/sha2/sha2_1024_64bit.dart | 208 + hashlib/lib/src/algorithms/sha2/sha2_512.dart | 179 + hashlib/lib/src/algorithms/sha3.dart | 44 + hashlib/lib/src/algorithms/shake.dart | 36 + hashlib/lib/src/algorithms/sm3.dart | 176 + hashlib/lib/src/algorithms/xxh3/xxh3_128.dart | 4 + .../src/algorithms/xxh3/xxh3_128_32bit.dart | 32 + .../src/algorithms/xxh3/xxh3_128_64bit.dart | 509 + hashlib/lib/src/algorithms/xxh3/xxh3_64.dart | 4 + .../src/algorithms/xxh3/xxh3_64_32bit.dart | 32 + .../src/algorithms/xxh3/xxh3_64_64bit.dart | 391 + hashlib/lib/src/algorithms/xxh32/xxh32.dart | 4 + .../lib/src/algorithms/xxh32/xxh32_32bit.dart | 136 + .../lib/src/algorithms/xxh32/xxh32_64bit.dart | 119 + hashlib/lib/src/algorithms/xxh64/xxh64.dart | 4 + .../lib/src/algorithms/xxh64/xxh64_32bit.dart | 27 + .../lib/src/algorithms/xxh64/xxh64_64bit.dart | 137 + hashlib/lib/src/argon2.dart | 110 + hashlib/lib/src/bcrypt.dart | 88 + hashlib/lib/src/blake2b.dart | 126 + hashlib/lib/src/blake2s.dart | 125 + hashlib/lib/src/core/block_hash.dart | 82 + hashlib/lib/src/core/hash_base.dart | 170 + hashlib/lib/src/core/hash_base_io.dart | 55 + hashlib/lib/src/core/hash_base_stub.dart | 41 + hashlib/lib/src/core/hash_digest.dart | 146 + hashlib/lib/src/core/kdf_base.dart | 47 + hashlib/lib/src/core/mac_base.dart | 52 + hashlib/lib/src/core/otpauth.dart | 30 + hashlib/lib/src/core/registry.dart | 141 + hashlib/lib/src/crc16.dart | 52 + hashlib/lib/src/crc32.dart | 55 + hashlib/lib/src/crc64.dart | 77 + hashlib/lib/src/hashlib.dart | 52 + hashlib/lib/src/hmac.dart | 53 + hashlib/lib/src/hotp.dart | 85 + hashlib/lib/src/keccak224.dart | 47 + hashlib/lib/src/keccak256.dart | 47 + hashlib/lib/src/keccak384.dart | 47 + hashlib/lib/src/keccak512.dart | 47 + hashlib/lib/src/md2.dart | 38 + hashlib/lib/src/md4.dart | 38 + hashlib/lib/src/md5.dart | 38 + hashlib/lib/src/pbkdf2.dart | 81 + hashlib/lib/src/poly1305.dart | 127 + hashlib/lib/src/random.dart | 81 + hashlib/lib/src/random/generator_js.dart | 24 + hashlib/lib/src/random/generator_vm.dart | 16 + hashlib/lib/src/random/generators.dart | 137 + hashlib/lib/src/random/random.dart | 203 + hashlib/lib/src/random/uuid_v1.dart | 98 + hashlib/lib/src/random/uuid_v3.dart | 85 + hashlib/lib/src/random/uuid_v4.dart | 73 + hashlib/lib/src/random/uuid_v5.dart | 85 + hashlib/lib/src/random/uuid_v6.dart | 97 + hashlib/lib/src/random/uuid_v7.dart | 79 + hashlib/lib/src/random/uuid_v8.dart | 86 + hashlib/lib/src/ripemd128.dart | 38 + hashlib/lib/src/ripemd160.dart | 38 + hashlib/lib/src/ripemd256.dart | 38 + hashlib/lib/src/ripemd320.dart | 39 + hashlib/lib/src/scrypt.dart | 51 + hashlib/lib/src/sha1.dart | 40 + hashlib/lib/src/sha224.dart | 41 + hashlib/lib/src/sha256.dart | 41 + hashlib/lib/src/sha384.dart | 41 + hashlib/lib/src/sha3_224.dart | 44 + hashlib/lib/src/sha3_256.dart | 44 + hashlib/lib/src/sha3_384.dart | 44 + hashlib/lib/src/sha3_512.dart | 44 + hashlib/lib/src/sha512.dart | 41 + hashlib/lib/src/sha512t.dart | 63 + hashlib/lib/src/shake128.dart | 119 + hashlib/lib/src/shake256.dart | 119 + hashlib/lib/src/sm3.dart | 43 + hashlib/lib/src/totp.dart | 82 + hashlib/lib/src/uuid.dart | 140 + hashlib/lib/src/xxh128.dart | 63 + hashlib/lib/src/xxh3.dart | 72 + hashlib/lib/src/xxh32.dart | 58 + hashlib/lib/src/xxh64.dart | 58 + hashlib/pubspec.yaml | 34 + hashlib/test/adler32_test.dart | 38 + hashlib/test/argon2_test.dart | 565 + hashlib/test/bcrypt_test.dart | 643 + hashlib/test/blake2b_test.dart | 213 + hashlib/test/blake2s_test.dart | 182 + hashlib/test/compare_test.dart | 432 + hashlib/test/core/block_hash_test.dart | 102 + hashlib/test/core/hash_base_file_test.dart | 51 + hashlib/test/core/hash_digest_test.dart | 166 + hashlib/test/core/hash_sink_test.dart | 102 + hashlib/test/core/kdf_base_test.dart | 52 + hashlib/test/core/mac_base_test.dart | 82 + hashlib/test/crc16_test.dart | 103 + hashlib/test/crc32_test.dart | 79 + hashlib/test/crc64_test.dart | 95 + hashlib/test/fixures/long.txt | 27 + hashlib/test/fixures/xxh32.csv | 10240 +++ hashlib/test/fixures/xxh3_128.csv | 10240 +++ hashlib/test/fixures/xxh3_64.csv | 10240 +++ hashlib/test/fixures/xxh64.csv | 10240 +++ hashlib/test/hmac_test.dart | 137 + hashlib/test/keccak_test.dart | 78 + hashlib/test/md2_test.dart | 88 + hashlib/test/md4_test.dart | 80 + hashlib/test/md5_test.dart | 118 + hashlib/test/pbkdf2_test.dart | 187 + hashlib/test/poly1305_test.dart | 295 + hashlib/test/random/random_test.dart | 429 + hashlib/test/random/uuid_test.dart | 297 + hashlib/test/registry_test.dart | 89 + hashlib/test/ripemd128_test.dart | 66 + hashlib/test/ripemd160_test.dart | 84 + hashlib/test/ripemd256_test.dart | 68 + hashlib/test/ripemd320_test.dart | 68 + hashlib/test/scrypt_test.dart | 268 + hashlib/test/sha1_test.dart | 76 + hashlib/test/sha224_test.dart | 72 + hashlib/test/sha256_test.dart | 72 + hashlib/test/sha384_test.dart | 79 + hashlib/test/sha3_test.dart | 83 + hashlib/test/sha512_224_test.dart | 77 + hashlib/test/sha512_256_test.dart | 77 + hashlib/test/sha512_test.dart | 82 + hashlib/test/shake_test.dart | 145 + hashlib/test/sm3_test.dart | 93 + hashlib/test/totp_test.dart | 112 + hashlib/test/xxh128_test.dart | 128 + hashlib/test/xxh32_test.dart | 66 + hashlib/test/xxh3_test.dart | 173 + hashlib/test/xxh64_test.dart | 76 + hashlib/test/xxh_test.dart | 71 + hashlib_codecs/LICENSE | 29 + hashlib_codecs/lib/hashlib_codecs.dart | 7 + hashlib_codecs/lib/src/base16.dart | 53 + hashlib_codecs/lib/src/base2.dart | 48 + hashlib_codecs/lib/src/base32.dart | 80 + hashlib_codecs/lib/src/base64.dart | 77 + hashlib_codecs/lib/src/base8.dart | 48 + hashlib_codecs/lib/src/bigint.dart | 59 + hashlib_codecs/lib/src/codecs/base16.dart | 119 + hashlib_codecs/lib/src/codecs/base2.dart | 110 + hashlib_codecs/lib/src/codecs/base32.dart | 383 + hashlib_codecs/lib/src/codecs/base64.dart | 182 + hashlib_codecs/lib/src/codecs/base8.dart | 149 + hashlib_codecs/lib/src/codecs/bigint.dart | 165 + .../lib/src/codecs/crypt/crypt.dart | 6 + .../lib/src/codecs/crypt/crypt_builder.dart | 87 + .../lib/src/codecs/crypt/crypt_codec.dart | 135 + .../lib/src/codecs/crypt/crypt_data.dart | 134 + hashlib_codecs/lib/src/codecs/utf8.dart | 219 + hashlib_codecs/lib/src/codecs_base.dart | 21 + hashlib_codecs/lib/src/core/alphabet.dart | 100 + hashlib_codecs/lib/src/core/byte.dart | 49 + hashlib_codecs/lib/src/core/codec.dart | 58 + hashlib_codecs/lib/src/core/decoder.dart | 63 + hashlib_codecs/lib/src/core/encoder.dart | 59 + hashlib_codecs/lib/src/crypt.dart | 22 + hashlib_codecs/lib/src/utf8.dart | 38 + hashlib_codecs/pubspec.yaml | 25 + hashlib_codecs/test/base16_test.dart | 173 + hashlib_codecs/test/base2_test.dart | 87 + hashlib_codecs/test/base32_test.dart | 457 + hashlib_codecs/test/base64_test.dart | 173 + hashlib_codecs/test/base64url_test.dart | 60 + hashlib_codecs/test/base8_test.dart | 122 + hashlib_codecs/test/bigint_test.dart | 134 + hashlib_codecs/test/core/alphabet_test.dart | 172 + hashlib_codecs/test/core/byte_test.dart | 74 + hashlib_codecs/test/core/codec_test.dart | 101 + hashlib_codecs/test/core/decoder_test.dart | 77 + hashlib_codecs/test/core/encoder_test.dart | 82 + .../test/crypt/crypt_builder_test.dart | 90 + hashlib_codecs/test/crypt/crypt_test.dart | 108 + hashlib_codecs/test/crypt_test.dart | 179 + hashlib_codecs/test/utf8_test.dart | 249 + hashlib_codecs/test/utils.dart | 47 + introduction_screen/LICENSE | 21 + .../lib/introduction_screen.dart | 8 + introduction_screen/lib/src/helper.dart | 19 + .../lib/src/introduction_screen.dart | 737 + .../lib/src/model/page_decoration.dart | 154 + .../lib/src/model/page_view_model.dart | 82 + .../lib/src/model/position.dart | 10 + .../lib/src/ui/footer_content.dart | 28 + .../lib/src/ui/intro_button.dart | 37 + .../lib/src/ui/intro_content.dart | 49 + .../lib/src/ui/intro_page.dart | 144 + introduction_screen/lib/testable_widget.dart | 7 + introduction_screen/pubspec.yaml | 20 + introduction_screen/test/src/helper_test.dart | 17 + .../test/src/introduction_screen_test.dart | 234 + .../test/src/model/page_decoration_test.dart | 65 + .../test/src/model/position_test.dart | 43 + .../test/widget/intro_ui_test.dart | 161 + libsignal_protocol_dart/LICENSE | 674 + .../lib/libsignal_protocol_dart.dart | 52 + libsignal_protocol_dart/lib/src/cbc.dart | 40 + .../lib/src/decryption_callback.dart | 3 + .../device_consistency_code_generator.dart | 41 + .../device_consistency_commitment.dart | 37 + .../devices/device_consistency_signature.dart | 12 + .../lib/src/duplicate_message_exception.dart | 7 + .../lib/src/ecc/curve.dart | 187 + .../lib/src/ecc/djb_ec_private_key.dart | 18 + .../lib/src/ecc/djb_ec_public_key.dart | 44 + .../lib/src/ecc/ec_key_pair.dart | 13 + .../lib/src/ecc/ec_private_key.dart | 6 + .../lib/src/ecc/ec_public_key.dart | 8 + .../lib/src/ecc/ed25519.dart | 117 + libsignal_protocol_dart/lib/src/entry.dart | 6 + libsignal_protocol_dart/lib/src/eq.dart | 4 + .../fingerprint/displayable_fingerprint.dart | 35 + .../lib/src/fingerprint/fingerprint.dart | 12 + .../fingerprint/fingerprint_generator.dart | 20 + .../fingerprint_parsing_exception.dart | 8 + ...ingerprint_version_mismatch_exception.dart | 8 + .../numeric_fingerprint_generator.dart | 79 + .../fingerprint/scannable_fingerprint.dart | 49 + .../lib/src/groups/group_cipher.dart | 98 + .../lib/src/groups/group_session_builder.dart | 48 + .../src/groups/ratchet/sender_chain_key.dart | 31 + .../groups/ratchet/sender_message_key.dart | 24 + .../lib/src/groups/sender_key_name.dart | 28 + .../state/in_memory_sender_key_store.dart | 29 + .../src/groups/state/sender_key_record.dart | 71 + .../src/groups/state/sender_key_state.dart | 107 + .../src/groups/state/sender_key_store.dart | 9 + .../lib/src/identity_key.dart | 33 + .../lib/src/identity_key_pair.dart | 32 + .../lib/src/invalid_key_exception.dart | 7 + .../lib/src/invalid_key_id_exception.dart | 7 + .../lib/src/invalid_mac_exception.dart | 7 + .../lib/src/invalid_message_exception.dart | 7 + .../lib/src/kdf/derived_message_secrets.dart | 29 + .../lib/src/kdf/derived_root_secrets.dart | 20 + libsignal_protocol_dart/lib/src/kdf/hkdf.dart | 81 + .../lib/src/kdf/hkdfv2.dart | 6 + .../lib/src/kdf/hkdfv3.dart | 6 + .../lib/src/legacy_message_exception.dart | 7 + .../lib/src/no_session_exception.dart | 7 + .../lib/src/protocol/ciphertext_message.dart | 16 + .../protocol/device_consistency_message.dart | 71 + .../src/protocol/pre_key_signal_message.dart | 101 + ...nder_key_distribution_message_wrapper.dart | 87 + .../lib/src/protocol/sender_key_message.dart | 108 + .../lib/src/protocol/signal_message.dart | 141 + .../lib/src/provisioning_cipher.dart | 109 + .../alice_signal_protocol_parameters.dart | 25 + .../bob_signal_protocol_parameters.dart | 37 + .../lib/src/ratchet/chain_key.dart | 46 + .../lib/src/ratchet/message_keys.dart | 18 + .../lib/src/ratchet/ratcheting_session.dart | 151 + .../lib/src/ratchet/root_key.dart | 33 + .../symmetric_signal_protocol_parameters.dart | 23 + .../lib/src/session_builder.dart | 156 + .../lib/src/session_cipher.dart | 290 + .../lib/src/signal_protocol_address.dart | 26 + .../src/state/fingerprint_protocol.pb.dart | 225 + .../state/fingerprint_protocol.pbenum.dart | 5 + .../state/fingerprint_protocol.pbjson.dart | 43 + .../state/fingerprint_protocol.pbserver.dart | 7 + .../lib/src/state/identity_key_store.dart | 20 + .../impl/in_memory_identity_key_store.dart | 51 + .../state/impl/in_memory_pre_key_store.dart | 32 + .../state/impl/in_memory_session_store.dart | 63 + .../impl/in_memory_signal_protocol_store.dart | 119 + .../impl/in_memory_signed_pre_key_store.dart | 43 + .../src/state/local_storage_protocol.pb.dart | 2301 + .../state/local_storage_protocol.pbenum.dart | 5 + .../state/local_storage_protocol.pbjson.dart | 348 + .../local_storage_protocol.pbserver.dart | 7 + .../lib/src/state/pre_key_bundle.dart | 45 + .../lib/src/state/pre_key_record.dart | 37 + .../lib/src/state/pre_key_store.dart | 12 + .../lib/src/state/session_record.dart | 86 + .../lib/src/state/session_state.dart | 399 + .../lib/src/state/session_store.dart | 18 + .../lib/src/state/signal_protocol_store.dart | 7 + .../lib/src/state/signed_pre_key_record.dart | 45 + .../lib/src/state/signed_pre_key_store.dart | 15 + .../src/state/whisper_text_protocol.pb.dart | 956 + .../state/whisper_text_protocol.pbenum.dart | 5 + .../state/whisper_text_protocol.pbjson.dart | 96 + .../state/whisper_text_protocol.pbserver.dart | 7 + .../lib/src/untrusted_identity_exception.dart | 8 + .../lib/src/util/byte_util.dart | 87 + .../lib/src/util/identity_key_comparator.dart | 5 + .../lib/src/util/key_helper.dart | 69 + libsignal_protocol_dart/lib/src/util/log.dart | 8 + .../lib/src/util/medium.dart | 1 + libsignal_protocol_dart/pubspec.yaml | 28 + .../test/devices/device_consistency_test.dart | 86 + .../test/ecc/curve25519_test.dart | 459 + .../numeric_fingerprint_generator_test.dart | 553 + .../test/groups/group_cipher_test.dart | 322 + .../test/kdf/hkdf_test.dart | 555 + .../test/provisioning_cipher_test.dart | 29 + .../test/ratchet/chain_key_test.dart | 314 + .../test/ratchet/ratcheting_session_test.dart | 418 + .../test/ratchet/root_key_test.dart | 243 + .../test/session_builder_test.dart | 347 + .../test/session_cipher_test.dart | 256 + .../in_memory_identity_key_store_test.dart | 42 + .../impl/in_memory_pre_key_store_test.dart | 26 + .../impl/in_memory_session_store_test.dart | 48 + .../in_memory_signal_protocol_store_test.dart | 104 + .../in_memory_signed_pre_key_store_test.dart | 41 + .../test_in_memory_identity_key_store.dart | 19 + .../test_in_memory_signal_protocol_store.dart | 19 + .../test/util/byte_util_test.dart | 113 + lottie/LICENSE | 21 + lottie/lib/lottie.dart | 19 + .../content/base_stroke_content.dart | 424 + .../content/compound_trim_path_content.dart | 17 + lottie/lib/src/animation/content/content.dart | 5 + .../src/animation/content/content_group.dart | 271 + .../animation/content/drawing_content.dart | 8 + .../animation/content/ellipse_content.dart | 135 + .../src/animation/content/fill_content.dart | 210 + .../content/gradient_fill_content.dart | 329 + .../content/gradient_stroke_content.dart | 206 + .../src/animation/content/greedy_content.dart | 13 + .../content/key_path_element_content.dart | 4 + .../content/merge_paths_content.dart | 107 + .../animation/content/modifier_content.dart | 1 + .../src/animation/content/path_content.dart | 6 + .../animation/content/polystar_content.dart | 348 + .../animation/content/rectangle_content.dart | 207 + .../animation/content/repeater_content.dart | 163 + .../content/rounded_corners_content.dart | 253 + .../src/animation/content/shape_content.dart | 79 + .../content/shape_modifier_content.dart | 6 + .../src/animation/content/stroke_content.dart | 76 + .../animation/content/trim_path_content.dart | 46 + .../keyframe/base_keyframe_animation.dart | 331 + .../keyframe/color_keyframe_animation.dart | 38 + .../keyframe/double_keyframe_animation.dart | 35 + .../drop_shadow_keyframe_animation.dart | 117 + .../gradient_color_keyframe_animation.dart | 41 + .../keyframe/integer_keyframe_animation.dart | 33 + .../keyframe/keyframe_animation.dart | 6 + .../keyframe/mask_keyframe_animation.dart | 17 + .../src/animation/keyframe/path_keyframe.dart | 40 + .../keyframe/path_keyframe_animation.dart | 58 + .../keyframe/point_keyframe_animation.dart | 52 + .../keyframe/shape_keyframe_animation.dart | 39 + ...lit_dimension_path_keyframe_animation.dart | 36 + .../keyframe/text_keyframe_animation.dart | 74 + .../transform_keyframe_animation.dart | 344 + .../value_callback_keyframe_animation.dart | 53 + lottie/lib/src/composition.dart | 271 + lottie/lib/src/frame_rate.dart | 28 + lottie/lib/src/l.dart | 59 + lottie/lib/src/lottie.dart | 460 + lottie/lib/src/lottie_builder.dart | 592 + lottie/lib/src/lottie_delegates.dart | 95 + lottie/lib/src/lottie_drawable.dart | 274 + lottie/lib/src/lottie_image_asset.dart | 22 + lottie/lib/src/lottie_property.dart | 146 + .../animatable/animatable_color_value.dart | 12 + .../animatable/animatable_double_value.dart | 13 + .../animatable_gradient_color_value.dart | 73 + .../animatable/animatable_integer_value.dart | 14 + .../animatable/animatable_path_value.dart | 29 + .../animatable/animatable_point_value.dart | 12 + .../animatable/animatable_scale_value.dart | 17 + .../animatable/animatable_shape_value.dart | 13 + ...animatable_split_dimension_path_value.dart | 36 + .../animatable/animatable_text_frame.dart | 13 + .../animatable_text_properties.dart | 16 + .../animatable/animatable_transform.dart | 57 + .../model/animatable/animatable_value.dart | 8 + .../animatable/base_animatable_value.dart | 31 + lottie/lib/src/model/content/blur_effect.dart | 7 + .../lib/src/model/content/circle_shape.dart | 29 + .../lib/src/model/content/content_model.dart | 7 + .../src/model/content/drop_shadow_effect.dart | 30 + .../lib/src/model/content/gradient_color.dart | 109 + .../lib/src/model/content/gradient_fill.dart | 42 + .../src/model/content/gradient_stroke.dart | 48 + .../lib/src/model/content/gradient_type.dart | 1 + lottie/lib/src/model/content/layer_blend.dart | 22 + lottie/lib/src/model/content/mask.dart | 23 + lottie/lib/src/model/content/merge_paths.dart | 48 + .../lib/src/model/content/polystar_shape.dart | 60 + .../src/model/content/rectangle_shape.dart | 34 + lottie/lib/src/model/content/repeater.dart | 28 + .../src/model/content/rounded_corners.dart | 18 + lottie/lib/src/model/content/shape_data.dart | 93 + lottie/lib/src/model/content/shape_fill.dart | 39 + lottie/lib/src/model/content/shape_group.dart | 23 + lottie/lib/src/model/content/shape_path.dart | 30 + .../lib/src/model/content/shape_stroke.dart | 68 + .../src/model/content/shape_trim_path.dart | 47 + lottie/lib/src/model/cubic_curve_data.dart | 48 + lottie/lib/src/model/document_data.dart | 77 + lottie/lib/src/model/font.dart | 13 + lottie/lib/src/model/font_character.dart | 45 + lottie/lib/src/model/key_path.dart | 172 + lottie/lib/src/model/key_path_element.dart | 29 + lottie/lib/src/model/layer/base_layer.dart | 689 + .../src/model/layer/composition_layer.dart | 230 + lottie/lib/src/model/layer/image_layer.dart | 85 + lottie/lib/src/model/layer/layer.dart | 129 + lottie/lib/src/model/layer/null_layer.dart | 22 + lottie/lib/src/model/layer/shape_layer.dart | 83 + lottie/lib/src/model/layer/solid_layer.dart | 101 + lottie/lib/src/model/layer/text_layer.dart | 638 + lottie/lib/src/model/marker.dart | 26 + lottie/lib/src/options.dart | 21 + .../parser/animatable_path_value_parser.dart | 85 + .../animatable_text_properties_parser.dart | 73 + .../parser/animatable_transform_parser.dart | 192 + .../src/parser/animatable_value_parser.dart | 111 + lottie/lib/src/parser/blur_effect_parser.dart | 63 + .../lib/src/parser/circle_shape_parser.dart | 62 + lottie/lib/src/parser/color_parser.dart | 35 + .../lib/src/parser/content_model_parser.dart | 91 + .../lib/src/parser/document_data_parser.dart | 98 + .../src/parser/drop_shadow_effect_parser.dart | 95 + lottie/lib/src/parser/float_parser.dart | 6 + .../lib/src/parser/font_character_parser.dart | 76 + lottie/lib/src/parser/font_parser.dart | 45 + .../lib/src/parser/gradient_color_parser.dart | 275 + .../lib/src/parser/gradient_fill_parser.dart | 101 + .../src/parser/gradient_stroke_parser.dart | 158 + lottie/lib/src/parser/integer_parser.dart | 6 + lottie/lib/src/parser/json_utils.dart | 117 + lottie/lib/src/parser/keyframe_parser.dart | 334 + lottie/lib/src/parser/keyframes_parser.dart | 99 + lottie/lib/src/parser/layer_parser.dart | 341 + .../src/parser/lottie_composition_parser.dart | 271 + lottie/lib/src/parser/mask_parser.dart | 60 + lottie/lib/src/parser/merge_paths_parser.dart | 34 + lottie/lib/src/parser/moshi/buffer.dart | 216 + lottie/lib/src/parser/moshi/charcode.dart | 465 + lottie/lib/src/parser/moshi/json_reader.dart | 354 + lottie/lib/src/parser/moshi/json_scope.dart | 67 + .../src/parser/moshi/json_utf8_reader.dart | 1034 + lottie/lib/src/parser/offset_parser.dart | 23 + .../lib/src/parser/path_keyframe_parser.dart | 22 + lottie/lib/src/parser/path_parser.dart | 7 + .../lib/src/parser/polysar_shape_parser.dart | 98 + .../src/parser/rectangle_shape_parser.dart | 59 + lottie/lib/src/parser/repeat_parser.dart | 52 + .../src/parser/rounded_corners_parser.dart | 37 + lottie/lib/src/parser/scale_xy_parser.dart | 18 + lottie/lib/src/parser/shape_data_parser.dart | 93 + lottie/lib/src/parser/shape_fill_parser.dart | 67 + lottie/lib/src/parser/shape_group_parser.dart | 42 + lottie/lib/src/parser/shape_path_parser.dart | 40 + .../lib/src/parser/shape_stroke_parser.dart | 118 + .../src/parser/shape_trim_path_parser.dart | 53 + lottie/lib/src/parser/value_parser.dart | 3 + lottie/lib/src/performance_tracker.dart | 67 + lottie/lib/src/providers/asset_provider.dart | 103 + lottie/lib/src/providers/file_provider.dart | 1 + .../lib/src/providers/file_provider_io.dart | 83 + .../src/providers/file_provider_no_io.dart | 27 + lottie/lib/src/providers/load_fonts.dart | 11 + lottie/lib/src/providers/load_image.dart | 40 + lottie/lib/src/providers/lottie_provider.dart | 138 + lottie/lib/src/providers/memory_provider.dart | 70 + .../lib/src/providers/network_provider.dart | 92 + lottie/lib/src/raw_lottie.dart | 144 + lottie/lib/src/render_cache.dart | 34 + lottie/lib/src/render_cache/key.dart | 37 + lottie/lib/src/render_cache/store.dart | 63 + .../lib/src/render_cache/store_drawing.dart | 134 + lottie/lib/src/render_cache/store_raster.dart | 183 + lottie/lib/src/render_lottie.dart | 310 + lottie/lib/src/utils.dart | 104 + lottie/lib/src/utils/characters.dart | 27 + lottie/lib/src/utils/collection.dart | 69 + lottie/lib/src/utils/dash_path.dart | 43 + lottie/lib/src/utils/gamma_evaluator.dart | 72 + lottie/lib/src/utils/mean_calculator.dart | 11 + lottie/lib/src/utils/misc.dart | 121 + lottie/lib/src/utils/pair.dart | 6 + lottie/lib/src/utils/path_interpolator.dart | 88 + lottie/lib/src/utils/utils.dart | 134 + lottie/lib/src/value/drop_shadow.dart | 48 + lottie/lib/src/value/keyframe.dart | 103 + lottie/lib/src/value/lottie_frame_info.dart | 20 + ...lottie_relative_double_value_callback.dart | 16 + ...ottie_relative_integer_value_callback.dart | 14 + .../lottie_relative_point_value_callback.dart | 16 + .../lib/src/value/lottie_value_callback.dart | 63 + lottie/lib/src/value_delegate.dart | 471 + lottie/pubspec.yaml | 29 + lottie/test/characters_test.dart | 37 + lottie/test/compositions_test.dart | 32 + lottie/test/data/loading_indicator.json | 1 + lottie/test/data/static_lottie.json | 689 + lottie/test/data/warningShimmer.json | 1850 + lottie/test/dotlottie.dart | 39 + lottie/test/dynamic_image_test.dart | 96 + lottie/test/dynamic_properties_test.dart | 478 + lottie/test/dynamic_test.dart | 40 + lottie/test/dynamic_text_properties_test.dart | 61 + lottie/test/dynamic_text_test.dart | 103 + lottie/test/fireworks_test.dart | 26 + lottie/test/flutter_test_config.dart | 22 + lottie/test/frame_rate_test.dart | 17 + lottie/test/gamma_evaluator_test.dart | 13 + lottie/test/golden/AndroidWave_0_0.png | Bin 0 -> 36740 bytes lottie/test/golden/HamburgerArrow_0_0.png | Bin 0 -> 17277 bytes lottie/test/golden/HamburgerArrow_0_5.png | Bin 0 -> 18991 bytes lottie/test/golden/HamburgerArrow_1_0.png | Bin 0 -> 17277 bytes lottie/test/golden/Logo/LogoSmall_0_5.png | Bin 0 -> 45733 bytes lottie/test/golden/Mobilo/A_0_5.png | Bin 0 -> 25224 bytes lottie/test/golden/Mobilo/B_0_5.png | Bin 0 -> 23031 bytes .../test/golden/lottiefiles/atm_link_1_0.png | Bin 0 -> 156589 bytes lottie/test/golden_test.dart | 37 + lottie/test/goldens/all/14595-thumbs-up.png | Bin 0 -> 25667 bytes lottie/test/goldens/all/17297-fireworks.png | Bin 0 -> 39730 bytes lottie/test/goldens/all/Logo/logosmall.png | Bin 0 -> 17439 bytes lottie/test/goldens/all/Mobilo/a.png | Bin 0 -> 30620 bytes lottie/test/goldens/all/Mobilo/apostrophe.png | Bin 0 -> 5821 bytes lottie/test/goldens/all/Mobilo/b.png | Bin 0 -> 17742 bytes .../goldens/all/Mobilo/blinkingcursor.png | Bin 0 -> 1874 bytes lottie/test/goldens/all/Mobilo/c.png | Bin 0 -> 12985 bytes lottie/test/goldens/all/Mobilo/colon.png | Bin 0 -> 6600 bytes lottie/test/goldens/all/Mobilo/comma.png | Bin 0 -> 5288 bytes lottie/test/goldens/all/Mobilo/d.png | Bin 0 -> 21699 bytes lottie/test/goldens/all/Mobilo/e.png | Bin 0 -> 10669 bytes lottie/test/goldens/all/Mobilo/f.png | Bin 0 -> 16253 bytes lottie/test/goldens/all/Mobilo/g.png | Bin 0 -> 21993 bytes lottie/test/goldens/all/Mobilo/h.png | Bin 0 -> 9493 bytes lottie/test/goldens/all/Mobilo/i.png | Bin 0 -> 8558 bytes lottie/test/goldens/all/Mobilo/j.png | Bin 0 -> 25644 bytes lottie/test/goldens/all/Mobilo/k.png | Bin 0 -> 20321 bytes lottie/test/goldens/all/Mobilo/l.png | Bin 0 -> 18095 bytes lottie/test/goldens/all/Mobilo/m.png | Bin 0 -> 19291 bytes lottie/test/goldens/all/Mobilo/n.png | Bin 0 -> 17457 bytes lottie/test/goldens/all/Mobilo/o.png | Bin 0 -> 23361 bytes lottie/test/goldens/all/Mobilo/p.png | Bin 0 -> 14461 bytes lottie/test/goldens/all/Mobilo/q.png | Bin 0 -> 18895 bytes lottie/test/goldens/all/Mobilo/r.png | Bin 0 -> 19559 bytes lottie/test/goldens/all/Mobilo/s.png | Bin 0 -> 16061 bytes lottie/test/goldens/all/Mobilo/t.png | Bin 0 -> 12733 bytes lottie/test/goldens/all/Mobilo/u.png | Bin 0 -> 14550 bytes lottie/test/goldens/all/Mobilo/v.png | Bin 0 -> 14267 bytes lottie/test/goldens/all/Mobilo/w.png | Bin 0 -> 17934 bytes lottie/test/goldens/all/Mobilo/x.png | Bin 0 -> 9610 bytes lottie/test/goldens/all/Mobilo/y.png | Bin 0 -> 21006 bytes lottie/test/goldens/all/Mobilo/z.png | Bin 0 -> 22076 bytes .../all/Tests/ telegramalphacompat.png | Bin 0 -> 1488 bytes .../test/goldens/all/Tests/1669133489622.png | Bin 0 -> 2788 bytes .../goldens/all/Tests/2frameanimation.png | Bin 0 -> 1924 bytes .../test/goldens/all/Tests/2parentsmatte.png | Bin 0 -> 3356 bytes lottie/test/goldens/all/Tests/adrock.png | Bin 0 -> 36003 bytes .../goldens/all/Tests/adrock_converted.png | Bin 0 -> 36003 bytes lottie/test/goldens/all/Tests/airbnb.png | Bin 0 -> 59767 bytes lottie/test/goldens/all/Tests/airbnb400.png | Bin 0 -> 89038 bytes lottie/test/goldens/all/Tests/airbnb800.png | Bin 0 -> 103432 bytes lottie/test/goldens/all/Tests/anim_jpg.png | Bin 0 -> 201349 bytes .../test/goldens/all/Tests/animatedshadow.png | Bin 0 -> 51042 bytes .../goldens/all/Tests/august_view_pulse.png | Bin 0 -> 3814 bytes lottie/test/goldens/all/Tests/autoorient.png | Bin 0 -> 5369 bytes .../test/goldens/all/Tests/beyondbounds.png | Bin 0 -> 4135 bytes lottie/test/goldens/all/Tests/bm.png | Bin 0 -> 24491 bytes .../test/goldens/all/Tests/bm_converted.png | Bin 0 -> 24491 bytes .../test/goldens/all/Tests/bounceeasings.png | Bin 0 -> 4630 bytes lottie/test/goldens/all/Tests/boxposition.png | Bin 0 -> 4079 bytes lottie/test/goldens/all/Tests/catrim.png | Bin 0 -> 19826 bytes .../goldens/all/Tests/catrim_converted.png | Bin 0 -> 19826 bytes lottie/test/goldens/all/Tests/checkswitch.png | Bin 0 -> 31787 bytes lottie/test/goldens/all/Tests/dalek.png | Bin 0 -> 12835 bytes .../goldens/all/Tests/dalek_converted.png | Bin 0 -> 12835 bytes .../goldens/all/Tests/defaultlinejoincap.png | Bin 0 -> 7645 bytes .../all/Tests/differentpointscount.png | Bin 0 -> 22840 bytes .../goldens/all/Tests/dynamicgradient.png | Bin 0 -> 13682 bytes lottie/test/goldens/all/Tests/dynamictext.png | Bin 0 -> 12808 bytes lottie/test/goldens/all/Tests/editedcolor.png | Bin 0 -> 22419 bytes .../goldens/all/Tests/ellipsedirection.png | Bin 0 -> 13243 bytes .../test/goldens/all/Tests/embeddedfont.png | Bin 0 -> 12808 bytes lottie/test/goldens/all/Tests/endframe.png | Bin 0 -> 1490 bytes .../goldens/all/Tests/exported_with_flow.png | Bin 0 -> 49284 bytes lottie/test/goldens/all/Tests/fill.png | Bin 0 -> 9752 bytes lottie/test/goldens/all/Tests/fillblur.png | Bin 0 -> 12922 bytes ...fication_translate_scale_rotation_test.png | Bin 0 -> 30693 bytes lottie/test/goldens/all/Tests/frame.png | Bin 0 -> 1536 bytes lottie/test/goldens/all/Tests/framerate.png | Bin 0 -> 2028 bytes .../Tests/gradientcolorkeyframeanimation.png | Bin 0 -> 109391 bytes .../test/goldens/all/Tests/gradientfill.png | Bin 0 -> 33178 bytes .../goldens/all/Tests/gradientfillblur.png | Bin 0 -> 69696 bytes .../goldens/all/Tests/gradientonecolor.png | Bin 0 -> 13713 bytes .../Tests/gradientopacityinterpolation.png | Bin 0 -> 17115 bytes ...city.changes.multiple.stops.countfirst.png | Bin 0 -> 27830 bytes .../goldens/all/Tests/gradientstrokeblur.png | Bin 0 -> 32654 bytes .../Tests/gradientwithvaryingopacitystops.png | Bin 0 -> 1514 bytes lottie/test/goldens/all/Tests/hd.png | Bin 0 -> 2595 bytes lottie/test/goldens/all/Tests/heart.png | Bin 0 -> 11970 bytes .../Tests/interpolatebetweenopacitystops.png | Bin 0 -> 130722 bytes .../all/Tests/interpolatorloopback.png | Bin 0 -> 1218 bytes lottie/test/goldens/all/Tests/issue_288.png | Bin 0 -> 12906 bytes .../test/goldens/all/Tests/keyframetypes.png | Bin 0 -> 7126 bytes .../all/Tests/kona_splash_animation.png | Bin 0 -> 38527 bytes .../goldens/all/Tests/largecomposition.png | Bin 0 -> 2482 bytes lottie/test/goldens/all/Tests/largesquare.png | Bin 0 -> 1722 bytes lottie/test/goldens/all/Tests/laugh4.png | Bin 0 -> 32756 bytes .../test/goldens/all/Tests/layerblend_0.png | Bin 0 -> 9680 bytes .../test/goldens/all/Tests/layerblend_1.png | Bin 0 -> 9180 bytes .../test/goldens/all/Tests/layerblend_10.png | Bin 0 -> 9710 bytes .../test/goldens/all/Tests/layerblend_11.png | Bin 0 -> 9505 bytes .../test/goldens/all/Tests/layerblend_12.png | Bin 0 -> 9405 bytes .../test/goldens/all/Tests/layerblend_13.png | Bin 0 -> 8576 bytes .../test/goldens/all/Tests/layerblend_14.png | Bin 0 -> 9583 bytes .../test/goldens/all/Tests/layerblend_15.png | Bin 0 -> 9226 bytes .../test/goldens/all/Tests/layerblend_16.png | Bin 0 -> 8914 bytes .../test/goldens/all/Tests/layerblend_17.png | Bin 0 -> 9680 bytes .../test/goldens/all/Tests/layerblend_2.png | Bin 0 -> 9012 bytes .../test/goldens/all/Tests/layerblend_3.png | Bin 0 -> 9167 bytes .../test/goldens/all/Tests/layerblend_4.png | Bin 0 -> 8949 bytes .../test/goldens/all/Tests/layerblend_5.png | Bin 0 -> 8808 bytes .../test/goldens/all/Tests/layerblend_6.png | Bin 0 -> 9206 bytes .../test/goldens/all/Tests/layerblend_7.png | Bin 0 -> 8916 bytes .../test/goldens/all/Tests/layerblend_8.png | Bin 0 -> 9723 bytes .../test/goldens/all/Tests/layerblend_9.png | Bin 0 -> 9029 bytes .../test/goldens/all/Tests/loopplayonce.png | Bin 0 -> 9609 bytes lottie/test/goldens/all/Tests/map.png | Bin 0 -> 5620 bytes lottie/test/goldens/all/Tests/marker.png | Bin 0 -> 2254 bytes lottie/test/goldens/all/Tests/maska.png | Bin 0 -> 4241 bytes lottie/test/goldens/all/Tests/maskinv.png | Bin 0 -> 5023 bytes lottie/test/goldens/all/Tests/masknone.png | Bin 0 -> 2686 bytes lottie/test/goldens/all/Tests/masks.png | Bin 0 -> 6479 bytes .../all/Tests/mattetimestretchline.png | Bin 0 -> 1486 bytes .../all/Tests/mattetimestretchscan.png | Bin 0 -> 13504 bytes .../goldens/all/Tests/missingendvalue.png | Bin 0 -> 90750 bytes lottie/test/goldens/all/Tests/miterlimit.png | Bin 0 -> 11499 bytes lottie/test/goldens/all/Tests/multiline.png | Bin 0 -> 11138 bytes .../test/goldens/all/Tests/nullendshape.png | Bin 0 -> 12598 bytes .../test/goldens/all/Tests/opacity_layers.png | Bin 0 -> 17415 bytes .../test/goldens/all/Tests/opacitystops.png | Bin 0 -> 12690 bytes .../all/Tests/overlapshapewithopacity.png | Bin 0 -> 3335 bytes lottie/test/goldens/all/Tests/parenting.png | Bin 0 -> 10401 bytes lottie/test/goldens/all/Tests/precompblur.png | Bin 0 -> 44003 bytes .../Tests/precompblurdecimapprecompsize.png | Bin 0 -> 44003 bytes lottie/test/goldens/all/Tests/precomps.png | Bin 0 -> 5129 bytes lottie/test/goldens/all/Tests/rect1.png | Bin 0 -> 4511 bytes lottie/test/goldens/all/Tests/rect2.png | Bin 0 -> 4470 bytes lottie/test/goldens/all/Tests/rect3.png | Bin 0 -> 4489 bytes lottie/test/goldens/all/Tests/rect4.png | Bin 0 -> 2702 bytes lottie/test/goldens/all/Tests/rect5.png | Bin 0 -> 3892 bytes lottie/test/goldens/all/Tests/rect6.png | Bin 0 -> 4296 bytes lottie/test/goldens/all/Tests/rect7.png | Bin 0 -> 3459 bytes lottie/test/goldens/all/Tests/rect8.png | Bin 0 -> 5635 bytes lottie/test/goldens/all/Tests/rect9.png | Bin 0 -> 4185 bytes lottie/test/goldens/all/Tests/remap.png | Bin 0 -> 8505 bytes lottie/test/goldens/all/Tests/repeater.png | Bin 0 -> 20413 bytes .../test/goldens/all/Tests/reversedstar.png | Bin 0 -> 7476 bytes lottie/test/goldens/all/Tests/rgb.png | Bin 0 -> 1746 bytes lottie/test/goldens/all/Tests/rgbmarker.png | Bin 0 -> 1917 bytes .../test/goldens/all/Tests/roundedcorners.png | Bin 0 -> 12568 bytes .../goldens/all/Tests/roundednonclosed.png | Bin 0 -> 11719 bytes .../roundedwithalreadyroundedcorners.png | Bin 0 -> 18479 bytes lottie/test/goldens/all/Tests/scale0.png | Bin 0 -> 2171 bytes lottie/test/goldens/all/Tests/shapes.png | Bin 0 -> 15436 bytes lottie/test/goldens/all/Tests/shapetypes.png | Bin 0 -> 8789 bytes lottie/test/goldens/all/Tests/skew.png | Bin 0 -> 3732 bytes .../goldens/all/Tests/solidlayertransform.png | Bin 0 -> 9518 bytes .../goldens/all/Tests/splitdimensions.png | Bin 0 -> 8032 bytes .../goldens/all/Tests/splitpathtransform.png | Bin 0 -> 2245 bytes lottie/test/goldens/all/Tests/squares.png | Bin 0 -> 16583 bytes lottie/test/goldens/all/Tests/starskew.png | Bin 0 -> 22200 bytes .../test/goldens/all/Tests/startendframe.png | Bin 0 -> 3129 bytes .../test/goldens/all/Tests/staticshadow.png | Bin 0 -> 8762 bytes lottie/test/goldens/all/Tests/stroke.png | Bin 0 -> 7182 bytes lottie/test/goldens/all/Tests/strokeblur.png | Bin 0 -> 16698 bytes .../goldens/all/Tests/telegramalphacompat.png | Bin 0 -> 1488 bytes lottie/test/goldens/all/Tests/text.png | Bin 0 -> 16924 bytes ...fication_translate_scale_rotation_text.png | Bin 0 -> 8218 bytes .../all/Tests/text_with_parent_alpha.png | Bin 0 -> 3814 bytes .../test/goldens/all/Tests/textbaseline.png | Bin 0 -> 8734 bytes .../goldens/all/Tests/textwithpscenter.png | Bin 0 -> 9251 bytes .../test/goldens/all/Tests/textwithpsleft.png | Bin 0 -> 2137 bytes .../goldens/all/Tests/tgswithoutopacity.png | Bin 0 -> 40435 bytes lottie/test/goldens/all/Tests/thumb.png | Bin 0 -> 4437 bytes .../all/Tests/timeremapandstartoffset.png | Bin 0 -> 14863 bytes lottie/test/goldens/all/Tests/timestretch.png | Bin 0 -> 2559 bytes .../all/Tests/timestretchandstartoffset.png | Bin 0 -> 1362 bytes .../goldens/all/Tests/timestretchmask.png | Bin 0 -> 4209 bytes .../goldens/all/Tests/timestretchprecomp.png | Bin 0 -> 3655 bytes .../goldens/all/Tests/timestretchprecomp2.png | Bin 0 -> 2034 bytes lottie/test/goldens/all/Tests/trackmattes.png | Bin 0 -> 7241 bytes .../all/Tests/transformwithoutendvalues.png | Bin 0 -> 1632 bytes lottie/test/goldens/all/Tests/trimpaths.png | Bin 0 -> 11288 bytes .../Tests/trimpathsinsideandoutsidegroup.png | Bin 0 -> 8988 bytes .../goldens/all/Tests/trimpathwraparound.png | Bin 0 -> 21787 bytes lottie/test/goldens/all/Tests/weaccept.png | Bin 0 -> 201432 bytes .../goldens/all/Tests/weacceptinlineimage.png | Bin 0 -> 201432 bytes lottie/test/goldens/all/Tests/wile.png | Bin 0 -> 15895 bytes .../test/goldens/all/Tests/zipinlineimage.png | Bin 0 -> 201432 bytes lottie/test/goldens/all/androidwave.png | Bin 0 -> 24375 bytes .../goldens/all/animation-1700642783167.png | Bin 0 -> 12128 bytes .../goldens/all/battery_optimizations.png | Bin 0 -> 27725 bytes lottie/test/goldens/all/blub.png | Bin 0 -> 13403 bytes lottie/test/goldens/all/bluetoothscanning.png | Bin 0 -> 49214 bytes lottie/test/goldens/all/camera_change.png | Bin 0 -> 13571 bytes lottie/test/goldens/all/dynamicgradient.png | Bin 0 -> 13682 bytes lottie/test/goldens/all/envelope.png | Bin 0 -> 49500 bytes .../goldens/all/example_with_images/data.png | Bin 0 -> 11810 bytes .../all/gradientcolorinterpolation.png | Bin 0 -> 45589 bytes lottie/test/goldens/all/hamburgerarrow.png | Bin 0 -> 6668 bytes lottie/test/goldens/all/issue270.png | Bin 0 -> 4543 bytes lottie/test/goldens/all/lf20_w2afea.png | Bin 0 -> 17745 bytes .../goldens/all/lottiefiles/100_percent.png | Bin 0 -> 52440 bytes .../lottiefiles/28861-connection-style-2.png | Bin 0 -> 39864 bytes ...45668-arrow-with-light-passing-through.png | Bin 0 -> 20533 bytes .../goldens/all/lottiefiles/a_mountain.png | Bin 0 -> 30544 bytes .../goldens/all/lottiefiles/accept_arrows.png | Bin 0 -> 29877 bytes .../test/goldens/all/lottiefiles/airbnb.png | Bin 0 -> 59767 bytes .../all/lottiefiles/android_fingerprint.png | Bin 0 -> 11726 bytes lottie/test/goldens/all/lottiefiles/angel.png | Bin 0 -> 31446 bytes lottie/test/goldens/all/lottiefiles/anima.png | Bin 0 -> 6074 bytes .../all/lottiefiles/animated_graph.png | Bin 0 -> 16273 bytes .../all/lottiefiles/animated_laptop_.png | Bin 0 -> 9217 bytes .../goldens/all/lottiefiles/animated_logo.png | Bin 0 -> 22573 bytes .../test/goldens/all/lottiefiles/atm_link.png | Bin 0 -> 56574 bytes .../all/lottiefiles/autoconnect_loading.png | Bin 0 -> 15117 bytes .../goldens/all/lottiefiles/ball_&_map.png | Bin 0 -> 2832 bytes .../all/lottiefiles/banner_animation.png | Bin 0 -> 36230 bytes lottie/test/goldens/all/lottiefiles/bb8.png | Bin 0 -> 108758 bytes lottie/test/goldens/all/lottiefiles/bell.png | Bin 0 -> 12788 bytes lottie/test/goldens/all/lottiefiles/birds.png | Bin 0 -> 19098 bytes .../all/lottiefiles/bitcoin_to_the_moon.png | Bin 0 -> 69829 bytes .../lottiefiles/blood_transfusion_kawaii.png | Bin 0 -> 16986 bytes lottie/test/goldens/all/lottiefiles/bomb.png | Bin 0 -> 50122 bytes lottie/test/goldens/all/lottiefiles/books.png | Bin 0 -> 35403 bytes .../goldens/all/lottiefiles/bootymovin.png | Bin 0 -> 77336 bytes .../all/lottiefiles/bounching_ball.png | Bin 0 -> 8476 bytes .../test/goldens/all/lottiefiles/brain__.png | Bin 0 -> 14191 bytes .../test/goldens/all/lottiefiles/browser.png | Bin 0 -> 9855 bytes .../building_evolution_animation.png | Bin 0 -> 26678 bytes .../test/goldens/all/lottiefiles/camera.png | Bin 0 -> 7388 bytes .../goldens/all/lottiefiles/camptravel.png | Bin 0 -> 12609 bytes .../goldens/all/lottiefiles/cancel_button.png | Bin 0 -> 8051 bytes lottie/test/goldens/all/lottiefiles/cash.png | Bin 0 -> 24504 bytes .../all/lottiefiles/change_to_search_bar.png | Bin 0 -> 4867 bytes .../goldens/all/lottiefiles/check_pop.png | Bin 0 -> 16720 bytes .../test/goldens/all/lottiefiles/chinese.png | Bin 0 -> 33113 bytes lottie/test/goldens/all/lottiefiles/clock.png | Bin 0 -> 42985 bytes .../all/lottiefiles/cloud_disconnection.png | Bin 0 -> 49297 bytes .../all/lottiefiles/code_invite_success.png | Bin 0 -> 19093 bytes .../goldens/all/lottiefiles/coding_ape.png | Bin 0 -> 25559 bytes .../test/goldens/all/lottiefiles/coinfall.png | Bin 0 -> 27172 bytes .../goldens/all/lottiefiles/colorline.png | Bin 0 -> 8066 bytes .../goldens/all/lottiefiles/confusion.png | Bin 0 -> 37818 bytes .../all/lottiefiles/construction_site.png | Bin 0 -> 27055 bytes .../goldens/all/lottiefiles/cooking_app.png | Bin 0 -> 17450 bytes .../goldens/all/lottiefiles/countdown.png | Bin 0 -> 13679 bytes .../goldens/all/lottiefiles/credit_card.png | Bin 0 -> 28105 bytes .../goldens/all/lottiefiles/credit_level.png | Bin 0 -> 23336 bytes .../goldens/all/lottiefiles/cube_loader.png | Bin 0 -> 5382 bytes .../goldens/all/lottiefiles/cubo_livre.png | Bin 0 -> 100476 bytes .../lottiefiles/curly_hair_character_loop.png | Bin 0 -> 86142 bytes .../all/lottiefiles/cycle_animation.png | Bin 0 -> 107548 bytes .../all/lottiefiles/day_night_cycle.png | Bin 0 -> 23660 bytes .../all/lottiefiles/day_of_the_dead.png | Bin 0 -> 32622 bytes .../test/goldens/all/lottiefiles/deadpool.png | Bin 0 -> 29274 bytes .../goldens/all/lottiefiles/delivery_van.png | Bin 0 -> 39775 bytes .../all/lottiefiles/developer-animation.png | Bin 0 -> 13753 bytes .../goldens/all/lottiefiles/dna_loader.png | Bin 0 -> 9562 bytes lottie/test/goldens/all/lottiefiles/dog.png | Bin 0 -> 28461 bytes lottie/test/goldens/all/lottiefiles/done.png | Bin 0 -> 46823 bytes .../goldens/all/lottiefiles/download copy.png | Bin 0 -> 59957 bytes .../test/goldens/all/lottiefiles/download.png | Bin 0 -> 8387 bytes .../goldens/all/lottiefiles/downloader.png | Bin 0 -> 30294 bytes lottie/test/goldens/all/lottiefiles/drop.png | Bin 0 -> 34365 bytes .../all/lottiefiles/drop_to_refresh.png | Bin 0 -> 13344 bytes .../all/lottiefiles/edited-landscape.png | Bin 0 -> 28764 bytes .../all/lottiefiles/elephant_trunk_swing.png | Bin 0 -> 14694 bytes .../goldens/all/lottiefiles/emoji_shock.png | Bin 0 -> 41723 bytes .../goldens/all/lottiefiles/emoji_tongue.png | Bin 0 -> 47809 bytes .../goldens/all/lottiefiles/emoji_wink.png | Bin 0 -> 29818 bytes .../goldens/all/lottiefiles/empty_status.png | Bin 0 -> 15347 bytes .../test/goldens/all/lottiefiles/estimate.png | Bin 0 -> 86081 bytes .../goldens/all/lottiefiles/fab_animate.png | Bin 0 -> 18133 bytes .../fabulous_onboarding_animation.png | Bin 0 -> 50185 bytes .../all/lottiefiles/favourite_app_icon.png | Bin 0 -> 11475 bytes .../goldens/all/lottiefiles/file_error.png | Bin 0 -> 37436 bytes .../all/lottiefiles/finance_animation.png | Bin 0 -> 47265 bytes .../all/lottiefiles/fingerprint_scanner.png | Bin 0 -> 23816 bytes .../goldens/all/lottiefiles/finish,done.png | Bin 0 -> 20557 bytes lottie/test/goldens/all/lottiefiles/fish.png | Bin 0 -> 20097 bytes .../all/lottiefiles/flag_of_mexico.png | Bin 0 -> 70117 bytes lottie/test/goldens/all/lottiefiles/flow.png | Bin 0 -> 15819 bytes lottie/test/goldens/all/lottiefiles/frog.png | Bin 0 -> 38846 bytes .../goldens/all/lottiefiles/funky_chicken.png | Bin 0 -> 126882 bytes .../goldens/all/lottiefiles/gaming_pad.png | Bin 0 -> 23788 bytes lottie/test/goldens/all/lottiefiles/gears.png | Bin 0 -> 79298 bytes .../test/goldens/all/lottiefiles/geometry.png | Bin 0 -> 9286 bytes .../goldens/all/lottiefiles/glow_loading.png | Bin 0 -> 14484 bytes .../gradient_animated_background.png | Bin 0 -> 57209 bytes .../all/lottiefiles/happy birthday.png | Bin 0 -> 25364 bytes .../test/goldens/all/lottiefiles/hardware.png | Bin 0 -> 13079 bytes .../test/goldens/all/lottiefiles/hint_01.png | Bin 0 -> 17365 bytes .../goldens/all/lottiefiles/im_thirsty.png | Bin 0 -> 18414 bytes .../goldens/all/lottiefiles/immiguide_.png | Bin 0 -> 32316 bytes .../all/lottiefiles/in-app_purchasing.png | Bin 0 -> 36752 bytes lottie/test/goldens/all/lottiefiles/india.png | Bin 0 -> 33202 bytes .../all/lottiefiles/infinite_rainbow.png | Bin 0 -> 35087 bytes .../lottiefiles/intelia_logo_animation.png | Bin 0 -> 83920 bytes .../all/lottiefiles/iphone_x_loading.png | Bin 0 -> 10473 bytes .../goldens/all/lottiefiles/jojo_the_bird.png | Bin 0 -> 65093 bytes .../goldens/all/lottiefiles/jolly_walker.png | Bin 0 -> 152642 bytes .../goldens/all/lottiefiles/judgement.png | Bin 0 -> 64002 bytes .../all/lottiefiles/kod.io_logo_reveal.png | Bin 0 -> 18727 bytes .../goldens/all/lottiefiles/la_calavera.png | Bin 0 -> 44397 bytes .../goldens/all/lottiefiles/landing_page.png | Bin 0 -> 24254 bytes .../goldens/all/lottiefiles/lego_loader.png | Bin 0 -> 23673 bytes .../goldens/all/lottiefiles/lf20_fteywrno.png | Bin 0 -> 2229 bytes lottie/test/goldens/all/lottiefiles/light.png | Bin 0 -> 20529 bytes .../goldens/all/lottiefiles/lightsaber.png | Bin 0 -> 12244 bytes .../little_girl_jumping_-_loader.png | Bin 0 -> 53544 bytes .../test/goldens/all/lottiefiles/loading.png | Bin 0 -> 37219 bytes .../goldens/all/lottiefiles/loading_copy.png | Bin 0 -> 166862 bytes .../goldens/all/lottiefiles/loading_disc.png | Bin 0 -> 17306 bytes .../all/lottiefiles/loading_semicircle.png | Bin 0 -> 7367 bytes .../test/goldens/all/lottiefiles/location.png | Bin 0 -> 12595 bytes .../all/lottiefiles/location_marker.png | Bin 0 -> 14007 bytes .../goldens/all/lottiefiles/location_pin.png | Bin 0 -> 11423 bytes .../goldens/all/lottiefiles/lottie_logo_1.png | Bin 0 -> 9426 bytes .../all/lottiefiles/lottiepreview_qr.png | Bin 0 -> 8472 bytes .../test/goldens/all/lottiefiles/mailsent.png | Bin 0 -> 20661 bytes .../man_and_pay_with_credit_card.png | Bin 0 -> 44966 bytes .../goldens/all/lottiefiles/map_animation.png | Bin 0 -> 58119 bytes .../all/lottiefiles/material loading.png | Bin 0 -> 15502 bytes .../all/lottiefiles/material_loader.png | Bin 0 -> 8212 bytes .../all/lottiefiles/material_loading_2.png | Bin 0 -> 10883 bytes .../all/lottiefiles/material_wave_loading.png | Bin 0 -> 12898 bytes .../goldens/all/lottiefiles/me_at_office.png | Bin 0 -> 50374 bytes lottie/test/goldens/all/lottiefiles/medal.png | Bin 0 -> 14336 bytes .../all/lottiefiles/menu_button_alt.png | Bin 0 -> 2502 bytes .../goldens/all/lottiefiles/menubutton2.png | Bin 0 -> 2502 bytes .../test/goldens/all/lottiefiles/mindful.png | Bin 0 -> 24972 bytes .../goldens/all/lottiefiles/mnemonics.png | Bin 0 -> 37050 bytes lottie/test/goldens/all/lottiefiles/money.png | Bin 0 -> 35970 bytes .../goldens/all/lottiefiles/motorcycle.png | Bin 0 -> 39402 bytes .../goldens/all/lottiefiles/moving bus.png | Bin 0 -> 22895 bytes .../goldens/all/lottiefiles/moving_eye.png | Bin 0 -> 35502 bytes .../lottiefiles/no_internet_connection.png | Bin 0 -> 21369 bytes .../all/lottiefiles/notification_request.png | Bin 0 -> 44100 bytes .../test/goldens/all/lottiefiles/octopus.png | Bin 0 -> 10736 bytes .../test/goldens/all/lottiefiles/ofrenda.png | Bin 0 -> 58661 bytes .../lottiefiles/on_off_settings_switch.png | Bin 0 -> 7378 bytes .../test/goldens/all/lottiefiles/pagado.png | Bin 0 -> 32496 bytes .../goldens/all/lottiefiles/pagination.png | Bin 0 -> 8524 bytes .../test/goldens/all/lottiefiles/panel2d.png | Bin 0 -> 7137 bytes .../test/goldens/all/lottiefiles/passport.png | Bin 0 -> 61463 bytes .../patient_successfully_added.png | Bin 0 -> 16211 bytes lottie/test/goldens/all/lottiefiles/payme.png | Bin 0 -> 46598 bytes .../goldens/all/lottiefiles/peli-canon.png | Bin 0 -> 46583 bytes .../goldens/all/lottiefiles/pen_tool_loop.png | Bin 0 -> 36294 bytes .../goldens/all/lottiefiles/pencil_write.png | Bin 0 -> 15902 bytes .../test/goldens/all/lottiefiles/penguin.png | Bin 0 -> 28107 bytes .../goldens/all/lottiefiles/permission.png | Bin 0 -> 110377 bytes .../all/lottiefiles/personal_character.png | Bin 0 -> 62249 bytes .../all/lottiefiles/ph_onboarding_.png | Bin 0 -> 49621 bytes .../goldens/all/lottiefiles/phonological.png | Bin 0 -> 43082 bytes .../all/lottiefiles/pink_drink_machine.png | Bin 0 -> 41239 bytes lottie/test/goldens/all/lottiefiles/plane.png | Bin 0 -> 15260 bytes .../all/lottiefiles/plane_to_dollar.png | Bin 0 -> 25507 bytes .../goldens/all/lottiefiles/play,_pause.png | Bin 0 -> 11139 bytes .../all/lottiefiles/play_and_like_it.png | Bin 0 -> 38855 bytes .../goldens/all/lottiefiles/play_button.png | Bin 0 -> 23910 bytes .../test/goldens/all/lottiefiles/playing.png | Bin 0 -> 22963 bytes lottie/test/goldens/all/lottiefiles/point.png | Bin 0 -> 27250 bytes .../goldens/all/lottiefiles/poo_loader.png | Bin 0 -> 39195 bytes .../lottiefiles/powerupp_app_onboard (1).png | Bin 0 -> 38563 bytes .../all/lottiefiles/powerupp_app_onboard.png | Bin 0 -> 38563 bytes .../goldens/all/lottiefiles/preloader.png | Bin 0 -> 10496 bytes lottie/test/goldens/all/lottiefiles/print.png | Bin 0 -> 12353 bytes .../all/lottiefiles/progress_bar 2.png | Bin 0 -> 3293 bytes .../goldens/all/lottiefiles/progress_bar.png | Bin 0 -> 7540 bytes .../test/goldens/all/lottiefiles/rating.png | Bin 0 -> 31598 bytes .../all/lottiefiles/red_pocket_pop_up.png | Bin 0 -> 32806 bytes .../goldens/all/lottiefiles/rejection.png | Bin 0 -> 111303 bytes .../test/goldens/all/lottiefiles/retweet.png | Bin 0 -> 7548 bytes .../test/goldens/all/lottiefiles/rocket.png | Bin 0 -> 29068 bytes .../all/lottiefiles/rocksauce_title_card.png | Bin 0 -> 13407 bytes lottie/test/goldens/all/lottiefiles/scan.png | Bin 0 -> 32197 bytes .../all/lottiefiles/scan_qr_code_success.png | Bin 0 -> 33099 bytes .../goldens/all/lottiefiles/search_button.png | Bin 0 -> 7491 bytes .../lottiefiles/security_token_roundtable.png | Bin 0 -> 22551 bytes .../goldens/all/lottiefiles/sensor_scan.png | Bin 0 -> 15085 bytes .../all/lottiefiles/servishero_loading.png | Bin 0 -> 32939 bytes .../goldens/all/lottiefiles/simple_loader.png | Bin 0 -> 4354 bytes lottie/test/goldens/all/lottiefiles/sky.png | Bin 0 -> 159059 bytes .../all/lottiefiles/slack_app_loader.png | Bin 0 -> 19204 bytes .../goldens/all/lottiefiles/snowcation.png | Bin 0 -> 35688 bytes .../goldens/all/lottiefiles/socar_logo.png | Bin 0 -> 15952 bytes .../goldens/all/lottiefiles/soda_loader.png | Bin 0 -> 11990 bytes .../test/goldens/all/lottiefiles/spacehub.png | Bin 0 -> 7708 bytes .../all/lottiefiles/spinner loading.png | Bin 0 -> 17385 bytes .../all/lottiefiles/splashy_loader.png | Bin 0 -> 11251 bytes .../all/lottiefiles/square_drop_loader.png | Bin 0 -> 11189 bytes .../test/goldens/all/lottiefiles/star 2.png | Bin 0 -> 24475 bytes .../all/lottiefiles/streetby_test_loading.png | Bin 0 -> 884 bytes .../all/lottiefiles/streetbymorning.png | Bin 0 -> 23060 bytes .../goldens/all/lottiefiles/submit button.png | Bin 0 -> 4605 bytes .../test/goldens/all/lottiefiles/summer.png | Bin 0 -> 26010 bytes .../all/lottiefiles/sushi_and_wine.png | Bin 0 -> 20736 bytes .../goldens/all/lottiefiles/swiftkey-logo.png | Bin 0 -> 19305 bytes .../goldens/all/lottiefiles/swipe_menu.png | Bin 0 -> 8265 bytes .../all/lottiefiles/swipe_right_indicator.png | Bin 0 -> 23006 bytes .../goldens/all/lottiefiles/switch_loop.png | Bin 0 -> 13019 bytes .../all/lottiefiles/the_final_frontier.png | Bin 0 -> 20323 bytes .../goldens/all/lottiefiles/tigerobo_demo.png | Bin 0 -> 36003 bytes .../all/lottiefiles/timer_(3_second_loop).png | Bin 0 -> 39628 bytes .../test/goldens/all/lottiefiles/toggle.png | Bin 0 -> 5676 bytes .../goldens/all/lottiefiles/toggle_switch.png | Bin 0 -> 12703 bytes .../test/goldens/all/lottiefiles/touch_id.png | Bin 0 -> 15395 bytes .../test/goldens/all/lottiefiles/tractor.png | Bin 0 -> 24120 bytes .../all/lottiefiles/tractor_animation.png | Bin 0 -> 48630 bytes .../goldens/all/lottiefiles/trail_loading.png | Bin 0 -> 8258 bytes .../test/goldens/all/lottiefiles/trophy.png | Bin 0 -> 23389 bytes .../all/lottiefiles/trophy_animation.png | Bin 0 -> 41731 bytes .../goldens/all/lottiefiles/truecosmos.png | Bin 0 -> 22474 bytes .../test/goldens/all/lottiefiles/turbine.png | Bin 0 -> 23301 bytes .../goldens/all/lottiefiles/typing dot.png | Bin 0 -> 9006 bytes lottie/test/goldens/all/lottiefiles/uk.png | Bin 0 -> 43850 bytes .../goldens/all/lottiefiles/updating_map.png | Bin 0 -> 15820 bytes lottie/test/goldens/all/lottiefiles/us.png | Bin 0 -> 35848 bytes .../goldens/all/lottiefiles/video_cam.png | Bin 0 -> 20136 bytes .../all/lottiefiles/vigilance_camera.png | Bin 0 -> 48759 bytes .../all/lottiefiles/volume_indicator.png | Bin 0 -> 17378 bytes .../lottiefiles/volume_shake_indicator.png | Bin 0 -> 20720 bytes .../goldens/all/lottiefiles/vr_animation.png | Bin 0 -> 76436 bytes .../goldens/all/lottiefiles/vr_sickness.png | Bin 0 -> 53021 bytes .../test/goldens/all/lottiefiles/walking.png | Bin 0 -> 17534 bytes .../goldens/all/lottiefiles/walking_arrow.png | Bin 0 -> 30630 bytes .../all/lottiefiles/wallet recharge.png | Bin 0 -> 2852 bytes .../all/lottiefiles/washing_machine.png | Bin 0 -> 31387 bytes .../goldens/all/lottiefiles/win_result_2.png | Bin 0 -> 73461 bytes .../goldens/all/lottiefiles/wolf_peek.png | Bin 0 -> 35248 bytes lottie/test/goldens/all/lottiefiles/x_pop.png | Bin 0 -> 13683 bytes .../all/lottiefiles/xamarin_logo_2.png | Bin 0 -> 33581 bytes .../all/lottiefiles/xuanwheel_logo.png | Bin 0 -> 10514 bytes .../goldens/all/lottiefiles/yoga_carpet.png | Bin 0 -> 19270 bytes .../all/lottiefiles/youtube_icon_reveal.png | Bin 0 -> 10201 bytes lottie/test/goldens/all/lottielogo1.png | Bin 0 -> 9426 bytes lottie/test/goldens/all/lottielogo2.png | Bin 0 -> 19402 bytes lottie/test/goldens/all/pass_loading.png | Bin 0 -> 6232 bytes lottie/test/goldens/all/playing.png | Bin 0 -> 73570 bytes .../test/goldens/all/spinning_carrousel.png | Bin 0 -> 61346 bytes lottie/test/goldens/all/sticker.png | Bin 0 -> 41766 bytes lottie/test/goldens/all/tent.png | Bin 0 -> 10749 bytes .../test/goldens/all/twitterheartbutton.png | Bin 0 -> 14657 bytes lottie/test/goldens/all/vegan_font.png | Bin 0 -> 7344 bytes lottie/test/goldens/all/weather/fog.png | Bin 0 -> 18019 bytes lottie/test/goldens/all/weather/hurricane.png | Bin 0 -> 84534 bytes .../goldens/all/weather/thunder-storm.png | Bin 0 -> 32688 bytes lottie/test/goldens/all/weather/tornado.png | Bin 0 -> 34180 bytes lottie/test/goldens/all/weather/windy.png | Bin 0 -> 14406 bytes lottie/test/goldens/dotlottie.png | Bin 0 -> 17903 bytes lottie/test/goldens/dynamic/blur.png | Bin 0 -> 148389 bytes lottie/test/goldens/dynamic/color_filter.png | Bin 0 -> 32806 bytes lottie/test/goldens/dynamic/drop_shadow.png | Bin 0 -> 33173 bytes .../test/goldens/dynamic/ellipse_position.png | Bin 0 -> 29917 bytes lottie/test/goldens/dynamic/ellipse_size.png | Bin 0 -> 30874 bytes .../test/goldens/dynamic/fill_color_green.png | Bin 0 -> 30425 bytes .../goldens/dynamic/fill_color_yellow.png | Bin 0 -> 30426 bytes lottie/test/goldens/dynamic/fill_opacity.png | Bin 0 -> 30425 bytes .../test/goldens/dynamic/matte_property.png | Bin 0 -> 18715 bytes .../goldens/dynamic/null_color_filter.png | Bin 0 -> 30418 bytes .../dynamic/opacity_interpolation_00.png | Bin 0 -> 30424 bytes .../dynamic/opacity_interpolation_05.png | Bin 0 -> 30524 bytes .../dynamic/opacity_interpolation_10.png | Bin 0 -> 30416 bytes .../test/goldens/dynamic/polygon_points.png | Bin 0 -> 32362 bytes .../test/goldens/dynamic/polygon_position.png | Bin 0 -> 30418 bytes .../test/goldens/dynamic/polygon_radius.png | Bin 0 -> 38611 bytes .../test/goldens/dynamic/polygon_rotation.png | Bin 0 -> 30904 bytes .../goldens/dynamic/polygon_roundedness.png | Bin 0 -> 31545 bytes .../dynamic/rectangle_corner_roundedness.png | Bin 0 -> 31639 bytes .../goldens/dynamic/rectangle_position.png | Bin 0 -> 30444 bytes .../test/goldens/dynamic/rectangle_size.png | Bin 0 -> 30631 bytes .../repeater_transform_end_opacity.png | Bin 0 -> 30431 bytes .../dynamic/repeater_transform_position.png | Bin 0 -> 30404 bytes .../dynamic/repeater_transform_rotation.png | Bin 0 -> 31366 bytes .../dynamic/repeater_transform_scale.png | Bin 0 -> 29851 bytes .../repeater_transform_start_opacity.png | Bin 0 -> 30433 bytes lottie/test/goldens/dynamic/solid_color.png | Bin 0 -> 17655 bytes .../goldens/dynamic/star_inner_radius.png | Bin 0 -> 30664 bytes .../dynamic/star_inner_roundedness.png | Bin 0 -> 30823 bytes .../goldens/dynamic/star_outer_radius.png | Bin 0 -> 35824 bytes .../dynamic/star_outer_roundedness.png | Bin 0 -> 31545 bytes lottie/test/goldens/dynamic/star_points.png | Bin 0 -> 32362 bytes lottie/test/goldens/dynamic/star_position.png | Bin 0 -> 30418 bytes lottie/test/goldens/dynamic/star_rotation.png | Bin 0 -> 30904 bytes lottie/test/goldens/dynamic/stroke_color.png | Bin 0 -> 30465 bytes .../test/goldens/dynamic/stroke_opacity.png | Bin 0 -> 30494 bytes lottie/test/goldens/dynamic/stroke_width.png | Bin 0 -> 30688 bytes .../test/goldens/dynamic/time_remapping.png | Bin 0 -> 30459 bytes .../dynamic/transform_anchor_point.png | Bin 0 -> 30468 bytes .../goldens/dynamic/transform_opacity.png | Bin 0 -> 30503 bytes .../goldens/dynamic/transform_position.png | Bin 0 -> 29391 bytes .../dynamic/transform_position_relative.png | Bin 0 -> 30444 bytes .../goldens/dynamic/transform_rotation.png | Bin 0 -> 32428 bytes .../test/goldens/dynamic/transform_scale.png | Bin 0 -> 30272 bytes .../test/goldens/dynamic_image/delegate.png | Bin 0 -> 64814 bytes .../dynamic_image/zip_with_provider.png | Bin 0 -> 64814 bytes lottie/test/goldens/dynamic_text.png | Bin 0 -> 5769 bytes .../dynamic_text/dynamic_text_delegate.png | Bin 0 -> 33352 bytes .../dynamic_text/dynamic_text_emoji.png | Bin 0 -> 39611 bytes .../dynamic_text_valuedelegate.png | Bin 0 -> 44171 bytes .../dynamic_text_valuedelegate_endvalue.png | Bin 0 -> 23195 bytes ...mic_text_valuedelegate_overallprogress.png | Bin 0 -> 23968 bytes .../dynamic_text_valuedelegate_startvalue.png | Bin 0 -> 23195 bytes .../dynamic_text/text_fill_blue__green.png | Bin 0 -> 56760 bytes .../dynamic_text/text_stroke_red__yellow.png | Bin 0 -> 59597 bytes .../dynamic_text/text_stroke_width.png | Bin 0 -> 24984 bytes .../goldens/dynamic_text/text_tracking_1.png | Bin 0 -> 53327 bytes .../goldens/dynamic_text/text_tracking_2.png | Bin 0 -> 33187 bytes lottie/test/goldens/enable_render_cache.png | Bin 0 -> 13493 bytes lottie/test/goldens/fireworks.png | Bin 0 -> 39730 bytes .../goldens/gradients/blub_red_callback.png | Bin 0 -> 25232 bytes .../test/goldens/gradients/blub_red_value.png | Bin 0 -> 25232 bytes .../gradients/linear_gradient_fill.png | Bin 0 -> 32055 bytes .../gradients/linear_gradient_stroke.png | Bin 0 -> 32583 bytes .../opacity_linear_gradient_fill.png | Bin 0 -> 34518 bytes .../gradients/radial_gradient_fill.png | Bin 0 -> 29412 bytes .../gradients/radial_gradient_stroke.png | Bin 0 -> 31502 bytes lottie/test/goldens/lightningbug_file.png | Bin 0 -> 47879 bytes lottie/test/goldens/mirror.png | Bin 0 -> 13207 bytes lottie/test/goldens/opacity_layers.png | Bin 0 -> 18363 bytes lottie/test/goldens/warningShimmer_1.png | Bin 0 -> 47522 bytes lottie/test/goldens/warningShimmer_2.png | Bin 0 -> 47522 bytes lottie/test/goldens/warningShimmer_3.png | Bin 0 -> 47522 bytes lottie/test/gradient_test.dart | 166 + lottie/test/lottie_test.dart | 558 + lottie/test/opacity_layer_test.dart | 41 + lottie/test/parser/moshi/buffer_test.dart | 25 + .../test/parser/moshi/json_reader_test.dart | 113 + lottie/test/render_cache_store_test.dart | 107 + lottie/test/render_cache_test.dart | 276 + lottie/test/screenshot_test.dart | 53 + lottie/test/telegram_sticker_test.dart | 27 + lottie/test/utils.dart | 57 + mutex/LICENSE | 24 + mutex/lib/mutex.dart | 11 + mutex/lib/src/mutex.dart | 84 + mutex/lib/src/read_write_mutex.dart | 293 + mutex/pubspec.yaml | 12 + mutex/test/mutex_multiple_read_test.dart | 102 + mutex/test/mutex_readwrite_test.dart | 485 + mutex/test/mutex_test.dart | 340 + optional/LICENSE | 19 + optional/lib/optional.dart | 10 + optional/lib/optional_internal.dart | 98 + optional/lib/src/absent.dart | 78 + optional/lib/src/extension.dart | 125 + optional/lib/src/novaluepresent.dart | 7 + optional/lib/src/present.dart | 85 + optional/pubspec.yaml | 15 + optional/test/optional_test.dart | 20 + optional/test/src/async.dart | 68 + optional/test/src/equality.dart | 29 + optional/test/src/extension.dart | 107 + optional/test/src/iterable.dart | 68 + optional/test/src/methods.dart | 286 + photo_view/LICENSE | 7 + photo_view/lib/photo_view.dart | 623 + photo_view/lib/photo_view_gallery.dart | 432 + .../src/controller/photo_view_controller.dart | 291 + .../photo_view_controller_delegate.dart | 215 + .../photo_view_scalestate_controller.dart | 98 + photo_view/lib/src/core/photo_view_core.dart | 451 + .../src/core/photo_view_gesture_detector.dart | 196 + .../lib/src/core/photo_view_hit_corners.dart | 78 + .../lib/src/photo_view_computed_scale.dart | 36 + .../lib/src/photo_view_default_widgets.dart | 45 + .../lib/src/photo_view_scale_state.dart | 14 + photo_view/lib/src/photo_view_wrappers.dart | 318 + .../src/utils/ignorable_change_notifier.dart | 109 + .../src/utils/photo_view_hero_attributes.dart | 28 + .../lib/src/utils/photo_view_utils.dart | 139 + photo_view/pubspec.yaml | 19 + photo_view/test/controller_test.dart | 103 + .../test/scale_state_controller_test.dart | 66 + pointycastle/LICENSE | 20 + .../stream_cipher_as_block_cipher.dart | 37 + pointycastle/lib/api.dart | 53 + pointycastle/lib/asn1.dart | 60 + pointycastle/lib/asn1/asn1_encoding_rule.dart | 16 + pointycastle/lib/asn1/asn1_object.dart | 142 + pointycastle/lib/asn1/asn1_parser.dart | 163 + pointycastle/lib/asn1/asn1_tags.dart | 134 + pointycastle/lib/asn1/asn1_utils.dart | 243 + pointycastle/lib/asn1/object_identifiers.dart | 34 + .../lib/asn1/object_identifiers_database.dart | 803 + .../lib/asn1/pkcs/pkcs1/asn1_digest_info.dart | 42 + .../pkcs10/asn1_certification_request.dart | 52 + .../asn1_certification_request_info.dart | 66 + .../pkcs10/asn1_subject_public_key_info.dart | 48 + .../pkcs/pkcs12/asn1_authenticated_safe.dart | 31 + .../lib/asn1/pkcs/pkcs12/asn1_cert_bag.dart | 88 + .../lib/asn1/pkcs/pkcs12/asn1_key_bag.dart | 19 + .../lib/asn1/pkcs/pkcs12/asn1_mac_data.dart | 47 + .../lib/asn1/pkcs/pkcs12/asn1_pfx.dart | 52 + .../pkcs/pkcs12/asn1_pkcs12_attribute.dart | 58 + .../lib/asn1/pkcs/pkcs12/asn1_safe_bag.dart | 93 + .../asn1/pkcs/pkcs12/asn1_safe_contents.dart | 40 + .../asn1/pkcs/pkcs7/asn1_content_info.dart | 65 + .../pkcs7/asn1_encrypted_content_info.dart | 67 + .../asn1/pkcs/pkcs8/asn1_encrypted_data.dart | 38 + .../asn1_encrypted_private_key_info.dart | 3 + .../pkcs/pkcs8/asn1_private_key_info.dart | 108 + .../lib/asn1/primitives/asn1_bit_string.dart | 166 + .../lib/asn1/primitives/asn1_bmp_string.dart | 143 + .../lib/asn1/primitives/asn1_boolean.dart | 68 + .../lib/asn1/primitives/asn1_enumerated.dart | 18 + .../primitives/asn1_generalized_time.dart | 79 + .../lib/asn1/primitives/asn1_ia5_string.dart | 130 + .../lib/asn1/primitives/asn1_integer.dart | 72 + .../lib/asn1/primitives/asn1_null.dart | 53 + .../primitives/asn1_object_identifier.dart | 189 + .../asn1/primitives/asn1_octet_string.dart | 133 + .../primitives/asn1_printable_string.dart | 130 + .../lib/asn1/primitives/asn1_sequence.dart | 94 + .../lib/asn1/primitives/asn1_set.dart | 94 + .../asn1/primitives/asn1_teletext_string.dart | 130 + .../lib/asn1/primitives/asn1_utc_time.dart | 94 + .../lib/asn1/primitives/asn1_utf8_string.dart | 130 + ...upported_asn1_encoding_rule_exception.dart | 14 + .../asn1/unsupported_asn1_tag_exception.dart | 12 + ...supported_object_identifier_exception.dart | 12 + .../x501/asn1_attribute_type_and_value.dart | 59 + pointycastle/lib/asn1/x501/asn1_name.dart | 26 + pointycastle/lib/asn1/x501/asn1_rdn.dart | 21 + .../asn1/x509/asn1_algorithm_identifier.dart | 49 + pointycastle/lib/asymmetric/api.dart | 158 + pointycastle/lib/asymmetric/ec_elgamal.dart | 80 + pointycastle/lib/asymmetric/oaep.dart | 527 + pointycastle/lib/asymmetric/pkcs1.dart | 173 + pointycastle/lib/asymmetric/rsa.dart | 163 + pointycastle/lib/block/aes.dart | 1551 + pointycastle/lib/block/aes_fast.dart | 3000 + pointycastle/lib/block/blowfish.dart | 466 + pointycastle/lib/block/camellia.dart | 698 + pointycastle/lib/block/des_base.dart | 860 + pointycastle/lib/block/desede_engine.dart | 108 + pointycastle/lib/block/modes/cbc.dart | 113 + pointycastle/lib/block/modes/ccm.dart | 344 + pointycastle/lib/block/modes/cfb.dart | 175 + pointycastle/lib/block/modes/ctr.dart | 22 + pointycastle/lib/block/modes/ecb.dart | 43 + pointycastle/lib/block/modes/gcm.dart | 226 + pointycastle/lib/block/modes/gctr.dart | 144 + pointycastle/lib/block/modes/ige.dart | 117 + pointycastle/lib/block/modes/ofb.dart | 104 + pointycastle/lib/block/modes/sic.dart | 23 + pointycastle/lib/block/rc2_engine.dart | 498 + pointycastle/lib/block/twofish.dart | 694 + pointycastle/lib/digests/blake2b.dart | 306 + pointycastle/lib/digests/cshake.dart | 114 + pointycastle/lib/digests/keccak.dart | 49 + pointycastle/lib/digests/md2.dart | 397 + pointycastle/lib/digests/md4.dart | 128 + pointycastle/lib/digests/md5.dart | 153 + pointycastle/lib/digests/ripemd128.dart | 232 + pointycastle/lib/digests/ripemd160.dart | 415 + pointycastle/lib/digests/ripemd256.dart | 256 + pointycastle/lib/digests/ripemd320.dart | 456 + pointycastle/lib/digests/sha1.dart | 145 + pointycastle/lib/digests/sha224.dart | 203 + pointycastle/lib/digests/sha256.dart | 203 + pointycastle/lib/digests/sha3.dart | 50 + pointycastle/lib/digests/sha384.dart | 57 + pointycastle/lib/digests/sha512.dart | 59 + pointycastle/lib/digests/sha512t.dart | 157 + pointycastle/lib/digests/shake.dart | 92 + pointycastle/lib/digests/sm3.dart | 130 + pointycastle/lib/digests/tiger.dart | 1321 + pointycastle/lib/digests/whirlpool.dart | 2297 + pointycastle/lib/digests/xof_utils.dart | 37 + pointycastle/lib/ecc/api.dart | 236 + .../lib/ecc/curves/brainpoolp160r1.dart | 33 + .../lib/ecc/curves/brainpoolp160t1.dart | 33 + .../lib/ecc/curves/brainpoolp192r1.dart | 37 + .../lib/ecc/curves/brainpoolp192t1.dart | 37 + .../lib/ecc/curves/brainpoolp224r1.dart | 41 + .../lib/ecc/curves/brainpoolp224t1.dart | 41 + .../lib/ecc/curves/brainpoolp256r1.dart | 41 + .../lib/ecc/curves/brainpoolp256t1.dart | 41 + .../lib/ecc/curves/brainpoolp320r1.dart | 41 + .../lib/ecc/curves/brainpoolp320t1.dart | 41 + .../lib/ecc/curves/brainpoolp384r1.dart | 41 + .../lib/ecc/curves/brainpoolp384t1.dart | 41 + .../lib/ecc/curves/brainpoolp512r1.dart | 41 + .../lib/ecc/curves/brainpoolp512t1.dart | 41 + .../curves/gostr3410_2001_cryptopro_a.dart | 42 + .../curves/gostr3410_2001_cryptopro_b.dart | 44 + .../curves/gostr3410_2001_cryptopro_c.dart | 42 + .../curves/gostr3410_2001_cryptopro_xcha.dart | 43 + .../curves/gostr3410_2001_cryptopro_xchb.dart | 43 + pointycastle/lib/ecc/curves/prime192v1.dart | 37 + pointycastle/lib/ecc/curves/prime192v2.dart | 37 + pointycastle/lib/ecc/curves/prime192v3.dart | 37 + pointycastle/lib/ecc/curves/prime239v1.dart | 42 + pointycastle/lib/ecc/curves/prime239v2.dart | 42 + pointycastle/lib/ecc/curves/prime239v3.dart | 42 + pointycastle/lib/ecc/curves/prime256v1.dart | 41 + pointycastle/lib/ecc/curves/secp112r1.dart | 34 + pointycastle/lib/ecc/curves/secp112r2.dart | 34 + pointycastle/lib/ecc/curves/secp128r1.dart | 34 + pointycastle/lib/ecc/curves/secp128r2.dart | 34 + pointycastle/lib/ecc/curves/secp160k1.dart | 33 + pointycastle/lib/ecc/curves/secp160r1.dart | 34 + pointycastle/lib/ecc/curves/secp160r2.dart | 34 + pointycastle/lib/ecc/curves/secp192k1.dart | 35 + pointycastle/lib/ecc/curves/secp192r1.dart | 38 + pointycastle/lib/ecc/curves/secp224k1.dart | 37 + pointycastle/lib/ecc/curves/secp224r1.dart | 42 + pointycastle/lib/ecc/curves/secp256k1.dart | 37 + pointycastle/lib/ecc/curves/secp256r1.dart | 41 + pointycastle/lib/ecc/curves/secp384r1.dart | 41 + pointycastle/lib/ecc/curves/secp521r1.dart | 41 + pointycastle/lib/ecc/ecc_base.dart | 280 + pointycastle/lib/ecc/ecc_fp.dart | 587 + pointycastle/lib/ecc/ecdh.dart | 70 + pointycastle/lib/export.dart | 154 + pointycastle/lib/impl.dart | 13 + pointycastle/lib/key_derivators/api.dart | 126 + pointycastle/lib/key_derivators/argon2.dart | 2 + .../argon2_native_int_impl.dart | 658 + .../argon2_register64_impl.dart | 695 + .../lib/key_derivators/concat_kdf.dart | 62 + pointycastle/lib/key_derivators/ecdh_kdf.dart | 37 + pointycastle/lib/key_derivators/hkdf.dart | 185 + pointycastle/lib/key_derivators/pbkdf2.dart | 102 + .../pkcs12_parameter_generator.dart | 148 + .../pkcs5s1_parameter_generator.dart | 75 + pointycastle/lib/key_derivators/scrypt.dart | 207 + pointycastle/lib/key_generators/api.dart | 27 + .../lib/key_generators/ec_key_generator.dart | 50 + .../lib/key_generators/rsa_key_generator.dart | 339 + .../lib/macs/cbc_block_cipher_mac.dart | 214 + pointycastle/lib/macs/cmac.dart | 287 + pointycastle/lib/macs/hmac.dart | 120 + pointycastle/lib/macs/poly1305.dart | 323 + .../padded_block_cipher_impl.dart | 121 + pointycastle/lib/paddings/iso7816d4.dart | 57 + pointycastle/lib/paddings/pkcs7.dart | 53 + pointycastle/lib/pointycastle.dart | 15 + .../random/auto_seed_block_ctr_random.dart | 105 + pointycastle/lib/random/block_ctr_random.dart | 69 + pointycastle/lib/random/fortuna_random.dart | 59 + pointycastle/lib/signers/ecdsa_signer.dart | 402 + pointycastle/lib/signers/pss_signer.dart | 269 + pointycastle/lib/signers/rsa_signer.dart | 197 + .../lib/src/api/aead_block_cipher.dart | 26 + pointycastle/lib/src/api/aead_cipher.dart | 30 + pointycastle/lib/src/api/aead_parameters.dart | 17 + pointycastle/lib/src/api/algorithm.dart | 9 + .../lib/src/api/asymmetric_block_cipher.dart | 35 + pointycastle/lib/src/api/asymmetric_key.dart | 6 + .../lib/src/api/asymmetric_key_pair.dart | 22 + .../lib/src/api/asymmetric_key_parameter.dart | 11 + pointycastle/lib/src/api/block_cipher.dart | 39 + .../lib/src/api/cipher_parameters.dart | 6 + pointycastle/lib/src/api/des_parameters.dart | 7 + .../lib/src/api/desede_parameters.dart | 7 + pointycastle/lib/src/api/digest.dart | 34 + pointycastle/lib/src/api/key_derivator.dart | 25 + pointycastle/lib/src/api/key_generator.dart | 19 + .../lib/src/api/key_generator_parameters.dart | 10 + pointycastle/lib/src/api/key_parameter.dart | 15 + pointycastle/lib/src/api/mac.dart | 35 + .../lib/src/api/padded_block_cipher.dart | 48 + .../api/padded_block_cipher_parameters.dart | 16 + pointycastle/lib/src/api/padding.dart | 32 + .../lib/src/api/parameters_with_iv.dart | 13 + .../lib/src/api/parameters_with_random.dart | 14 + .../lib/src/api/parameters_with_salt.dart | 13 + .../parameters_with_salt_configuration.dart | 15 + .../lib/src/api/pbe_parameters_generator.dart | 23 + pointycastle/lib/src/api/private_key.dart | 6 + .../lib/src/api/private_key_parameter.dart | 9 + pointycastle/lib/src/api/public_key.dart | 6 + .../lib/src/api/public_key_parameter.dart | 9 + pointycastle/lib/src/api/rc2_parameters.dart | 13 + .../src/api/registry_factory_exception.dart | 24 + pointycastle/lib/src/api/secure_random.dart | 34 + pointycastle/lib/src/api/signature.dart | 6 + pointycastle/lib/src/api/signer.dart | 25 + pointycastle/lib/src/api/srp_client.dart | 35 + pointycastle/lib/src/api/srp_server.dart | 37 + pointycastle/lib/src/api/stream_cipher.dart | 32 + pointycastle/lib/src/api/xof.dart | 11 + pointycastle/lib/src/ct.dart | 16 + .../src/ec_standard_curve_constructor.dart | 20 + .../lib/src/impl/base_aead_block_cipher.dart | 223 + .../lib/src/impl/base_aead_cipher.dart | 11 + .../impl/base_asymmetric_block_cipher.dart | 15 + .../lib/src/impl/base_block_cipher.dart | 15 + pointycastle/lib/src/impl/base_digest.dart | 16 + .../lib/src/impl/base_key_derivator.dart | 15 + pointycastle/lib/src/impl/base_mac.dart | 16 + pointycastle/lib/src/impl/base_padding.dart | 19 + .../lib/src/impl/base_stream_cipher.dart | 15 + pointycastle/lib/src/impl/entropy.dart | 7 + pointycastle/lib/src/impl/keccak_engine.dart | 396 + .../lib/src/impl/long_sha2_family_digest.dart | 443 + .../lib/src/impl/md4_family_digest.dart | 190 + .../lib/src/impl/secure_random_base.dart | 60 + .../lib/src/platform_check/abstract.dart | 36 + .../lib/src/platform_check/native.dart | 45 + .../lib/src/platform_check/node_crypto.dart | 17 + .../src/platform_check/platform_check.dart | 37 + pointycastle/lib/src/platform_check/web.dart | 65 + pointycastle/lib/src/registration.dart | 44 + .../lib/src/registry/registration.dart | 171 + pointycastle/lib/src/registry/registry.dart | 165 + pointycastle/lib/src/ufixnum.dart | 562 + pointycastle/lib/src/utils.dart | 336 + pointycastle/lib/srp/srp6_client.dart | 104 + pointycastle/lib/srp/srp6_server.dart | 101 + .../lib/srp/srp6_standard_groups.dart | 176 + pointycastle/lib/srp/srp6_util.dart | 167 + .../lib/srp/srp6_verifier_generator.dart | 32 + pointycastle/lib/stream/chacha20.dart | 314 + pointycastle/lib/stream/chacha20poly1305.dart | 503 + pointycastle/lib/stream/chacha7539.dart | 315 + pointycastle/lib/stream/ctr.dart | 23 + pointycastle/lib/stream/eax.dart | 311 + pointycastle/lib/stream/rc4_engine.dart | 114 + pointycastle/lib/stream/salsa20.dart | 195 + pointycastle/lib/stream/sic.dart | 99 + pointycastle/pubspec.yaml | 21 + .../stream_cipher_as_block_cipher_test.dart | 22 + .../test/asn1/asn1_all_test-disabled.dart | 40 + pointycastle/test/asn1/asn1_dump_test.dart | 153 + pointycastle/test/asn1/asn1_object_test.dart | 101 + pointycastle/test/asn1/asn1_parser_test.dart | 336 + pointycastle/test/asn1/asn1_utils_test.dart | 155 + .../asn1/primitives/asn1_bit_string_test.dart | 245 + .../asn1/primitives/asn1_bmp_string_test.dart | 421 + .../asn1/primitives/asn1_boolean_test.dart | 36 + .../asn1/primitives/asn1_enumerated_test.dart | 37 + .../asn1_generalized_time_test.dart | 109 + .../asn1/primitives/asn1_ia5_string_test.dart | 449 + .../asn1/primitives/asn1_integer_test.dart | 113 + .../test/asn1/primitives/asn1_null_test.dart | 60 + .../asn1_object_identifier_test.dart | 79 + .../primitives/asn1_octet_string_test.dart | 269 + .../asn1_printable_string_test.dart | 286 + .../asn1/primitives/asn1_sequence_test.dart | 253 + .../test/asn1/primitives/asn1_set_test.dart | 103 + .../primitives/asn1_teletext_string_test.dart | 239 + .../asn1/primitives/asn1_utc_time_test.dart | 101 + .../primitives/asn1_utf8_string_test.dart | 312 + .../test/asymmetric/ec_elgamal_test.dart | 80 + pointycastle/test/asymmetric/oaep_test.dart | 1005 + pointycastle/test/asymmetric/pkcs1_test.dart | 30 + pointycastle/test/asymmetric/rsa_test.dart | 62 + pointycastle/test/block/aes_fast_test.dart | 73 + pointycastle/test/block/aes_test.dart | 229 + pointycastle/test/block/blowfish_test.dart | 29 + pointycastle/test/block/camellia_test.dart | 40 + .../test/block/desede_engine_test.dart | 45 + pointycastle/test/block/rc2_engine_test.dart | 104 + pointycastle/test/block/twofish_test.dart | 36 + pointycastle/test/digests/blake2b_test.dart | 73 + pointycastle/test/digests/cshake_test.dart | 240 + pointycastle/test/digests/keccak_test.dart | 356 + pointycastle/test/digests/md2_test.dart | 14 + pointycastle/test/digests/md4_test.dart | 14 + pointycastle/test/digests/md5_test.dart | 14 + pointycastle/test/digests/ripemd128_test.dart | 14 + pointycastle/test/digests/ripemd160_test.dart | 20 + pointycastle/test/digests/ripemd256_test.dart | 14 + pointycastle/test/digests/ripemd320_test.dart | 14 + pointycastle/test/digests/sha1_test.dart | 16 + pointycastle/test/digests/sha224_test.dart | 14 + pointycastle/test/digests/sha256_test.dart | 16 + pointycastle/test/digests/sha384_test.dart | 16 + pointycastle/test/digests/sha3_test.dart | 182 + pointycastle/test/digests/sha512_test.dart | 16 + pointycastle/test/digests/sha512t_test.dart | 32 + pointycastle/test/digests/shake_test.dart | 130 + pointycastle/test/digests/sm3_test.dart | 54 + pointycastle/test/digests/tiger_test.dart | 14 + pointycastle/test/digests/whirlpool_test.dart | 14 + pointycastle/test/ecc/curves_test.dart | 54 + pointycastle/test/ecc/ecdh_test.dart | 338 + pointycastle/test/impl_test.dart | 168 + .../key_derivators/argon2_nonvm_test.dart | 66 + .../test/key_derivators/argon2_vm_test.dart | 142 + .../key_derivators/concatkdf_nonvm_test.dart | 8415 ++ .../test/key_derivators/concatkdf_test.dart | 269 + .../test/key_derivators/hkdf_test.dart | 247 + .../test/key_derivators/pbkdf2_test.dart | 21 + .../pkcs12_parameter_generator_test.dart | 97 + .../key_derivators/scrypt_nonvm_test.dart | 29 + .../test/key_derivators/scrypt_vm_test.dart | 36 + .../key_generators/ec_key_generator_test.dart | 42 + .../rsa_key_generator_test.dart | 254 + .../test/macs/cbc_block_cipher_mac_test.dart | 31 + pointycastle/test/macs/cmac_test.dart | 53 + pointycastle/test/macs/hmac_test.dart | 222 + pointycastle/test/macs/poly1305_test.dart | 80 + pointycastle/test/macs/poly1305_web_test.dart | 22 + pointycastle/test/modes/cbc_test.dart | 40 + pointycastle/test/modes/ccm_test.dart | 71 + pointycastle/test/modes/cfb_test.dart | 40 + pointycastle/test/modes/ecb_test.dart | 40 + pointycastle/test/modes/gcm_test.dart | 297 + pointycastle/test/modes/gctr_test.dart | 40 + pointycastle/test/modes/ige_test.dart | 36 + pointycastle/test/modes/ofb_test.dart | 40 + pointycastle/test/modes/sic_test.dart | 55 + .../test/paddings/iso7816d4_test.dart | 13 + .../paddings/padded_block_cipher_test.dart | 112 + pointycastle/test/paddings/pkcs7_test.dart | 15 + .../test/platform/platform_native_test.dart | 15 + .../test/platform/platform_web_test.dart | 16 + .../auto_seed_block_ctr_random_test.dart | 65 + .../test/random/block_ctr_random_test.dart | 4138 + pointycastle/test/random/fixed_rng_test.dart | 33 + .../test/random/fortuna_random_test.dart | 64 + .../test/signers/ecdsa_signer_test.dart | 71 + pointycastle/test/signers/ecdsa_vec.dart | 4147 + .../test/signers/ecdsa_vector_vm_test.dart | 192 + .../test/signers/pss_signer_test.dart | 243 + .../test/signers/rsa_signer_test.dart | 49 + pointycastle/test/src/ct_nonvm_test.dart | 65 + pointycastle/test/src/ct_test.dart | 66 + pointycastle/test/src/ufixnum_test.dart | 786 + pointycastle/test/src/utils_test.dart | 82 + pointycastle/test/srp/srp_test.dart | 298 + pointycastle/test/stream/chacha20_test.dart | 156 + .../test/stream/chacha20poly1305_test.dart | 90 + pointycastle/test/stream/eax_test.dart | 313 + pointycastle/test/stream/rc4_engine_test.dart | 34 + pointycastle/test/stream/salsa20_test.dart | 39 + .../test/runners/asymmetric_block_cipher.dart | 78 + .../test/test/runners/block_cipher.dart | 94 + pointycastle/test/test/runners/digest.dart | 43 + .../test/test/runners/key_derivators.dart | 35 + .../test/test/runners/key_generators.dart | 24 + pointycastle/test/test/runners/mac.dart | 91 + pointycastle/test/test/runners/padding.dart | 33 + pointycastle/test/test/runners/registry.dart | 92 + pointycastle/test/test/runners/signer.dart | 114 + .../test/test/runners/stream_cipher.dart | 80 + .../test/test/src/fixed_secure_random.dart | 58 + pointycastle/test/test/src/helpers.dart | 158 + .../src/null_asymmetric_block_cipher.dart | 49 + .../test/test/src/null_block_cipher.dart | 37 + pointycastle/test/test/src/null_digest.dart | 36 + .../test/test/src/null_secure_random.dart | 20 + .../test/test/src/null_stream_cipher.dart | 30 + .../test/test_resources/kdf-56c/KDA.req.json | 72385 ++++++++++++++++ .../test/test_resources/kdf-56c/KDA.rsp.json | 23010 +++++ pubspec.yaml | 30 + qr_dart/LICENSE | 26 + qr_dart/lib/qr.dart | 5 + qr_dart/lib/src/bit_buffer.dart | 46 + qr_dart/lib/src/byte.dart | 140 + qr_dart/lib/src/error_correct_level.dart | 20 + qr_dart/lib/src/input_too_long_exception.dart | 20 + qr_dart/lib/src/mask_pattern.dart | 8 + qr_dart/lib/src/math.dart | 27 + qr_dart/lib/src/mode.dart | 4 + qr_dart/lib/src/polynomial.dart | 63 + qr_dart/lib/src/qr_code.dart | 288 + qr_dart/lib/src/qr_image.dart | 345 + qr_dart/lib/src/readme.md | 27 + qr_dart/lib/src/rs_block.dart | 287 + qr_dart/lib/src/util.dart | 85 + qr_dart/pubspec.yaml | 20 + qr_dart/test/qr_alphanumeric_test.dart | 89 + qr_dart/test/qr_bit_buffer_test.dart | 75 + qr_dart/test/qr_byte_test.dart | 21 + qr_dart/test/qr_code_test.dart | 194 + qr_dart/test/qr_code_test_data.dart | 16248 ++++ qr_dart/test/qr_code_test_data_with_mask.dart | 194 + qr_dart/test/qr_numeric_test.dart | 115 + update.py | 157 + x25519/LICENSE | 201 + x25519/lib/src/curve25519.dart | 944 + x25519/lib/src/numbers.dart | 11 + x25519/lib/x25519.dart | 180 + x25519/pubspec.yaml | 17 + .../test/benchmark/curve25519_benchmark.dart | 35 + x25519/test/benchmark/rate_benchmark.dart | 42 + x25519/test/curve25519_test.dart | 59 + x25519/test/vectors_test.dart | 1894 + 1560 files changed, 309395 insertions(+) create mode 100644 .gitignore create mode 100644 adaptive_number/LICENSE create mode 100644 adaptive_number/lib/adaptive_number.dart create mode 100644 adaptive_number/lib/src/int.dart create mode 100644 adaptive_number/lib/src/int64.dart create mode 100644 adaptive_number/lib/src/number.dart create mode 100644 adaptive_number/lib/src/stub.dart create mode 100644 adaptive_number/pubspec.yaml create mode 100644 adaptive_number/test/adaptive_number_test.dart create mode 100644 config.lock.yaml create mode 100644 config.yaml create mode 100644 dots_indicator/LICENSE create mode 100644 dots_indicator/lib/dots_indicator.dart create mode 100644 dots_indicator/lib/src/dots_decorator.dart create mode 100644 dots_indicator/lib/src/dots_indicator.dart create mode 100644 dots_indicator/pubspec.yaml create mode 100644 ed25519_edwards/LICENSE create mode 100644 ed25519_edwards/lib/ed25519_edwards.dart create mode 100644 ed25519_edwards/lib/src/const.dart create mode 100644 ed25519_edwards/lib/src/edwards25519.dart create mode 100644 ed25519_edwards/lib/src/numbers.dart create mode 100644 ed25519_edwards/lib/src/util.dart create mode 100644 ed25519_edwards/pubspec.yaml create mode 100644 ed25519_edwards/test/benchmark/ed25519_benchmark.dart create mode 100644 ed25519_edwards/test/benchmark/rate_benchmark.dart create mode 100644 ed25519_edwards/test/ed25519_test.dart create mode 100644 hashlib/LICENSE create mode 100644 hashlib/lib/codecs.dart create mode 100644 hashlib/lib/hashlib.dart create mode 100644 hashlib/lib/random.dart create mode 100644 hashlib/lib/src/adler32.dart create mode 100644 hashlib/lib/src/algorithms/adler32.dart create mode 100644 hashlib/lib/src/algorithms/argon2/argon2.dart create mode 100644 hashlib/lib/src/algorithms/argon2/argon2_32bit.dart create mode 100644 hashlib/lib/src/algorithms/argon2/argon2_64bit.dart create mode 100644 hashlib/lib/src/algorithms/argon2/common.dart create mode 100644 hashlib/lib/src/algorithms/argon2/security.dart create mode 100644 hashlib/lib/src/algorithms/bcrypt/bcrypt.dart create mode 100644 hashlib/lib/src/algorithms/bcrypt/common.dart create mode 100644 hashlib/lib/src/algorithms/bcrypt/security.dart create mode 100644 hashlib/lib/src/algorithms/blake2/blake2b.dart create mode 100644 hashlib/lib/src/algorithms/blake2/blake2b_32bit.dart create mode 100644 hashlib/lib/src/algorithms/blake2/blake2b_64bit.dart create mode 100644 hashlib/lib/src/algorithms/blake2/blake2s.dart create mode 100644 hashlib/lib/src/algorithms/crc/crc16.dart create mode 100644 hashlib/lib/src/algorithms/crc/crc32.dart create mode 100644 hashlib/lib/src/algorithms/crc/crc64.dart create mode 100644 hashlib/lib/src/algorithms/hmac.dart create mode 100644 hashlib/lib/src/algorithms/keccak/keccak.dart create mode 100644 hashlib/lib/src/algorithms/keccak/keccak_32bit.dart create mode 100644 hashlib/lib/src/algorithms/keccak/keccak_64bit.dart create mode 100644 hashlib/lib/src/algorithms/md2.dart create mode 100644 hashlib/lib/src/algorithms/md4.dart create mode 100644 hashlib/lib/src/algorithms/md5.dart create mode 100644 hashlib/lib/src/algorithms/pbkdf2/pbkdf2.dart create mode 100644 hashlib/lib/src/algorithms/pbkdf2/security.dart create mode 100644 hashlib/lib/src/algorithms/poly1305/poly1305_32bit.dart create mode 100644 hashlib/lib/src/algorithms/poly1305/poly1305_64bit.dart create mode 100644 hashlib/lib/src/algorithms/poly1305/poly1305_sink.dart create mode 100644 hashlib/lib/src/algorithms/ripemd/ripemd128.dart create mode 100644 hashlib/lib/src/algorithms/ripemd/ripemd160.dart create mode 100644 hashlib/lib/src/algorithms/ripemd/ripemd256.dart create mode 100644 hashlib/lib/src/algorithms/ripemd/ripemd320.dart create mode 100644 hashlib/lib/src/algorithms/scrypt/scrypt.dart create mode 100644 hashlib/lib/src/algorithms/scrypt/security.dart create mode 100644 hashlib/lib/src/algorithms/sha1.dart create mode 100644 hashlib/lib/src/algorithms/sha2/sha2.dart create mode 100644 hashlib/lib/src/algorithms/sha2/sha2_1024_32bit.dart create mode 100644 hashlib/lib/src/algorithms/sha2/sha2_1024_64bit.dart create mode 100644 hashlib/lib/src/algorithms/sha2/sha2_512.dart create mode 100644 hashlib/lib/src/algorithms/sha3.dart create mode 100644 hashlib/lib/src/algorithms/shake.dart create mode 100644 hashlib/lib/src/algorithms/sm3.dart create mode 100644 hashlib/lib/src/algorithms/xxh3/xxh3_128.dart create mode 100644 hashlib/lib/src/algorithms/xxh3/xxh3_128_32bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh3/xxh3_128_64bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh3/xxh3_64.dart create mode 100644 hashlib/lib/src/algorithms/xxh3/xxh3_64_32bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh3/xxh3_64_64bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh32/xxh32.dart create mode 100644 hashlib/lib/src/algorithms/xxh32/xxh32_32bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh32/xxh32_64bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh64/xxh64.dart create mode 100644 hashlib/lib/src/algorithms/xxh64/xxh64_32bit.dart create mode 100644 hashlib/lib/src/algorithms/xxh64/xxh64_64bit.dart create mode 100644 hashlib/lib/src/argon2.dart create mode 100644 hashlib/lib/src/bcrypt.dart create mode 100644 hashlib/lib/src/blake2b.dart create mode 100644 hashlib/lib/src/blake2s.dart create mode 100644 hashlib/lib/src/core/block_hash.dart create mode 100644 hashlib/lib/src/core/hash_base.dart create mode 100644 hashlib/lib/src/core/hash_base_io.dart create mode 100644 hashlib/lib/src/core/hash_base_stub.dart create mode 100644 hashlib/lib/src/core/hash_digest.dart create mode 100644 hashlib/lib/src/core/kdf_base.dart create mode 100644 hashlib/lib/src/core/mac_base.dart create mode 100644 hashlib/lib/src/core/otpauth.dart create mode 100644 hashlib/lib/src/core/registry.dart create mode 100644 hashlib/lib/src/crc16.dart create mode 100644 hashlib/lib/src/crc32.dart create mode 100644 hashlib/lib/src/crc64.dart create mode 100644 hashlib/lib/src/hashlib.dart create mode 100644 hashlib/lib/src/hmac.dart create mode 100644 hashlib/lib/src/hotp.dart create mode 100644 hashlib/lib/src/keccak224.dart create mode 100644 hashlib/lib/src/keccak256.dart create mode 100644 hashlib/lib/src/keccak384.dart create mode 100644 hashlib/lib/src/keccak512.dart create mode 100644 hashlib/lib/src/md2.dart create mode 100644 hashlib/lib/src/md4.dart create mode 100644 hashlib/lib/src/md5.dart create mode 100644 hashlib/lib/src/pbkdf2.dart create mode 100644 hashlib/lib/src/poly1305.dart create mode 100644 hashlib/lib/src/random.dart create mode 100644 hashlib/lib/src/random/generator_js.dart create mode 100644 hashlib/lib/src/random/generator_vm.dart create mode 100644 hashlib/lib/src/random/generators.dart create mode 100644 hashlib/lib/src/random/random.dart create mode 100644 hashlib/lib/src/random/uuid_v1.dart create mode 100644 hashlib/lib/src/random/uuid_v3.dart create mode 100644 hashlib/lib/src/random/uuid_v4.dart create mode 100644 hashlib/lib/src/random/uuid_v5.dart create mode 100644 hashlib/lib/src/random/uuid_v6.dart create mode 100644 hashlib/lib/src/random/uuid_v7.dart create mode 100644 hashlib/lib/src/random/uuid_v8.dart create mode 100644 hashlib/lib/src/ripemd128.dart create mode 100644 hashlib/lib/src/ripemd160.dart create mode 100644 hashlib/lib/src/ripemd256.dart create mode 100644 hashlib/lib/src/ripemd320.dart create mode 100644 hashlib/lib/src/scrypt.dart create mode 100644 hashlib/lib/src/sha1.dart create mode 100644 hashlib/lib/src/sha224.dart create mode 100644 hashlib/lib/src/sha256.dart create mode 100644 hashlib/lib/src/sha384.dart create mode 100644 hashlib/lib/src/sha3_224.dart create mode 100644 hashlib/lib/src/sha3_256.dart create mode 100644 hashlib/lib/src/sha3_384.dart create mode 100644 hashlib/lib/src/sha3_512.dart create mode 100644 hashlib/lib/src/sha512.dart create mode 100644 hashlib/lib/src/sha512t.dart create mode 100644 hashlib/lib/src/shake128.dart create mode 100644 hashlib/lib/src/shake256.dart create mode 100644 hashlib/lib/src/sm3.dart create mode 100644 hashlib/lib/src/totp.dart create mode 100644 hashlib/lib/src/uuid.dart create mode 100644 hashlib/lib/src/xxh128.dart create mode 100644 hashlib/lib/src/xxh3.dart create mode 100644 hashlib/lib/src/xxh32.dart create mode 100644 hashlib/lib/src/xxh64.dart create mode 100644 hashlib/pubspec.yaml create mode 100644 hashlib/test/adler32_test.dart create mode 100644 hashlib/test/argon2_test.dart create mode 100644 hashlib/test/bcrypt_test.dart create mode 100644 hashlib/test/blake2b_test.dart create mode 100644 hashlib/test/blake2s_test.dart create mode 100644 hashlib/test/compare_test.dart create mode 100644 hashlib/test/core/block_hash_test.dart create mode 100644 hashlib/test/core/hash_base_file_test.dart create mode 100644 hashlib/test/core/hash_digest_test.dart create mode 100644 hashlib/test/core/hash_sink_test.dart create mode 100644 hashlib/test/core/kdf_base_test.dart create mode 100644 hashlib/test/core/mac_base_test.dart create mode 100644 hashlib/test/crc16_test.dart create mode 100644 hashlib/test/crc32_test.dart create mode 100644 hashlib/test/crc64_test.dart create mode 100644 hashlib/test/fixures/long.txt create mode 100644 hashlib/test/fixures/xxh32.csv create mode 100644 hashlib/test/fixures/xxh3_128.csv create mode 100644 hashlib/test/fixures/xxh3_64.csv create mode 100644 hashlib/test/fixures/xxh64.csv create mode 100644 hashlib/test/hmac_test.dart create mode 100644 hashlib/test/keccak_test.dart create mode 100644 hashlib/test/md2_test.dart create mode 100644 hashlib/test/md4_test.dart create mode 100644 hashlib/test/md5_test.dart create mode 100644 hashlib/test/pbkdf2_test.dart create mode 100644 hashlib/test/poly1305_test.dart create mode 100644 hashlib/test/random/random_test.dart create mode 100644 hashlib/test/random/uuid_test.dart create mode 100644 hashlib/test/registry_test.dart create mode 100644 hashlib/test/ripemd128_test.dart create mode 100644 hashlib/test/ripemd160_test.dart create mode 100644 hashlib/test/ripemd256_test.dart create mode 100644 hashlib/test/ripemd320_test.dart create mode 100644 hashlib/test/scrypt_test.dart create mode 100644 hashlib/test/sha1_test.dart create mode 100644 hashlib/test/sha224_test.dart create mode 100644 hashlib/test/sha256_test.dart create mode 100644 hashlib/test/sha384_test.dart create mode 100644 hashlib/test/sha3_test.dart create mode 100644 hashlib/test/sha512_224_test.dart create mode 100644 hashlib/test/sha512_256_test.dart create mode 100644 hashlib/test/sha512_test.dart create mode 100644 hashlib/test/shake_test.dart create mode 100644 hashlib/test/sm3_test.dart create mode 100644 hashlib/test/totp_test.dart create mode 100644 hashlib/test/xxh128_test.dart create mode 100644 hashlib/test/xxh32_test.dart create mode 100644 hashlib/test/xxh3_test.dart create mode 100644 hashlib/test/xxh64_test.dart create mode 100644 hashlib/test/xxh_test.dart create mode 100644 hashlib_codecs/LICENSE create mode 100644 hashlib_codecs/lib/hashlib_codecs.dart create mode 100644 hashlib_codecs/lib/src/base16.dart create mode 100644 hashlib_codecs/lib/src/base2.dart create mode 100644 hashlib_codecs/lib/src/base32.dart create mode 100644 hashlib_codecs/lib/src/base64.dart create mode 100644 hashlib_codecs/lib/src/base8.dart create mode 100644 hashlib_codecs/lib/src/bigint.dart create mode 100644 hashlib_codecs/lib/src/codecs/base16.dart create mode 100644 hashlib_codecs/lib/src/codecs/base2.dart create mode 100644 hashlib_codecs/lib/src/codecs/base32.dart create mode 100644 hashlib_codecs/lib/src/codecs/base64.dart create mode 100644 hashlib_codecs/lib/src/codecs/base8.dart create mode 100644 hashlib_codecs/lib/src/codecs/bigint.dart create mode 100644 hashlib_codecs/lib/src/codecs/crypt/crypt.dart create mode 100644 hashlib_codecs/lib/src/codecs/crypt/crypt_builder.dart create mode 100644 hashlib_codecs/lib/src/codecs/crypt/crypt_codec.dart create mode 100644 hashlib_codecs/lib/src/codecs/crypt/crypt_data.dart create mode 100644 hashlib_codecs/lib/src/codecs/utf8.dart create mode 100644 hashlib_codecs/lib/src/codecs_base.dart create mode 100644 hashlib_codecs/lib/src/core/alphabet.dart create mode 100644 hashlib_codecs/lib/src/core/byte.dart create mode 100644 hashlib_codecs/lib/src/core/codec.dart create mode 100644 hashlib_codecs/lib/src/core/decoder.dart create mode 100644 hashlib_codecs/lib/src/core/encoder.dart create mode 100644 hashlib_codecs/lib/src/crypt.dart create mode 100644 hashlib_codecs/lib/src/utf8.dart create mode 100644 hashlib_codecs/pubspec.yaml create mode 100644 hashlib_codecs/test/base16_test.dart create mode 100644 hashlib_codecs/test/base2_test.dart create mode 100644 hashlib_codecs/test/base32_test.dart create mode 100644 hashlib_codecs/test/base64_test.dart create mode 100644 hashlib_codecs/test/base64url_test.dart create mode 100644 hashlib_codecs/test/base8_test.dart create mode 100644 hashlib_codecs/test/bigint_test.dart create mode 100644 hashlib_codecs/test/core/alphabet_test.dart create mode 100644 hashlib_codecs/test/core/byte_test.dart create mode 100644 hashlib_codecs/test/core/codec_test.dart create mode 100644 hashlib_codecs/test/core/decoder_test.dart create mode 100644 hashlib_codecs/test/core/encoder_test.dart create mode 100644 hashlib_codecs/test/crypt/crypt_builder_test.dart create mode 100644 hashlib_codecs/test/crypt/crypt_test.dart create mode 100644 hashlib_codecs/test/crypt_test.dart create mode 100644 hashlib_codecs/test/utf8_test.dart create mode 100644 hashlib_codecs/test/utils.dart create mode 100644 introduction_screen/LICENSE create mode 100644 introduction_screen/lib/introduction_screen.dart create mode 100644 introduction_screen/lib/src/helper.dart create mode 100644 introduction_screen/lib/src/introduction_screen.dart create mode 100644 introduction_screen/lib/src/model/page_decoration.dart create mode 100644 introduction_screen/lib/src/model/page_view_model.dart create mode 100644 introduction_screen/lib/src/model/position.dart create mode 100644 introduction_screen/lib/src/ui/footer_content.dart create mode 100644 introduction_screen/lib/src/ui/intro_button.dart create mode 100644 introduction_screen/lib/src/ui/intro_content.dart create mode 100644 introduction_screen/lib/src/ui/intro_page.dart create mode 100644 introduction_screen/lib/testable_widget.dart create mode 100644 introduction_screen/pubspec.yaml create mode 100644 introduction_screen/test/src/helper_test.dart create mode 100644 introduction_screen/test/src/introduction_screen_test.dart create mode 100644 introduction_screen/test/src/model/page_decoration_test.dart create mode 100644 introduction_screen/test/src/model/position_test.dart create mode 100644 introduction_screen/test/widget/intro_ui_test.dart create mode 100644 libsignal_protocol_dart/LICENSE create mode 100644 libsignal_protocol_dart/lib/libsignal_protocol_dart.dart create mode 100644 libsignal_protocol_dart/lib/src/cbc.dart create mode 100644 libsignal_protocol_dart/lib/src/decryption_callback.dart create mode 100644 libsignal_protocol_dart/lib/src/devices/device_consistency_code_generator.dart create mode 100644 libsignal_protocol_dart/lib/src/devices/device_consistency_commitment.dart create mode 100644 libsignal_protocol_dart/lib/src/devices/device_consistency_signature.dart create mode 100644 libsignal_protocol_dart/lib/src/duplicate_message_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/curve.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/djb_ec_private_key.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/djb_ec_public_key.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/ec_key_pair.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/ec_private_key.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/ec_public_key.dart create mode 100644 libsignal_protocol_dart/lib/src/ecc/ed25519.dart create mode 100644 libsignal_protocol_dart/lib/src/entry.dart create mode 100644 libsignal_protocol_dart/lib/src/eq.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/displayable_fingerprint.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/fingerprint.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/fingerprint_generator.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/fingerprint_parsing_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/fingerprint_version_mismatch_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart create mode 100644 libsignal_protocol_dart/lib/src/fingerprint/scannable_fingerprint.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/group_cipher.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/group_session_builder.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/ratchet/sender_chain_key.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/ratchet/sender_message_key.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/sender_key_name.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/state/in_memory_sender_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/state/sender_key_record.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/state/sender_key_state.dart create mode 100644 libsignal_protocol_dart/lib/src/groups/state/sender_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/identity_key.dart create mode 100644 libsignal_protocol_dart/lib/src/identity_key_pair.dart create mode 100644 libsignal_protocol_dart/lib/src/invalid_key_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/invalid_key_id_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/invalid_mac_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/invalid_message_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/kdf/derived_message_secrets.dart create mode 100644 libsignal_protocol_dart/lib/src/kdf/derived_root_secrets.dart create mode 100644 libsignal_protocol_dart/lib/src/kdf/hkdf.dart create mode 100644 libsignal_protocol_dart/lib/src/kdf/hkdfv2.dart create mode 100644 libsignal_protocol_dart/lib/src/kdf/hkdfv3.dart create mode 100644 libsignal_protocol_dart/lib/src/legacy_message_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/no_session_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/protocol/ciphertext_message.dart create mode 100644 libsignal_protocol_dart/lib/src/protocol/device_consistency_message.dart create mode 100644 libsignal_protocol_dart/lib/src/protocol/pre_key_signal_message.dart create mode 100644 libsignal_protocol_dart/lib/src/protocol/sender_key_distribution_message_wrapper.dart create mode 100644 libsignal_protocol_dart/lib/src/protocol/sender_key_message.dart create mode 100644 libsignal_protocol_dart/lib/src/protocol/signal_message.dart create mode 100644 libsignal_protocol_dart/lib/src/provisioning_cipher.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/alice_signal_protocol_parameters.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/bob_signal_protocol_parameters.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/chain_key.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/message_keys.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/ratcheting_session.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/root_key.dart create mode 100644 libsignal_protocol_dart/lib/src/ratchet/symmetric_signal_protocol_parameters.dart create mode 100644 libsignal_protocol_dart/lib/src/session_builder.dart create mode 100644 libsignal_protocol_dart/lib/src/session_cipher.dart create mode 100644 libsignal_protocol_dart/lib/src/signal_protocol_address.dart create mode 100644 libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart create mode 100644 libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbenum.dart create mode 100644 libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbjson.dart create mode 100644 libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbserver.dart create mode 100644 libsignal_protocol_dart/lib/src/state/identity_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/impl/in_memory_identity_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/impl/in_memory_pre_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/impl/in_memory_session_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/impl/in_memory_signal_protocol_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/impl/in_memory_signed_pre_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart create mode 100644 libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbenum.dart create mode 100644 libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbjson.dart create mode 100644 libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbserver.dart create mode 100644 libsignal_protocol_dart/lib/src/state/pre_key_bundle.dart create mode 100644 libsignal_protocol_dart/lib/src/state/pre_key_record.dart create mode 100644 libsignal_protocol_dart/lib/src/state/pre_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/session_record.dart create mode 100644 libsignal_protocol_dart/lib/src/state/session_state.dart create mode 100644 libsignal_protocol_dart/lib/src/state/session_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/signal_protocol_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/signed_pre_key_record.dart create mode 100644 libsignal_protocol_dart/lib/src/state/signed_pre_key_store.dart create mode 100644 libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart create mode 100644 libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbenum.dart create mode 100644 libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbjson.dart create mode 100644 libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbserver.dart create mode 100644 libsignal_protocol_dart/lib/src/untrusted_identity_exception.dart create mode 100644 libsignal_protocol_dart/lib/src/util/byte_util.dart create mode 100644 libsignal_protocol_dart/lib/src/util/identity_key_comparator.dart create mode 100644 libsignal_protocol_dart/lib/src/util/key_helper.dart create mode 100644 libsignal_protocol_dart/lib/src/util/log.dart create mode 100644 libsignal_protocol_dart/lib/src/util/medium.dart create mode 100644 libsignal_protocol_dart/pubspec.yaml create mode 100644 libsignal_protocol_dart/test/devices/device_consistency_test.dart create mode 100644 libsignal_protocol_dart/test/ecc/curve25519_test.dart create mode 100644 libsignal_protocol_dart/test/fingerprint/numeric_fingerprint_generator_test.dart create mode 100644 libsignal_protocol_dart/test/groups/group_cipher_test.dart create mode 100644 libsignal_protocol_dart/test/kdf/hkdf_test.dart create mode 100644 libsignal_protocol_dart/test/provisioning_cipher_test.dart create mode 100644 libsignal_protocol_dart/test/ratchet/chain_key_test.dart create mode 100644 libsignal_protocol_dart/test/ratchet/ratcheting_session_test.dart create mode 100644 libsignal_protocol_dart/test/ratchet/root_key_test.dart create mode 100644 libsignal_protocol_dart/test/session_builder_test.dart create mode 100644 libsignal_protocol_dart/test/session_cipher_test.dart create mode 100644 libsignal_protocol_dart/test/state/impl/in_memory_identity_key_store_test.dart create mode 100644 libsignal_protocol_dart/test/state/impl/in_memory_pre_key_store_test.dart create mode 100644 libsignal_protocol_dart/test/state/impl/in_memory_session_store_test.dart create mode 100644 libsignal_protocol_dart/test/state/impl/in_memory_signal_protocol_store_test.dart create mode 100644 libsignal_protocol_dart/test/state/impl/in_memory_signed_pre_key_store_test.dart create mode 100644 libsignal_protocol_dart/test/test_in_memory_identity_key_store.dart create mode 100644 libsignal_protocol_dart/test/test_in_memory_signal_protocol_store.dart create mode 100644 libsignal_protocol_dart/test/util/byte_util_test.dart create mode 100644 lottie/LICENSE create mode 100644 lottie/lib/lottie.dart create mode 100644 lottie/lib/src/animation/content/base_stroke_content.dart create mode 100644 lottie/lib/src/animation/content/compound_trim_path_content.dart create mode 100644 lottie/lib/src/animation/content/content.dart create mode 100644 lottie/lib/src/animation/content/content_group.dart create mode 100644 lottie/lib/src/animation/content/drawing_content.dart create mode 100644 lottie/lib/src/animation/content/ellipse_content.dart create mode 100644 lottie/lib/src/animation/content/fill_content.dart create mode 100644 lottie/lib/src/animation/content/gradient_fill_content.dart create mode 100644 lottie/lib/src/animation/content/gradient_stroke_content.dart create mode 100644 lottie/lib/src/animation/content/greedy_content.dart create mode 100644 lottie/lib/src/animation/content/key_path_element_content.dart create mode 100644 lottie/lib/src/animation/content/merge_paths_content.dart create mode 100644 lottie/lib/src/animation/content/modifier_content.dart create mode 100644 lottie/lib/src/animation/content/path_content.dart create mode 100644 lottie/lib/src/animation/content/polystar_content.dart create mode 100644 lottie/lib/src/animation/content/rectangle_content.dart create mode 100644 lottie/lib/src/animation/content/repeater_content.dart create mode 100644 lottie/lib/src/animation/content/rounded_corners_content.dart create mode 100644 lottie/lib/src/animation/content/shape_content.dart create mode 100644 lottie/lib/src/animation/content/shape_modifier_content.dart create mode 100644 lottie/lib/src/animation/content/stroke_content.dart create mode 100644 lottie/lib/src/animation/content/trim_path_content.dart create mode 100644 lottie/lib/src/animation/keyframe/base_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/color_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/double_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/drop_shadow_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/gradient_color_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/integer_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/mask_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/path_keyframe.dart create mode 100644 lottie/lib/src/animation/keyframe/path_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/point_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/shape_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/split_dimension_path_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/text_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/transform_keyframe_animation.dart create mode 100644 lottie/lib/src/animation/keyframe/value_callback_keyframe_animation.dart create mode 100644 lottie/lib/src/composition.dart create mode 100644 lottie/lib/src/frame_rate.dart create mode 100644 lottie/lib/src/l.dart create mode 100644 lottie/lib/src/lottie.dart create mode 100644 lottie/lib/src/lottie_builder.dart create mode 100644 lottie/lib/src/lottie_delegates.dart create mode 100644 lottie/lib/src/lottie_drawable.dart create mode 100644 lottie/lib/src/lottie_image_asset.dart create mode 100644 lottie/lib/src/lottie_property.dart create mode 100644 lottie/lib/src/model/animatable/animatable_color_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_double_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_gradient_color_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_integer_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_path_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_point_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_scale_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_shape_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_split_dimension_path_value.dart create mode 100644 lottie/lib/src/model/animatable/animatable_text_frame.dart create mode 100644 lottie/lib/src/model/animatable/animatable_text_properties.dart create mode 100644 lottie/lib/src/model/animatable/animatable_transform.dart create mode 100644 lottie/lib/src/model/animatable/animatable_value.dart create mode 100644 lottie/lib/src/model/animatable/base_animatable_value.dart create mode 100644 lottie/lib/src/model/content/blur_effect.dart create mode 100644 lottie/lib/src/model/content/circle_shape.dart create mode 100644 lottie/lib/src/model/content/content_model.dart create mode 100644 lottie/lib/src/model/content/drop_shadow_effect.dart create mode 100644 lottie/lib/src/model/content/gradient_color.dart create mode 100644 lottie/lib/src/model/content/gradient_fill.dart create mode 100644 lottie/lib/src/model/content/gradient_stroke.dart create mode 100644 lottie/lib/src/model/content/gradient_type.dart create mode 100644 lottie/lib/src/model/content/layer_blend.dart create mode 100644 lottie/lib/src/model/content/mask.dart create mode 100644 lottie/lib/src/model/content/merge_paths.dart create mode 100644 lottie/lib/src/model/content/polystar_shape.dart create mode 100644 lottie/lib/src/model/content/rectangle_shape.dart create mode 100644 lottie/lib/src/model/content/repeater.dart create mode 100644 lottie/lib/src/model/content/rounded_corners.dart create mode 100644 lottie/lib/src/model/content/shape_data.dart create mode 100644 lottie/lib/src/model/content/shape_fill.dart create mode 100644 lottie/lib/src/model/content/shape_group.dart create mode 100644 lottie/lib/src/model/content/shape_path.dart create mode 100644 lottie/lib/src/model/content/shape_stroke.dart create mode 100644 lottie/lib/src/model/content/shape_trim_path.dart create mode 100644 lottie/lib/src/model/cubic_curve_data.dart create mode 100644 lottie/lib/src/model/document_data.dart create mode 100644 lottie/lib/src/model/font.dart create mode 100644 lottie/lib/src/model/font_character.dart create mode 100644 lottie/lib/src/model/key_path.dart create mode 100644 lottie/lib/src/model/key_path_element.dart create mode 100644 lottie/lib/src/model/layer/base_layer.dart create mode 100644 lottie/lib/src/model/layer/composition_layer.dart create mode 100644 lottie/lib/src/model/layer/image_layer.dart create mode 100644 lottie/lib/src/model/layer/layer.dart create mode 100644 lottie/lib/src/model/layer/null_layer.dart create mode 100644 lottie/lib/src/model/layer/shape_layer.dart create mode 100644 lottie/lib/src/model/layer/solid_layer.dart create mode 100644 lottie/lib/src/model/layer/text_layer.dart create mode 100644 lottie/lib/src/model/marker.dart create mode 100644 lottie/lib/src/options.dart create mode 100644 lottie/lib/src/parser/animatable_path_value_parser.dart create mode 100644 lottie/lib/src/parser/animatable_text_properties_parser.dart create mode 100644 lottie/lib/src/parser/animatable_transform_parser.dart create mode 100644 lottie/lib/src/parser/animatable_value_parser.dart create mode 100644 lottie/lib/src/parser/blur_effect_parser.dart create mode 100644 lottie/lib/src/parser/circle_shape_parser.dart create mode 100644 lottie/lib/src/parser/color_parser.dart create mode 100644 lottie/lib/src/parser/content_model_parser.dart create mode 100644 lottie/lib/src/parser/document_data_parser.dart create mode 100644 lottie/lib/src/parser/drop_shadow_effect_parser.dart create mode 100644 lottie/lib/src/parser/float_parser.dart create mode 100644 lottie/lib/src/parser/font_character_parser.dart create mode 100644 lottie/lib/src/parser/font_parser.dart create mode 100644 lottie/lib/src/parser/gradient_color_parser.dart create mode 100644 lottie/lib/src/parser/gradient_fill_parser.dart create mode 100644 lottie/lib/src/parser/gradient_stroke_parser.dart create mode 100644 lottie/lib/src/parser/integer_parser.dart create mode 100644 lottie/lib/src/parser/json_utils.dart create mode 100644 lottie/lib/src/parser/keyframe_parser.dart create mode 100644 lottie/lib/src/parser/keyframes_parser.dart create mode 100644 lottie/lib/src/parser/layer_parser.dart create mode 100644 lottie/lib/src/parser/lottie_composition_parser.dart create mode 100644 lottie/lib/src/parser/mask_parser.dart create mode 100644 lottie/lib/src/parser/merge_paths_parser.dart create mode 100644 lottie/lib/src/parser/moshi/buffer.dart create mode 100644 lottie/lib/src/parser/moshi/charcode.dart create mode 100644 lottie/lib/src/parser/moshi/json_reader.dart create mode 100644 lottie/lib/src/parser/moshi/json_scope.dart create mode 100644 lottie/lib/src/parser/moshi/json_utf8_reader.dart create mode 100644 lottie/lib/src/parser/offset_parser.dart create mode 100644 lottie/lib/src/parser/path_keyframe_parser.dart create mode 100644 lottie/lib/src/parser/path_parser.dart create mode 100644 lottie/lib/src/parser/polysar_shape_parser.dart create mode 100644 lottie/lib/src/parser/rectangle_shape_parser.dart create mode 100644 lottie/lib/src/parser/repeat_parser.dart create mode 100644 lottie/lib/src/parser/rounded_corners_parser.dart create mode 100644 lottie/lib/src/parser/scale_xy_parser.dart create mode 100644 lottie/lib/src/parser/shape_data_parser.dart create mode 100644 lottie/lib/src/parser/shape_fill_parser.dart create mode 100644 lottie/lib/src/parser/shape_group_parser.dart create mode 100644 lottie/lib/src/parser/shape_path_parser.dart create mode 100644 lottie/lib/src/parser/shape_stroke_parser.dart create mode 100644 lottie/lib/src/parser/shape_trim_path_parser.dart create mode 100644 lottie/lib/src/parser/value_parser.dart create mode 100644 lottie/lib/src/performance_tracker.dart create mode 100644 lottie/lib/src/providers/asset_provider.dart create mode 100644 lottie/lib/src/providers/file_provider.dart create mode 100644 lottie/lib/src/providers/file_provider_io.dart create mode 100644 lottie/lib/src/providers/file_provider_no_io.dart create mode 100644 lottie/lib/src/providers/load_fonts.dart create mode 100644 lottie/lib/src/providers/load_image.dart create mode 100644 lottie/lib/src/providers/lottie_provider.dart create mode 100644 lottie/lib/src/providers/memory_provider.dart create mode 100644 lottie/lib/src/providers/network_provider.dart create mode 100644 lottie/lib/src/raw_lottie.dart create mode 100644 lottie/lib/src/render_cache.dart create mode 100644 lottie/lib/src/render_cache/key.dart create mode 100644 lottie/lib/src/render_cache/store.dart create mode 100644 lottie/lib/src/render_cache/store_drawing.dart create mode 100644 lottie/lib/src/render_cache/store_raster.dart create mode 100644 lottie/lib/src/render_lottie.dart create mode 100644 lottie/lib/src/utils.dart create mode 100644 lottie/lib/src/utils/characters.dart create mode 100644 lottie/lib/src/utils/collection.dart create mode 100644 lottie/lib/src/utils/dash_path.dart create mode 100644 lottie/lib/src/utils/gamma_evaluator.dart create mode 100644 lottie/lib/src/utils/mean_calculator.dart create mode 100644 lottie/lib/src/utils/misc.dart create mode 100644 lottie/lib/src/utils/pair.dart create mode 100644 lottie/lib/src/utils/path_interpolator.dart create mode 100644 lottie/lib/src/utils/utils.dart create mode 100644 lottie/lib/src/value/drop_shadow.dart create mode 100644 lottie/lib/src/value/keyframe.dart create mode 100644 lottie/lib/src/value/lottie_frame_info.dart create mode 100644 lottie/lib/src/value/lottie_relative_double_value_callback.dart create mode 100644 lottie/lib/src/value/lottie_relative_integer_value_callback.dart create mode 100644 lottie/lib/src/value/lottie_relative_point_value_callback.dart create mode 100644 lottie/lib/src/value/lottie_value_callback.dart create mode 100644 lottie/lib/src/value_delegate.dart create mode 100644 lottie/pubspec.yaml create mode 100644 lottie/test/characters_test.dart create mode 100644 lottie/test/compositions_test.dart create mode 100644 lottie/test/data/loading_indicator.json create mode 100644 lottie/test/data/static_lottie.json create mode 100644 lottie/test/data/warningShimmer.json create mode 100644 lottie/test/dotlottie.dart create mode 100644 lottie/test/dynamic_image_test.dart create mode 100644 lottie/test/dynamic_properties_test.dart create mode 100644 lottie/test/dynamic_test.dart create mode 100644 lottie/test/dynamic_text_properties_test.dart create mode 100644 lottie/test/dynamic_text_test.dart create mode 100644 lottie/test/fireworks_test.dart create mode 100644 lottie/test/flutter_test_config.dart create mode 100644 lottie/test/frame_rate_test.dart create mode 100644 lottie/test/gamma_evaluator_test.dart create mode 100644 lottie/test/golden/AndroidWave_0_0.png create mode 100644 lottie/test/golden/HamburgerArrow_0_0.png create mode 100644 lottie/test/golden/HamburgerArrow_0_5.png create mode 100644 lottie/test/golden/HamburgerArrow_1_0.png create mode 100644 lottie/test/golden/Logo/LogoSmall_0_5.png create mode 100644 lottie/test/golden/Mobilo/A_0_5.png create mode 100644 lottie/test/golden/Mobilo/B_0_5.png create mode 100644 lottie/test/golden/lottiefiles/atm_link_1_0.png create mode 100644 lottie/test/golden_test.dart create mode 100644 lottie/test/goldens/all/14595-thumbs-up.png create mode 100644 lottie/test/goldens/all/17297-fireworks.png create mode 100644 lottie/test/goldens/all/Logo/logosmall.png create mode 100644 lottie/test/goldens/all/Mobilo/a.png create mode 100644 lottie/test/goldens/all/Mobilo/apostrophe.png create mode 100644 lottie/test/goldens/all/Mobilo/b.png create mode 100644 lottie/test/goldens/all/Mobilo/blinkingcursor.png create mode 100644 lottie/test/goldens/all/Mobilo/c.png create mode 100644 lottie/test/goldens/all/Mobilo/colon.png create mode 100644 lottie/test/goldens/all/Mobilo/comma.png create mode 100644 lottie/test/goldens/all/Mobilo/d.png create mode 100644 lottie/test/goldens/all/Mobilo/e.png create mode 100644 lottie/test/goldens/all/Mobilo/f.png create mode 100644 lottie/test/goldens/all/Mobilo/g.png create mode 100644 lottie/test/goldens/all/Mobilo/h.png create mode 100644 lottie/test/goldens/all/Mobilo/i.png create mode 100644 lottie/test/goldens/all/Mobilo/j.png create mode 100644 lottie/test/goldens/all/Mobilo/k.png create mode 100644 lottie/test/goldens/all/Mobilo/l.png create mode 100644 lottie/test/goldens/all/Mobilo/m.png create mode 100644 lottie/test/goldens/all/Mobilo/n.png create mode 100644 lottie/test/goldens/all/Mobilo/o.png create mode 100644 lottie/test/goldens/all/Mobilo/p.png create mode 100644 lottie/test/goldens/all/Mobilo/q.png create mode 100644 lottie/test/goldens/all/Mobilo/r.png create mode 100644 lottie/test/goldens/all/Mobilo/s.png create mode 100644 lottie/test/goldens/all/Mobilo/t.png create mode 100644 lottie/test/goldens/all/Mobilo/u.png create mode 100644 lottie/test/goldens/all/Mobilo/v.png create mode 100644 lottie/test/goldens/all/Mobilo/w.png create mode 100644 lottie/test/goldens/all/Mobilo/x.png create mode 100644 lottie/test/goldens/all/Mobilo/y.png create mode 100644 lottie/test/goldens/all/Mobilo/z.png create mode 100644 lottie/test/goldens/all/Tests/ telegramalphacompat.png create mode 100644 lottie/test/goldens/all/Tests/1669133489622.png create mode 100644 lottie/test/goldens/all/Tests/2frameanimation.png create mode 100644 lottie/test/goldens/all/Tests/2parentsmatte.png create mode 100644 lottie/test/goldens/all/Tests/adrock.png create mode 100644 lottie/test/goldens/all/Tests/adrock_converted.png create mode 100644 lottie/test/goldens/all/Tests/airbnb.png create mode 100644 lottie/test/goldens/all/Tests/airbnb400.png create mode 100644 lottie/test/goldens/all/Tests/airbnb800.png create mode 100644 lottie/test/goldens/all/Tests/anim_jpg.png create mode 100644 lottie/test/goldens/all/Tests/animatedshadow.png create mode 100644 lottie/test/goldens/all/Tests/august_view_pulse.png create mode 100644 lottie/test/goldens/all/Tests/autoorient.png create mode 100644 lottie/test/goldens/all/Tests/beyondbounds.png create mode 100644 lottie/test/goldens/all/Tests/bm.png create mode 100644 lottie/test/goldens/all/Tests/bm_converted.png create mode 100644 lottie/test/goldens/all/Tests/bounceeasings.png create mode 100644 lottie/test/goldens/all/Tests/boxposition.png create mode 100644 lottie/test/goldens/all/Tests/catrim.png create mode 100644 lottie/test/goldens/all/Tests/catrim_converted.png create mode 100644 lottie/test/goldens/all/Tests/checkswitch.png create mode 100644 lottie/test/goldens/all/Tests/dalek.png create mode 100644 lottie/test/goldens/all/Tests/dalek_converted.png create mode 100644 lottie/test/goldens/all/Tests/defaultlinejoincap.png create mode 100644 lottie/test/goldens/all/Tests/differentpointscount.png create mode 100644 lottie/test/goldens/all/Tests/dynamicgradient.png create mode 100644 lottie/test/goldens/all/Tests/dynamictext.png create mode 100644 lottie/test/goldens/all/Tests/editedcolor.png create mode 100644 lottie/test/goldens/all/Tests/ellipsedirection.png create mode 100644 lottie/test/goldens/all/Tests/embeddedfont.png create mode 100644 lottie/test/goldens/all/Tests/endframe.png create mode 100644 lottie/test/goldens/all/Tests/exported_with_flow.png create mode 100644 lottie/test/goldens/all/Tests/fill.png create mode 100644 lottie/test/goldens/all/Tests/fillblur.png create mode 100644 lottie/test/goldens/all/Tests/font_text_justification_translate_scale_rotation_test.png create mode 100644 lottie/test/goldens/all/Tests/frame.png create mode 100644 lottie/test/goldens/all/Tests/framerate.png create mode 100644 lottie/test/goldens/all/Tests/gradientcolorkeyframeanimation.png create mode 100644 lottie/test/goldens/all/Tests/gradientfill.png create mode 100644 lottie/test/goldens/all/Tests/gradientfillblur.png create mode 100644 lottie/test/goldens/all/Tests/gradientonecolor.png create mode 100644 lottie/test/goldens/all/Tests/gradientopacityinterpolation.png create mode 100644 lottie/test/goldens/all/Tests/gradients.color_opacity.changes.multiple.stops.countfirst.png create mode 100644 lottie/test/goldens/all/Tests/gradientstrokeblur.png create mode 100644 lottie/test/goldens/all/Tests/gradientwithvaryingopacitystops.png create mode 100644 lottie/test/goldens/all/Tests/hd.png create mode 100644 lottie/test/goldens/all/Tests/heart.png create mode 100644 lottie/test/goldens/all/Tests/interpolatebetweenopacitystops.png create mode 100644 lottie/test/goldens/all/Tests/interpolatorloopback.png create mode 100644 lottie/test/goldens/all/Tests/issue_288.png create mode 100644 lottie/test/goldens/all/Tests/keyframetypes.png create mode 100644 lottie/test/goldens/all/Tests/kona_splash_animation.png create mode 100644 lottie/test/goldens/all/Tests/largecomposition.png create mode 100644 lottie/test/goldens/all/Tests/largesquare.png create mode 100644 lottie/test/goldens/all/Tests/laugh4.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_0.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_1.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_10.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_11.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_12.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_13.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_14.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_15.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_16.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_17.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_2.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_3.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_4.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_5.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_6.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_7.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_8.png create mode 100644 lottie/test/goldens/all/Tests/layerblend_9.png create mode 100644 lottie/test/goldens/all/Tests/loopplayonce.png create mode 100644 lottie/test/goldens/all/Tests/map.png create mode 100644 lottie/test/goldens/all/Tests/marker.png create mode 100644 lottie/test/goldens/all/Tests/maska.png create mode 100644 lottie/test/goldens/all/Tests/maskinv.png create mode 100644 lottie/test/goldens/all/Tests/masknone.png create mode 100644 lottie/test/goldens/all/Tests/masks.png create mode 100644 lottie/test/goldens/all/Tests/mattetimestretchline.png create mode 100644 lottie/test/goldens/all/Tests/mattetimestretchscan.png create mode 100644 lottie/test/goldens/all/Tests/missingendvalue.png create mode 100644 lottie/test/goldens/all/Tests/miterlimit.png create mode 100644 lottie/test/goldens/all/Tests/multiline.png create mode 100644 lottie/test/goldens/all/Tests/nullendshape.png create mode 100644 lottie/test/goldens/all/Tests/opacity_layers.png create mode 100644 lottie/test/goldens/all/Tests/opacitystops.png create mode 100644 lottie/test/goldens/all/Tests/overlapshapewithopacity.png create mode 100644 lottie/test/goldens/all/Tests/parenting.png create mode 100644 lottie/test/goldens/all/Tests/precompblur.png create mode 100644 lottie/test/goldens/all/Tests/precompblurdecimapprecompsize.png create mode 100644 lottie/test/goldens/all/Tests/precomps.png create mode 100644 lottie/test/goldens/all/Tests/rect1.png create mode 100644 lottie/test/goldens/all/Tests/rect2.png create mode 100644 lottie/test/goldens/all/Tests/rect3.png create mode 100644 lottie/test/goldens/all/Tests/rect4.png create mode 100644 lottie/test/goldens/all/Tests/rect5.png create mode 100644 lottie/test/goldens/all/Tests/rect6.png create mode 100644 lottie/test/goldens/all/Tests/rect7.png create mode 100644 lottie/test/goldens/all/Tests/rect8.png create mode 100644 lottie/test/goldens/all/Tests/rect9.png create mode 100644 lottie/test/goldens/all/Tests/remap.png create mode 100644 lottie/test/goldens/all/Tests/repeater.png create mode 100644 lottie/test/goldens/all/Tests/reversedstar.png create mode 100644 lottie/test/goldens/all/Tests/rgb.png create mode 100644 lottie/test/goldens/all/Tests/rgbmarker.png create mode 100644 lottie/test/goldens/all/Tests/roundedcorners.png create mode 100644 lottie/test/goldens/all/Tests/roundednonclosed.png create mode 100644 lottie/test/goldens/all/Tests/roundedwithalreadyroundedcorners.png create mode 100644 lottie/test/goldens/all/Tests/scale0.png create mode 100644 lottie/test/goldens/all/Tests/shapes.png create mode 100644 lottie/test/goldens/all/Tests/shapetypes.png create mode 100644 lottie/test/goldens/all/Tests/skew.png create mode 100644 lottie/test/goldens/all/Tests/solidlayertransform.png create mode 100644 lottie/test/goldens/all/Tests/splitdimensions.png create mode 100644 lottie/test/goldens/all/Tests/splitpathtransform.png create mode 100644 lottie/test/goldens/all/Tests/squares.png create mode 100644 lottie/test/goldens/all/Tests/starskew.png create mode 100644 lottie/test/goldens/all/Tests/startendframe.png create mode 100644 lottie/test/goldens/all/Tests/staticshadow.png create mode 100644 lottie/test/goldens/all/Tests/stroke.png create mode 100644 lottie/test/goldens/all/Tests/strokeblur.png create mode 100644 lottie/test/goldens/all/Tests/telegramalphacompat.png create mode 100644 lottie/test/goldens/all/Tests/text.png create mode 100644 lottie/test/goldens/all/Tests/text_justification_translate_scale_rotation_text.png create mode 100644 lottie/test/goldens/all/Tests/text_with_parent_alpha.png create mode 100644 lottie/test/goldens/all/Tests/textbaseline.png create mode 100644 lottie/test/goldens/all/Tests/textwithpscenter.png create mode 100644 lottie/test/goldens/all/Tests/textwithpsleft.png create mode 100644 lottie/test/goldens/all/Tests/tgswithoutopacity.png create mode 100644 lottie/test/goldens/all/Tests/thumb.png create mode 100644 lottie/test/goldens/all/Tests/timeremapandstartoffset.png create mode 100644 lottie/test/goldens/all/Tests/timestretch.png create mode 100644 lottie/test/goldens/all/Tests/timestretchandstartoffset.png create mode 100644 lottie/test/goldens/all/Tests/timestretchmask.png create mode 100644 lottie/test/goldens/all/Tests/timestretchprecomp.png create mode 100644 lottie/test/goldens/all/Tests/timestretchprecomp2.png create mode 100644 lottie/test/goldens/all/Tests/trackmattes.png create mode 100644 lottie/test/goldens/all/Tests/transformwithoutendvalues.png create mode 100644 lottie/test/goldens/all/Tests/trimpaths.png create mode 100644 lottie/test/goldens/all/Tests/trimpathsinsideandoutsidegroup.png create mode 100644 lottie/test/goldens/all/Tests/trimpathwraparound.png create mode 100644 lottie/test/goldens/all/Tests/weaccept.png create mode 100644 lottie/test/goldens/all/Tests/weacceptinlineimage.png create mode 100644 lottie/test/goldens/all/Tests/wile.png create mode 100644 lottie/test/goldens/all/Tests/zipinlineimage.png create mode 100644 lottie/test/goldens/all/androidwave.png create mode 100644 lottie/test/goldens/all/animation-1700642783167.png create mode 100644 lottie/test/goldens/all/battery_optimizations.png create mode 100644 lottie/test/goldens/all/blub.png create mode 100644 lottie/test/goldens/all/bluetoothscanning.png create mode 100644 lottie/test/goldens/all/camera_change.png create mode 100644 lottie/test/goldens/all/dynamicgradient.png create mode 100644 lottie/test/goldens/all/envelope.png create mode 100644 lottie/test/goldens/all/example_with_images/data.png create mode 100644 lottie/test/goldens/all/gradientcolorinterpolation.png create mode 100644 lottie/test/goldens/all/hamburgerarrow.png create mode 100644 lottie/test/goldens/all/issue270.png create mode 100644 lottie/test/goldens/all/lf20_w2afea.png create mode 100644 lottie/test/goldens/all/lottiefiles/100_percent.png create mode 100644 lottie/test/goldens/all/lottiefiles/28861-connection-style-2.png create mode 100644 lottie/test/goldens/all/lottiefiles/45668-arrow-with-light-passing-through.png create mode 100644 lottie/test/goldens/all/lottiefiles/a_mountain.png create mode 100644 lottie/test/goldens/all/lottiefiles/accept_arrows.png create mode 100644 lottie/test/goldens/all/lottiefiles/airbnb.png create mode 100644 lottie/test/goldens/all/lottiefiles/android_fingerprint.png create mode 100644 lottie/test/goldens/all/lottiefiles/angel.png create mode 100644 lottie/test/goldens/all/lottiefiles/anima.png create mode 100644 lottie/test/goldens/all/lottiefiles/animated_graph.png create mode 100644 lottie/test/goldens/all/lottiefiles/animated_laptop_.png create mode 100644 lottie/test/goldens/all/lottiefiles/animated_logo.png create mode 100644 lottie/test/goldens/all/lottiefiles/atm_link.png create mode 100644 lottie/test/goldens/all/lottiefiles/autoconnect_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/ball_&_map.png create mode 100644 lottie/test/goldens/all/lottiefiles/banner_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/bb8.png create mode 100644 lottie/test/goldens/all/lottiefiles/bell.png create mode 100644 lottie/test/goldens/all/lottiefiles/birds.png create mode 100644 lottie/test/goldens/all/lottiefiles/bitcoin_to_the_moon.png create mode 100644 lottie/test/goldens/all/lottiefiles/blood_transfusion_kawaii.png create mode 100644 lottie/test/goldens/all/lottiefiles/bomb.png create mode 100644 lottie/test/goldens/all/lottiefiles/books.png create mode 100644 lottie/test/goldens/all/lottiefiles/bootymovin.png create mode 100644 lottie/test/goldens/all/lottiefiles/bounching_ball.png create mode 100644 lottie/test/goldens/all/lottiefiles/brain__.png create mode 100644 lottie/test/goldens/all/lottiefiles/browser.png create mode 100644 lottie/test/goldens/all/lottiefiles/building_evolution_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/camera.png create mode 100644 lottie/test/goldens/all/lottiefiles/camptravel.png create mode 100644 lottie/test/goldens/all/lottiefiles/cancel_button.png create mode 100644 lottie/test/goldens/all/lottiefiles/cash.png create mode 100644 lottie/test/goldens/all/lottiefiles/change_to_search_bar.png create mode 100644 lottie/test/goldens/all/lottiefiles/check_pop.png create mode 100644 lottie/test/goldens/all/lottiefiles/chinese.png create mode 100644 lottie/test/goldens/all/lottiefiles/clock.png create mode 100644 lottie/test/goldens/all/lottiefiles/cloud_disconnection.png create mode 100644 lottie/test/goldens/all/lottiefiles/code_invite_success.png create mode 100644 lottie/test/goldens/all/lottiefiles/coding_ape.png create mode 100644 lottie/test/goldens/all/lottiefiles/coinfall.png create mode 100644 lottie/test/goldens/all/lottiefiles/colorline.png create mode 100644 lottie/test/goldens/all/lottiefiles/confusion.png create mode 100644 lottie/test/goldens/all/lottiefiles/construction_site.png create mode 100644 lottie/test/goldens/all/lottiefiles/cooking_app.png create mode 100644 lottie/test/goldens/all/lottiefiles/countdown.png create mode 100644 lottie/test/goldens/all/lottiefiles/credit_card.png create mode 100644 lottie/test/goldens/all/lottiefiles/credit_level.png create mode 100644 lottie/test/goldens/all/lottiefiles/cube_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/cubo_livre.png create mode 100644 lottie/test/goldens/all/lottiefiles/curly_hair_character_loop.png create mode 100644 lottie/test/goldens/all/lottiefiles/cycle_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/day_night_cycle.png create mode 100644 lottie/test/goldens/all/lottiefiles/day_of_the_dead.png create mode 100644 lottie/test/goldens/all/lottiefiles/deadpool.png create mode 100644 lottie/test/goldens/all/lottiefiles/delivery_van.png create mode 100644 lottie/test/goldens/all/lottiefiles/developer-animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/dna_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/dog.png create mode 100644 lottie/test/goldens/all/lottiefiles/done.png create mode 100644 lottie/test/goldens/all/lottiefiles/download copy.png create mode 100644 lottie/test/goldens/all/lottiefiles/download.png create mode 100644 lottie/test/goldens/all/lottiefiles/downloader.png create mode 100644 lottie/test/goldens/all/lottiefiles/drop.png create mode 100644 lottie/test/goldens/all/lottiefiles/drop_to_refresh.png create mode 100644 lottie/test/goldens/all/lottiefiles/edited-landscape.png create mode 100644 lottie/test/goldens/all/lottiefiles/elephant_trunk_swing.png create mode 100644 lottie/test/goldens/all/lottiefiles/emoji_shock.png create mode 100644 lottie/test/goldens/all/lottiefiles/emoji_tongue.png create mode 100644 lottie/test/goldens/all/lottiefiles/emoji_wink.png create mode 100644 lottie/test/goldens/all/lottiefiles/empty_status.png create mode 100644 lottie/test/goldens/all/lottiefiles/estimate.png create mode 100644 lottie/test/goldens/all/lottiefiles/fab_animate.png create mode 100644 lottie/test/goldens/all/lottiefiles/fabulous_onboarding_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/favourite_app_icon.png create mode 100644 lottie/test/goldens/all/lottiefiles/file_error.png create mode 100644 lottie/test/goldens/all/lottiefiles/finance_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/fingerprint_scanner.png create mode 100644 lottie/test/goldens/all/lottiefiles/finish,done.png create mode 100644 lottie/test/goldens/all/lottiefiles/fish.png create mode 100644 lottie/test/goldens/all/lottiefiles/flag_of_mexico.png create mode 100644 lottie/test/goldens/all/lottiefiles/flow.png create mode 100644 lottie/test/goldens/all/lottiefiles/frog.png create mode 100644 lottie/test/goldens/all/lottiefiles/funky_chicken.png create mode 100644 lottie/test/goldens/all/lottiefiles/gaming_pad.png create mode 100644 lottie/test/goldens/all/lottiefiles/gears.png create mode 100644 lottie/test/goldens/all/lottiefiles/geometry.png create mode 100644 lottie/test/goldens/all/lottiefiles/glow_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/gradient_animated_background.png create mode 100644 lottie/test/goldens/all/lottiefiles/happy birthday.png create mode 100644 lottie/test/goldens/all/lottiefiles/hardware.png create mode 100644 lottie/test/goldens/all/lottiefiles/hint_01.png create mode 100644 lottie/test/goldens/all/lottiefiles/im_thirsty.png create mode 100644 lottie/test/goldens/all/lottiefiles/immiguide_.png create mode 100644 lottie/test/goldens/all/lottiefiles/in-app_purchasing.png create mode 100644 lottie/test/goldens/all/lottiefiles/india.png create mode 100644 lottie/test/goldens/all/lottiefiles/infinite_rainbow.png create mode 100644 lottie/test/goldens/all/lottiefiles/intelia_logo_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/iphone_x_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/jojo_the_bird.png create mode 100644 lottie/test/goldens/all/lottiefiles/jolly_walker.png create mode 100644 lottie/test/goldens/all/lottiefiles/judgement.png create mode 100644 lottie/test/goldens/all/lottiefiles/kod.io_logo_reveal.png create mode 100644 lottie/test/goldens/all/lottiefiles/la_calavera.png create mode 100644 lottie/test/goldens/all/lottiefiles/landing_page.png create mode 100644 lottie/test/goldens/all/lottiefiles/lego_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/lf20_fteywrno.png create mode 100644 lottie/test/goldens/all/lottiefiles/light.png create mode 100644 lottie/test/goldens/all/lottiefiles/lightsaber.png create mode 100644 lottie/test/goldens/all/lottiefiles/little_girl_jumping_-_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/loading_copy.png create mode 100644 lottie/test/goldens/all/lottiefiles/loading_disc.png create mode 100644 lottie/test/goldens/all/lottiefiles/loading_semicircle.png create mode 100644 lottie/test/goldens/all/lottiefiles/location.png create mode 100644 lottie/test/goldens/all/lottiefiles/location_marker.png create mode 100644 lottie/test/goldens/all/lottiefiles/location_pin.png create mode 100644 lottie/test/goldens/all/lottiefiles/lottie_logo_1.png create mode 100644 lottie/test/goldens/all/lottiefiles/lottiepreview_qr.png create mode 100644 lottie/test/goldens/all/lottiefiles/mailsent.png create mode 100644 lottie/test/goldens/all/lottiefiles/man_and_pay_with_credit_card.png create mode 100644 lottie/test/goldens/all/lottiefiles/map_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/material loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/material_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/material_loading_2.png create mode 100644 lottie/test/goldens/all/lottiefiles/material_wave_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/me_at_office.png create mode 100644 lottie/test/goldens/all/lottiefiles/medal.png create mode 100644 lottie/test/goldens/all/lottiefiles/menu_button_alt.png create mode 100644 lottie/test/goldens/all/lottiefiles/menubutton2.png create mode 100644 lottie/test/goldens/all/lottiefiles/mindful.png create mode 100644 lottie/test/goldens/all/lottiefiles/mnemonics.png create mode 100644 lottie/test/goldens/all/lottiefiles/money.png create mode 100644 lottie/test/goldens/all/lottiefiles/motorcycle.png create mode 100644 lottie/test/goldens/all/lottiefiles/moving bus.png create mode 100644 lottie/test/goldens/all/lottiefiles/moving_eye.png create mode 100644 lottie/test/goldens/all/lottiefiles/no_internet_connection.png create mode 100644 lottie/test/goldens/all/lottiefiles/notification_request.png create mode 100644 lottie/test/goldens/all/lottiefiles/octopus.png create mode 100644 lottie/test/goldens/all/lottiefiles/ofrenda.png create mode 100644 lottie/test/goldens/all/lottiefiles/on_off_settings_switch.png create mode 100644 lottie/test/goldens/all/lottiefiles/pagado.png create mode 100644 lottie/test/goldens/all/lottiefiles/pagination.png create mode 100644 lottie/test/goldens/all/lottiefiles/panel2d.png create mode 100644 lottie/test/goldens/all/lottiefiles/passport.png create mode 100644 lottie/test/goldens/all/lottiefiles/patient_successfully_added.png create mode 100644 lottie/test/goldens/all/lottiefiles/payme.png create mode 100644 lottie/test/goldens/all/lottiefiles/peli-canon.png create mode 100644 lottie/test/goldens/all/lottiefiles/pen_tool_loop.png create mode 100644 lottie/test/goldens/all/lottiefiles/pencil_write.png create mode 100644 lottie/test/goldens/all/lottiefiles/penguin.png create mode 100644 lottie/test/goldens/all/lottiefiles/permission.png create mode 100644 lottie/test/goldens/all/lottiefiles/personal_character.png create mode 100644 lottie/test/goldens/all/lottiefiles/ph_onboarding_.png create mode 100644 lottie/test/goldens/all/lottiefiles/phonological.png create mode 100644 lottie/test/goldens/all/lottiefiles/pink_drink_machine.png create mode 100644 lottie/test/goldens/all/lottiefiles/plane.png create mode 100644 lottie/test/goldens/all/lottiefiles/plane_to_dollar.png create mode 100644 lottie/test/goldens/all/lottiefiles/play,_pause.png create mode 100644 lottie/test/goldens/all/lottiefiles/play_and_like_it.png create mode 100644 lottie/test/goldens/all/lottiefiles/play_button.png create mode 100644 lottie/test/goldens/all/lottiefiles/playing.png create mode 100644 lottie/test/goldens/all/lottiefiles/point.png create mode 100644 lottie/test/goldens/all/lottiefiles/poo_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/powerupp_app_onboard (1).png create mode 100644 lottie/test/goldens/all/lottiefiles/powerupp_app_onboard.png create mode 100644 lottie/test/goldens/all/lottiefiles/preloader.png create mode 100644 lottie/test/goldens/all/lottiefiles/print.png create mode 100644 lottie/test/goldens/all/lottiefiles/progress_bar 2.png create mode 100644 lottie/test/goldens/all/lottiefiles/progress_bar.png create mode 100644 lottie/test/goldens/all/lottiefiles/rating.png create mode 100644 lottie/test/goldens/all/lottiefiles/red_pocket_pop_up.png create mode 100644 lottie/test/goldens/all/lottiefiles/rejection.png create mode 100644 lottie/test/goldens/all/lottiefiles/retweet.png create mode 100644 lottie/test/goldens/all/lottiefiles/rocket.png create mode 100644 lottie/test/goldens/all/lottiefiles/rocksauce_title_card.png create mode 100644 lottie/test/goldens/all/lottiefiles/scan.png create mode 100644 lottie/test/goldens/all/lottiefiles/scan_qr_code_success.png create mode 100644 lottie/test/goldens/all/lottiefiles/search_button.png create mode 100644 lottie/test/goldens/all/lottiefiles/security_token_roundtable.png create mode 100644 lottie/test/goldens/all/lottiefiles/sensor_scan.png create mode 100644 lottie/test/goldens/all/lottiefiles/servishero_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/simple_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/sky.png create mode 100644 lottie/test/goldens/all/lottiefiles/slack_app_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/snowcation.png create mode 100644 lottie/test/goldens/all/lottiefiles/socar_logo.png create mode 100644 lottie/test/goldens/all/lottiefiles/soda_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/spacehub.png create mode 100644 lottie/test/goldens/all/lottiefiles/spinner loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/splashy_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/square_drop_loader.png create mode 100644 lottie/test/goldens/all/lottiefiles/star 2.png create mode 100644 lottie/test/goldens/all/lottiefiles/streetby_test_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/streetbymorning.png create mode 100644 lottie/test/goldens/all/lottiefiles/submit button.png create mode 100644 lottie/test/goldens/all/lottiefiles/summer.png create mode 100644 lottie/test/goldens/all/lottiefiles/sushi_and_wine.png create mode 100644 lottie/test/goldens/all/lottiefiles/swiftkey-logo.png create mode 100644 lottie/test/goldens/all/lottiefiles/swipe_menu.png create mode 100644 lottie/test/goldens/all/lottiefiles/swipe_right_indicator.png create mode 100644 lottie/test/goldens/all/lottiefiles/switch_loop.png create mode 100644 lottie/test/goldens/all/lottiefiles/the_final_frontier.png create mode 100644 lottie/test/goldens/all/lottiefiles/tigerobo_demo.png create mode 100644 lottie/test/goldens/all/lottiefiles/timer_(3_second_loop).png create mode 100644 lottie/test/goldens/all/lottiefiles/toggle.png create mode 100644 lottie/test/goldens/all/lottiefiles/toggle_switch.png create mode 100644 lottie/test/goldens/all/lottiefiles/touch_id.png create mode 100644 lottie/test/goldens/all/lottiefiles/tractor.png create mode 100644 lottie/test/goldens/all/lottiefiles/tractor_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/trail_loading.png create mode 100644 lottie/test/goldens/all/lottiefiles/trophy.png create mode 100644 lottie/test/goldens/all/lottiefiles/trophy_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/truecosmos.png create mode 100644 lottie/test/goldens/all/lottiefiles/turbine.png create mode 100644 lottie/test/goldens/all/lottiefiles/typing dot.png create mode 100644 lottie/test/goldens/all/lottiefiles/uk.png create mode 100644 lottie/test/goldens/all/lottiefiles/updating_map.png create mode 100644 lottie/test/goldens/all/lottiefiles/us.png create mode 100644 lottie/test/goldens/all/lottiefiles/video_cam.png create mode 100644 lottie/test/goldens/all/lottiefiles/vigilance_camera.png create mode 100644 lottie/test/goldens/all/lottiefiles/volume_indicator.png create mode 100644 lottie/test/goldens/all/lottiefiles/volume_shake_indicator.png create mode 100644 lottie/test/goldens/all/lottiefiles/vr_animation.png create mode 100644 lottie/test/goldens/all/lottiefiles/vr_sickness.png create mode 100644 lottie/test/goldens/all/lottiefiles/walking.png create mode 100644 lottie/test/goldens/all/lottiefiles/walking_arrow.png create mode 100644 lottie/test/goldens/all/lottiefiles/wallet recharge.png create mode 100644 lottie/test/goldens/all/lottiefiles/washing_machine.png create mode 100644 lottie/test/goldens/all/lottiefiles/win_result_2.png create mode 100644 lottie/test/goldens/all/lottiefiles/wolf_peek.png create mode 100644 lottie/test/goldens/all/lottiefiles/x_pop.png create mode 100644 lottie/test/goldens/all/lottiefiles/xamarin_logo_2.png create mode 100644 lottie/test/goldens/all/lottiefiles/xuanwheel_logo.png create mode 100644 lottie/test/goldens/all/lottiefiles/yoga_carpet.png create mode 100644 lottie/test/goldens/all/lottiefiles/youtube_icon_reveal.png create mode 100644 lottie/test/goldens/all/lottielogo1.png create mode 100644 lottie/test/goldens/all/lottielogo2.png create mode 100644 lottie/test/goldens/all/pass_loading.png create mode 100644 lottie/test/goldens/all/playing.png create mode 100644 lottie/test/goldens/all/spinning_carrousel.png create mode 100644 lottie/test/goldens/all/sticker.png create mode 100644 lottie/test/goldens/all/tent.png create mode 100644 lottie/test/goldens/all/twitterheartbutton.png create mode 100644 lottie/test/goldens/all/vegan_font.png create mode 100644 lottie/test/goldens/all/weather/fog.png create mode 100644 lottie/test/goldens/all/weather/hurricane.png create mode 100644 lottie/test/goldens/all/weather/thunder-storm.png create mode 100644 lottie/test/goldens/all/weather/tornado.png create mode 100644 lottie/test/goldens/all/weather/windy.png create mode 100644 lottie/test/goldens/dotlottie.png create mode 100644 lottie/test/goldens/dynamic/blur.png create mode 100644 lottie/test/goldens/dynamic/color_filter.png create mode 100644 lottie/test/goldens/dynamic/drop_shadow.png create mode 100644 lottie/test/goldens/dynamic/ellipse_position.png create mode 100644 lottie/test/goldens/dynamic/ellipse_size.png create mode 100644 lottie/test/goldens/dynamic/fill_color_green.png create mode 100644 lottie/test/goldens/dynamic/fill_color_yellow.png create mode 100644 lottie/test/goldens/dynamic/fill_opacity.png create mode 100644 lottie/test/goldens/dynamic/matte_property.png create mode 100644 lottie/test/goldens/dynamic/null_color_filter.png create mode 100644 lottie/test/goldens/dynamic/opacity_interpolation_00.png create mode 100644 lottie/test/goldens/dynamic/opacity_interpolation_05.png create mode 100644 lottie/test/goldens/dynamic/opacity_interpolation_10.png create mode 100644 lottie/test/goldens/dynamic/polygon_points.png create mode 100644 lottie/test/goldens/dynamic/polygon_position.png create mode 100644 lottie/test/goldens/dynamic/polygon_radius.png create mode 100644 lottie/test/goldens/dynamic/polygon_rotation.png create mode 100644 lottie/test/goldens/dynamic/polygon_roundedness.png create mode 100644 lottie/test/goldens/dynamic/rectangle_corner_roundedness.png create mode 100644 lottie/test/goldens/dynamic/rectangle_position.png create mode 100644 lottie/test/goldens/dynamic/rectangle_size.png create mode 100644 lottie/test/goldens/dynamic/repeater_transform_end_opacity.png create mode 100644 lottie/test/goldens/dynamic/repeater_transform_position.png create mode 100644 lottie/test/goldens/dynamic/repeater_transform_rotation.png create mode 100644 lottie/test/goldens/dynamic/repeater_transform_scale.png create mode 100644 lottie/test/goldens/dynamic/repeater_transform_start_opacity.png create mode 100644 lottie/test/goldens/dynamic/solid_color.png create mode 100644 lottie/test/goldens/dynamic/star_inner_radius.png create mode 100644 lottie/test/goldens/dynamic/star_inner_roundedness.png create mode 100644 lottie/test/goldens/dynamic/star_outer_radius.png create mode 100644 lottie/test/goldens/dynamic/star_outer_roundedness.png create mode 100644 lottie/test/goldens/dynamic/star_points.png create mode 100644 lottie/test/goldens/dynamic/star_position.png create mode 100644 lottie/test/goldens/dynamic/star_rotation.png create mode 100644 lottie/test/goldens/dynamic/stroke_color.png create mode 100644 lottie/test/goldens/dynamic/stroke_opacity.png create mode 100644 lottie/test/goldens/dynamic/stroke_width.png create mode 100644 lottie/test/goldens/dynamic/time_remapping.png create mode 100644 lottie/test/goldens/dynamic/transform_anchor_point.png create mode 100644 lottie/test/goldens/dynamic/transform_opacity.png create mode 100644 lottie/test/goldens/dynamic/transform_position.png create mode 100644 lottie/test/goldens/dynamic/transform_position_relative.png create mode 100644 lottie/test/goldens/dynamic/transform_rotation.png create mode 100644 lottie/test/goldens/dynamic/transform_scale.png create mode 100644 lottie/test/goldens/dynamic_image/delegate.png create mode 100644 lottie/test/goldens/dynamic_image/zip_with_provider.png create mode 100644 lottie/test/goldens/dynamic_text.png create mode 100644 lottie/test/goldens/dynamic_text/dynamic_text_delegate.png create mode 100644 lottie/test/goldens/dynamic_text/dynamic_text_emoji.png create mode 100644 lottie/test/goldens/dynamic_text/dynamic_text_valuedelegate.png create mode 100644 lottie/test/goldens/dynamic_text/dynamic_text_valuedelegate_endvalue.png create mode 100644 lottie/test/goldens/dynamic_text/dynamic_text_valuedelegate_overallprogress.png create mode 100644 lottie/test/goldens/dynamic_text/dynamic_text_valuedelegate_startvalue.png create mode 100644 lottie/test/goldens/dynamic_text/text_fill_blue__green.png create mode 100644 lottie/test/goldens/dynamic_text/text_stroke_red__yellow.png create mode 100644 lottie/test/goldens/dynamic_text/text_stroke_width.png create mode 100644 lottie/test/goldens/dynamic_text/text_tracking_1.png create mode 100644 lottie/test/goldens/dynamic_text/text_tracking_2.png create mode 100644 lottie/test/goldens/enable_render_cache.png create mode 100644 lottie/test/goldens/fireworks.png create mode 100644 lottie/test/goldens/gradients/blub_red_callback.png create mode 100644 lottie/test/goldens/gradients/blub_red_value.png create mode 100644 lottie/test/goldens/gradients/linear_gradient_fill.png create mode 100644 lottie/test/goldens/gradients/linear_gradient_stroke.png create mode 100644 lottie/test/goldens/gradients/opacity_linear_gradient_fill.png create mode 100644 lottie/test/goldens/gradients/radial_gradient_fill.png create mode 100644 lottie/test/goldens/gradients/radial_gradient_stroke.png create mode 100644 lottie/test/goldens/lightningbug_file.png create mode 100644 lottie/test/goldens/mirror.png create mode 100644 lottie/test/goldens/opacity_layers.png create mode 100644 lottie/test/goldens/warningShimmer_1.png create mode 100644 lottie/test/goldens/warningShimmer_2.png create mode 100644 lottie/test/goldens/warningShimmer_3.png create mode 100644 lottie/test/gradient_test.dart create mode 100644 lottie/test/lottie_test.dart create mode 100644 lottie/test/opacity_layer_test.dart create mode 100644 lottie/test/parser/moshi/buffer_test.dart create mode 100644 lottie/test/parser/moshi/json_reader_test.dart create mode 100644 lottie/test/render_cache_store_test.dart create mode 100644 lottie/test/render_cache_test.dart create mode 100644 lottie/test/screenshot_test.dart create mode 100644 lottie/test/telegram_sticker_test.dart create mode 100644 lottie/test/utils.dart create mode 100644 mutex/LICENSE create mode 100644 mutex/lib/mutex.dart create mode 100644 mutex/lib/src/mutex.dart create mode 100644 mutex/lib/src/read_write_mutex.dart create mode 100644 mutex/pubspec.yaml create mode 100644 mutex/test/mutex_multiple_read_test.dart create mode 100644 mutex/test/mutex_readwrite_test.dart create mode 100644 mutex/test/mutex_test.dart create mode 100644 optional/LICENSE create mode 100644 optional/lib/optional.dart create mode 100644 optional/lib/optional_internal.dart create mode 100644 optional/lib/src/absent.dart create mode 100644 optional/lib/src/extension.dart create mode 100644 optional/lib/src/novaluepresent.dart create mode 100644 optional/lib/src/present.dart create mode 100644 optional/pubspec.yaml create mode 100644 optional/test/optional_test.dart create mode 100644 optional/test/src/async.dart create mode 100644 optional/test/src/equality.dart create mode 100644 optional/test/src/extension.dart create mode 100644 optional/test/src/iterable.dart create mode 100644 optional/test/src/methods.dart create mode 100644 photo_view/LICENSE create mode 100644 photo_view/lib/photo_view.dart create mode 100644 photo_view/lib/photo_view_gallery.dart create mode 100644 photo_view/lib/src/controller/photo_view_controller.dart create mode 100644 photo_view/lib/src/controller/photo_view_controller_delegate.dart create mode 100644 photo_view/lib/src/controller/photo_view_scalestate_controller.dart create mode 100644 photo_view/lib/src/core/photo_view_core.dart create mode 100644 photo_view/lib/src/core/photo_view_gesture_detector.dart create mode 100644 photo_view/lib/src/core/photo_view_hit_corners.dart create mode 100644 photo_view/lib/src/photo_view_computed_scale.dart create mode 100644 photo_view/lib/src/photo_view_default_widgets.dart create mode 100644 photo_view/lib/src/photo_view_scale_state.dart create mode 100644 photo_view/lib/src/photo_view_wrappers.dart create mode 100644 photo_view/lib/src/utils/ignorable_change_notifier.dart create mode 100644 photo_view/lib/src/utils/photo_view_hero_attributes.dart create mode 100644 photo_view/lib/src/utils/photo_view_utils.dart create mode 100644 photo_view/pubspec.yaml create mode 100644 photo_view/test/controller_test.dart create mode 100644 photo_view/test/scale_state_controller_test.dart create mode 100644 pointycastle/LICENSE create mode 100644 pointycastle/lib/adapters/stream_cipher_as_block_cipher.dart create mode 100644 pointycastle/lib/api.dart create mode 100644 pointycastle/lib/asn1.dart create mode 100644 pointycastle/lib/asn1/asn1_encoding_rule.dart create mode 100644 pointycastle/lib/asn1/asn1_object.dart create mode 100644 pointycastle/lib/asn1/asn1_parser.dart create mode 100644 pointycastle/lib/asn1/asn1_tags.dart create mode 100644 pointycastle/lib/asn1/asn1_utils.dart create mode 100644 pointycastle/lib/asn1/object_identifiers.dart create mode 100644 pointycastle/lib/asn1/object_identifiers_database.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs1/asn1_digest_info.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs10/asn1_certification_request.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs10/asn1_certification_request_info.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs10/asn1_subject_public_key_info.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_authenticated_safe.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_cert_bag.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_key_bag.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_mac_data.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_pfx.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_pkcs12_attribute.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_safe_bag.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs12/asn1_safe_contents.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs7/asn1_content_info.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs7/asn1_encrypted_content_info.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs8/asn1_encrypted_data.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs8/asn1_encrypted_private_key_info.dart create mode 100644 pointycastle/lib/asn1/pkcs/pkcs8/asn1_private_key_info.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_bit_string.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_bmp_string.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_boolean.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_enumerated.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_generalized_time.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_ia5_string.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_integer.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_null.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_object_identifier.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_octet_string.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_printable_string.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_sequence.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_set.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_teletext_string.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_utc_time.dart create mode 100644 pointycastle/lib/asn1/primitives/asn1_utf8_string.dart create mode 100644 pointycastle/lib/asn1/unsupported_asn1_encoding_rule_exception.dart create mode 100644 pointycastle/lib/asn1/unsupported_asn1_tag_exception.dart create mode 100644 pointycastle/lib/asn1/unsupported_object_identifier_exception.dart create mode 100644 pointycastle/lib/asn1/x501/asn1_attribute_type_and_value.dart create mode 100644 pointycastle/lib/asn1/x501/asn1_name.dart create mode 100644 pointycastle/lib/asn1/x501/asn1_rdn.dart create mode 100644 pointycastle/lib/asn1/x509/asn1_algorithm_identifier.dart create mode 100644 pointycastle/lib/asymmetric/api.dart create mode 100644 pointycastle/lib/asymmetric/ec_elgamal.dart create mode 100644 pointycastle/lib/asymmetric/oaep.dart create mode 100644 pointycastle/lib/asymmetric/pkcs1.dart create mode 100644 pointycastle/lib/asymmetric/rsa.dart create mode 100644 pointycastle/lib/block/aes.dart create mode 100644 pointycastle/lib/block/aes_fast.dart create mode 100644 pointycastle/lib/block/blowfish.dart create mode 100644 pointycastle/lib/block/camellia.dart create mode 100644 pointycastle/lib/block/des_base.dart create mode 100644 pointycastle/lib/block/desede_engine.dart create mode 100644 pointycastle/lib/block/modes/cbc.dart create mode 100644 pointycastle/lib/block/modes/ccm.dart create mode 100644 pointycastle/lib/block/modes/cfb.dart create mode 100644 pointycastle/lib/block/modes/ctr.dart create mode 100644 pointycastle/lib/block/modes/ecb.dart create mode 100644 pointycastle/lib/block/modes/gcm.dart create mode 100644 pointycastle/lib/block/modes/gctr.dart create mode 100644 pointycastle/lib/block/modes/ige.dart create mode 100644 pointycastle/lib/block/modes/ofb.dart create mode 100644 pointycastle/lib/block/modes/sic.dart create mode 100644 pointycastle/lib/block/rc2_engine.dart create mode 100644 pointycastle/lib/block/twofish.dart create mode 100644 pointycastle/lib/digests/blake2b.dart create mode 100644 pointycastle/lib/digests/cshake.dart create mode 100644 pointycastle/lib/digests/keccak.dart create mode 100644 pointycastle/lib/digests/md2.dart create mode 100644 pointycastle/lib/digests/md4.dart create mode 100644 pointycastle/lib/digests/md5.dart create mode 100644 pointycastle/lib/digests/ripemd128.dart create mode 100644 pointycastle/lib/digests/ripemd160.dart create mode 100644 pointycastle/lib/digests/ripemd256.dart create mode 100644 pointycastle/lib/digests/ripemd320.dart create mode 100644 pointycastle/lib/digests/sha1.dart create mode 100644 pointycastle/lib/digests/sha224.dart create mode 100644 pointycastle/lib/digests/sha256.dart create mode 100644 pointycastle/lib/digests/sha3.dart create mode 100644 pointycastle/lib/digests/sha384.dart create mode 100644 pointycastle/lib/digests/sha512.dart create mode 100644 pointycastle/lib/digests/sha512t.dart create mode 100644 pointycastle/lib/digests/shake.dart create mode 100644 pointycastle/lib/digests/sm3.dart create mode 100644 pointycastle/lib/digests/tiger.dart create mode 100644 pointycastle/lib/digests/whirlpool.dart create mode 100644 pointycastle/lib/digests/xof_utils.dart create mode 100644 pointycastle/lib/ecc/api.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp160r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp160t1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp192r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp192t1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp224r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp224t1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp256r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp256t1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp320r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp320t1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp384r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp384t1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp512r1.dart create mode 100644 pointycastle/lib/ecc/curves/brainpoolp512t1.dart create mode 100644 pointycastle/lib/ecc/curves/gostr3410_2001_cryptopro_a.dart create mode 100644 pointycastle/lib/ecc/curves/gostr3410_2001_cryptopro_b.dart create mode 100644 pointycastle/lib/ecc/curves/gostr3410_2001_cryptopro_c.dart create mode 100644 pointycastle/lib/ecc/curves/gostr3410_2001_cryptopro_xcha.dart create mode 100644 pointycastle/lib/ecc/curves/gostr3410_2001_cryptopro_xchb.dart create mode 100644 pointycastle/lib/ecc/curves/prime192v1.dart create mode 100644 pointycastle/lib/ecc/curves/prime192v2.dart create mode 100644 pointycastle/lib/ecc/curves/prime192v3.dart create mode 100644 pointycastle/lib/ecc/curves/prime239v1.dart create mode 100644 pointycastle/lib/ecc/curves/prime239v2.dart create mode 100644 pointycastle/lib/ecc/curves/prime239v3.dart create mode 100644 pointycastle/lib/ecc/curves/prime256v1.dart create mode 100644 pointycastle/lib/ecc/curves/secp112r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp112r2.dart create mode 100644 pointycastle/lib/ecc/curves/secp128r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp128r2.dart create mode 100644 pointycastle/lib/ecc/curves/secp160k1.dart create mode 100644 pointycastle/lib/ecc/curves/secp160r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp160r2.dart create mode 100644 pointycastle/lib/ecc/curves/secp192k1.dart create mode 100644 pointycastle/lib/ecc/curves/secp192r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp224k1.dart create mode 100644 pointycastle/lib/ecc/curves/secp224r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp256k1.dart create mode 100644 pointycastle/lib/ecc/curves/secp256r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp384r1.dart create mode 100644 pointycastle/lib/ecc/curves/secp521r1.dart create mode 100644 pointycastle/lib/ecc/ecc_base.dart create mode 100644 pointycastle/lib/ecc/ecc_fp.dart create mode 100644 pointycastle/lib/ecc/ecdh.dart create mode 100644 pointycastle/lib/export.dart create mode 100644 pointycastle/lib/impl.dart create mode 100644 pointycastle/lib/key_derivators/api.dart create mode 100644 pointycastle/lib/key_derivators/argon2.dart create mode 100644 pointycastle/lib/key_derivators/argon2_native_int_impl.dart create mode 100644 pointycastle/lib/key_derivators/argon2_register64_impl.dart create mode 100644 pointycastle/lib/key_derivators/concat_kdf.dart create mode 100644 pointycastle/lib/key_derivators/ecdh_kdf.dart create mode 100644 pointycastle/lib/key_derivators/hkdf.dart create mode 100644 pointycastle/lib/key_derivators/pbkdf2.dart create mode 100644 pointycastle/lib/key_derivators/pkcs12_parameter_generator.dart create mode 100644 pointycastle/lib/key_derivators/pkcs5s1_parameter_generator.dart create mode 100644 pointycastle/lib/key_derivators/scrypt.dart create mode 100644 pointycastle/lib/key_generators/api.dart create mode 100644 pointycastle/lib/key_generators/ec_key_generator.dart create mode 100644 pointycastle/lib/key_generators/rsa_key_generator.dart create mode 100644 pointycastle/lib/macs/cbc_block_cipher_mac.dart create mode 100644 pointycastle/lib/macs/cmac.dart create mode 100644 pointycastle/lib/macs/hmac.dart create mode 100644 pointycastle/lib/macs/poly1305.dart create mode 100644 pointycastle/lib/padded_block_cipher/padded_block_cipher_impl.dart create mode 100644 pointycastle/lib/paddings/iso7816d4.dart create mode 100644 pointycastle/lib/paddings/pkcs7.dart create mode 100644 pointycastle/lib/pointycastle.dart create mode 100644 pointycastle/lib/random/auto_seed_block_ctr_random.dart create mode 100644 pointycastle/lib/random/block_ctr_random.dart create mode 100644 pointycastle/lib/random/fortuna_random.dart create mode 100644 pointycastle/lib/signers/ecdsa_signer.dart create mode 100644 pointycastle/lib/signers/pss_signer.dart create mode 100644 pointycastle/lib/signers/rsa_signer.dart create mode 100644 pointycastle/lib/src/api/aead_block_cipher.dart create mode 100644 pointycastle/lib/src/api/aead_cipher.dart create mode 100644 pointycastle/lib/src/api/aead_parameters.dart create mode 100644 pointycastle/lib/src/api/algorithm.dart create mode 100644 pointycastle/lib/src/api/asymmetric_block_cipher.dart create mode 100644 pointycastle/lib/src/api/asymmetric_key.dart create mode 100644 pointycastle/lib/src/api/asymmetric_key_pair.dart create mode 100644 pointycastle/lib/src/api/asymmetric_key_parameter.dart create mode 100644 pointycastle/lib/src/api/block_cipher.dart create mode 100644 pointycastle/lib/src/api/cipher_parameters.dart create mode 100644 pointycastle/lib/src/api/des_parameters.dart create mode 100644 pointycastle/lib/src/api/desede_parameters.dart create mode 100644 pointycastle/lib/src/api/digest.dart create mode 100644 pointycastle/lib/src/api/key_derivator.dart create mode 100644 pointycastle/lib/src/api/key_generator.dart create mode 100644 pointycastle/lib/src/api/key_generator_parameters.dart create mode 100644 pointycastle/lib/src/api/key_parameter.dart create mode 100644 pointycastle/lib/src/api/mac.dart create mode 100644 pointycastle/lib/src/api/padded_block_cipher.dart create mode 100644 pointycastle/lib/src/api/padded_block_cipher_parameters.dart create mode 100644 pointycastle/lib/src/api/padding.dart create mode 100644 pointycastle/lib/src/api/parameters_with_iv.dart create mode 100644 pointycastle/lib/src/api/parameters_with_random.dart create mode 100644 pointycastle/lib/src/api/parameters_with_salt.dart create mode 100644 pointycastle/lib/src/api/parameters_with_salt_configuration.dart create mode 100644 pointycastle/lib/src/api/pbe_parameters_generator.dart create mode 100644 pointycastle/lib/src/api/private_key.dart create mode 100644 pointycastle/lib/src/api/private_key_parameter.dart create mode 100644 pointycastle/lib/src/api/public_key.dart create mode 100644 pointycastle/lib/src/api/public_key_parameter.dart create mode 100644 pointycastle/lib/src/api/rc2_parameters.dart create mode 100644 pointycastle/lib/src/api/registry_factory_exception.dart create mode 100644 pointycastle/lib/src/api/secure_random.dart create mode 100644 pointycastle/lib/src/api/signature.dart create mode 100644 pointycastle/lib/src/api/signer.dart create mode 100644 pointycastle/lib/src/api/srp_client.dart create mode 100644 pointycastle/lib/src/api/srp_server.dart create mode 100644 pointycastle/lib/src/api/stream_cipher.dart create mode 100644 pointycastle/lib/src/api/xof.dart create mode 100644 pointycastle/lib/src/ct.dart create mode 100644 pointycastle/lib/src/ec_standard_curve_constructor.dart create mode 100644 pointycastle/lib/src/impl/base_aead_block_cipher.dart create mode 100644 pointycastle/lib/src/impl/base_aead_cipher.dart create mode 100644 pointycastle/lib/src/impl/base_asymmetric_block_cipher.dart create mode 100644 pointycastle/lib/src/impl/base_block_cipher.dart create mode 100644 pointycastle/lib/src/impl/base_digest.dart create mode 100644 pointycastle/lib/src/impl/base_key_derivator.dart create mode 100644 pointycastle/lib/src/impl/base_mac.dart create mode 100644 pointycastle/lib/src/impl/base_padding.dart create mode 100644 pointycastle/lib/src/impl/base_stream_cipher.dart create mode 100644 pointycastle/lib/src/impl/entropy.dart create mode 100644 pointycastle/lib/src/impl/keccak_engine.dart create mode 100644 pointycastle/lib/src/impl/long_sha2_family_digest.dart create mode 100644 pointycastle/lib/src/impl/md4_family_digest.dart create mode 100644 pointycastle/lib/src/impl/secure_random_base.dart create mode 100644 pointycastle/lib/src/platform_check/abstract.dart create mode 100644 pointycastle/lib/src/platform_check/native.dart create mode 100644 pointycastle/lib/src/platform_check/node_crypto.dart create mode 100644 pointycastle/lib/src/platform_check/platform_check.dart create mode 100644 pointycastle/lib/src/platform_check/web.dart create mode 100644 pointycastle/lib/src/registration.dart create mode 100644 pointycastle/lib/src/registry/registration.dart create mode 100644 pointycastle/lib/src/registry/registry.dart create mode 100644 pointycastle/lib/src/ufixnum.dart create mode 100644 pointycastle/lib/src/utils.dart create mode 100644 pointycastle/lib/srp/srp6_client.dart create mode 100644 pointycastle/lib/srp/srp6_server.dart create mode 100644 pointycastle/lib/srp/srp6_standard_groups.dart create mode 100644 pointycastle/lib/srp/srp6_util.dart create mode 100644 pointycastle/lib/srp/srp6_verifier_generator.dart create mode 100644 pointycastle/lib/stream/chacha20.dart create mode 100644 pointycastle/lib/stream/chacha20poly1305.dart create mode 100644 pointycastle/lib/stream/chacha7539.dart create mode 100644 pointycastle/lib/stream/ctr.dart create mode 100644 pointycastle/lib/stream/eax.dart create mode 100644 pointycastle/lib/stream/rc4_engine.dart create mode 100644 pointycastle/lib/stream/salsa20.dart create mode 100644 pointycastle/lib/stream/sic.dart create mode 100644 pointycastle/pubspec.yaml create mode 100644 pointycastle/test/adapters/stream_cipher_as_block_cipher_test.dart create mode 100644 pointycastle/test/asn1/asn1_all_test-disabled.dart create mode 100644 pointycastle/test/asn1/asn1_dump_test.dart create mode 100644 pointycastle/test/asn1/asn1_object_test.dart create mode 100644 pointycastle/test/asn1/asn1_parser_test.dart create mode 100644 pointycastle/test/asn1/asn1_utils_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_bit_string_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_bmp_string_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_boolean_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_enumerated_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_generalized_time_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_ia5_string_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_integer_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_null_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_object_identifier_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_octet_string_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_printable_string_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_sequence_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_set_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_teletext_string_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_utc_time_test.dart create mode 100644 pointycastle/test/asn1/primitives/asn1_utf8_string_test.dart create mode 100644 pointycastle/test/asymmetric/ec_elgamal_test.dart create mode 100644 pointycastle/test/asymmetric/oaep_test.dart create mode 100644 pointycastle/test/asymmetric/pkcs1_test.dart create mode 100644 pointycastle/test/asymmetric/rsa_test.dart create mode 100644 pointycastle/test/block/aes_fast_test.dart create mode 100644 pointycastle/test/block/aes_test.dart create mode 100644 pointycastle/test/block/blowfish_test.dart create mode 100644 pointycastle/test/block/camellia_test.dart create mode 100644 pointycastle/test/block/desede_engine_test.dart create mode 100644 pointycastle/test/block/rc2_engine_test.dart create mode 100644 pointycastle/test/block/twofish_test.dart create mode 100644 pointycastle/test/digests/blake2b_test.dart create mode 100644 pointycastle/test/digests/cshake_test.dart create mode 100644 pointycastle/test/digests/keccak_test.dart create mode 100644 pointycastle/test/digests/md2_test.dart create mode 100644 pointycastle/test/digests/md4_test.dart create mode 100644 pointycastle/test/digests/md5_test.dart create mode 100644 pointycastle/test/digests/ripemd128_test.dart create mode 100644 pointycastle/test/digests/ripemd160_test.dart create mode 100644 pointycastle/test/digests/ripemd256_test.dart create mode 100644 pointycastle/test/digests/ripemd320_test.dart create mode 100644 pointycastle/test/digests/sha1_test.dart create mode 100644 pointycastle/test/digests/sha224_test.dart create mode 100644 pointycastle/test/digests/sha256_test.dart create mode 100644 pointycastle/test/digests/sha384_test.dart create mode 100644 pointycastle/test/digests/sha3_test.dart create mode 100644 pointycastle/test/digests/sha512_test.dart create mode 100644 pointycastle/test/digests/sha512t_test.dart create mode 100644 pointycastle/test/digests/shake_test.dart create mode 100644 pointycastle/test/digests/sm3_test.dart create mode 100644 pointycastle/test/digests/tiger_test.dart create mode 100644 pointycastle/test/digests/whirlpool_test.dart create mode 100644 pointycastle/test/ecc/curves_test.dart create mode 100644 pointycastle/test/ecc/ecdh_test.dart create mode 100644 pointycastle/test/impl_test.dart create mode 100644 pointycastle/test/key_derivators/argon2_nonvm_test.dart create mode 100644 pointycastle/test/key_derivators/argon2_vm_test.dart create mode 100644 pointycastle/test/key_derivators/concatkdf_nonvm_test.dart create mode 100644 pointycastle/test/key_derivators/concatkdf_test.dart create mode 100644 pointycastle/test/key_derivators/hkdf_test.dart create mode 100644 pointycastle/test/key_derivators/pbkdf2_test.dart create mode 100644 pointycastle/test/key_derivators/pkcs12_parameter_generator_test.dart create mode 100644 pointycastle/test/key_derivators/scrypt_nonvm_test.dart create mode 100644 pointycastle/test/key_derivators/scrypt_vm_test.dart create mode 100644 pointycastle/test/key_generators/ec_key_generator_test.dart create mode 100644 pointycastle/test/key_generators/rsa_key_generator_test.dart create mode 100644 pointycastle/test/macs/cbc_block_cipher_mac_test.dart create mode 100644 pointycastle/test/macs/cmac_test.dart create mode 100644 pointycastle/test/macs/hmac_test.dart create mode 100644 pointycastle/test/macs/poly1305_test.dart create mode 100644 pointycastle/test/macs/poly1305_web_test.dart create mode 100644 pointycastle/test/modes/cbc_test.dart create mode 100644 pointycastle/test/modes/ccm_test.dart create mode 100644 pointycastle/test/modes/cfb_test.dart create mode 100644 pointycastle/test/modes/ecb_test.dart create mode 100644 pointycastle/test/modes/gcm_test.dart create mode 100644 pointycastle/test/modes/gctr_test.dart create mode 100644 pointycastle/test/modes/ige_test.dart create mode 100644 pointycastle/test/modes/ofb_test.dart create mode 100644 pointycastle/test/modes/sic_test.dart create mode 100644 pointycastle/test/paddings/iso7816d4_test.dart create mode 100644 pointycastle/test/paddings/padded_block_cipher_test.dart create mode 100644 pointycastle/test/paddings/pkcs7_test.dart create mode 100644 pointycastle/test/platform/platform_native_test.dart create mode 100644 pointycastle/test/platform/platform_web_test.dart create mode 100644 pointycastle/test/random/auto_seed_block_ctr_random_test.dart create mode 100644 pointycastle/test/random/block_ctr_random_test.dart create mode 100644 pointycastle/test/random/fixed_rng_test.dart create mode 100644 pointycastle/test/random/fortuna_random_test.dart create mode 100644 pointycastle/test/signers/ecdsa_signer_test.dart create mode 100644 pointycastle/test/signers/ecdsa_vec.dart create mode 100644 pointycastle/test/signers/ecdsa_vector_vm_test.dart create mode 100644 pointycastle/test/signers/pss_signer_test.dart create mode 100644 pointycastle/test/signers/rsa_signer_test.dart create mode 100644 pointycastle/test/src/ct_nonvm_test.dart create mode 100644 pointycastle/test/src/ct_test.dart create mode 100644 pointycastle/test/src/ufixnum_test.dart create mode 100644 pointycastle/test/src/utils_test.dart create mode 100644 pointycastle/test/srp/srp_test.dart create mode 100644 pointycastle/test/stream/chacha20_test.dart create mode 100644 pointycastle/test/stream/chacha20poly1305_test.dart create mode 100644 pointycastle/test/stream/eax_test.dart create mode 100644 pointycastle/test/stream/rc4_engine_test.dart create mode 100644 pointycastle/test/stream/salsa20_test.dart create mode 100644 pointycastle/test/test/runners/asymmetric_block_cipher.dart create mode 100644 pointycastle/test/test/runners/block_cipher.dart create mode 100644 pointycastle/test/test/runners/digest.dart create mode 100644 pointycastle/test/test/runners/key_derivators.dart create mode 100644 pointycastle/test/test/runners/key_generators.dart create mode 100644 pointycastle/test/test/runners/mac.dart create mode 100644 pointycastle/test/test/runners/padding.dart create mode 100644 pointycastle/test/test/runners/registry.dart create mode 100644 pointycastle/test/test/runners/signer.dart create mode 100644 pointycastle/test/test/runners/stream_cipher.dart create mode 100644 pointycastle/test/test/src/fixed_secure_random.dart create mode 100644 pointycastle/test/test/src/helpers.dart create mode 100644 pointycastle/test/test/src/null_asymmetric_block_cipher.dart create mode 100644 pointycastle/test/test/src/null_block_cipher.dart create mode 100644 pointycastle/test/test/src/null_digest.dart create mode 100644 pointycastle/test/test/src/null_secure_random.dart create mode 100644 pointycastle/test/test/src/null_stream_cipher.dart create mode 100644 pointycastle/test/test_resources/kdf-56c/KDA.req.json create mode 100644 pointycastle/test/test_resources/kdf-56c/KDA.rsp.json create mode 100644 pubspec.yaml create mode 100644 qr_dart/LICENSE create mode 100644 qr_dart/lib/qr.dart create mode 100644 qr_dart/lib/src/bit_buffer.dart create mode 100644 qr_dart/lib/src/byte.dart create mode 100644 qr_dart/lib/src/error_correct_level.dart create mode 100644 qr_dart/lib/src/input_too_long_exception.dart create mode 100644 qr_dart/lib/src/mask_pattern.dart create mode 100644 qr_dart/lib/src/math.dart create mode 100644 qr_dart/lib/src/mode.dart create mode 100644 qr_dart/lib/src/polynomial.dart create mode 100644 qr_dart/lib/src/qr_code.dart create mode 100644 qr_dart/lib/src/qr_image.dart create mode 100644 qr_dart/lib/src/readme.md create mode 100644 qr_dart/lib/src/rs_block.dart create mode 100644 qr_dart/lib/src/util.dart create mode 100644 qr_dart/pubspec.yaml create mode 100644 qr_dart/test/qr_alphanumeric_test.dart create mode 100644 qr_dart/test/qr_bit_buffer_test.dart create mode 100644 qr_dart/test/qr_byte_test.dart create mode 100644 qr_dart/test/qr_code_test.dart create mode 100644 qr_dart/test/qr_code_test_data.dart create mode 100644 qr_dart/test/qr_code_test_data_with_mask.dart create mode 100644 qr_dart/test/qr_numeric_test.dart create mode 100644 update.py create mode 100644 x25519/LICENSE create mode 100644 x25519/lib/src/curve25519.dart create mode 100644 x25519/lib/src/numbers.dart create mode 100644 x25519/lib/x25519.dart create mode 100644 x25519/pubspec.yaml create mode 100644 x25519/test/benchmark/curve25519_benchmark.dart create mode 100644 x25519/test/benchmark/rate_benchmark.dart create mode 100644 x25519/test/curve25519_test.dart create mode 100644 x25519/test/vectors_test.dart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b694934 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.venv \ No newline at end of file diff --git a/adaptive_number/LICENSE b/adaptive_number/LICENSE new file mode 100644 index 0000000..b0e8b7e --- /dev/null +++ b/adaptive_number/LICENSE @@ -0,0 +1,11 @@ +Copyright 2021 Philipp Sessler + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/adaptive_number/lib/adaptive_number.dart b/adaptive_number/lib/adaptive_number.dart new file mode 100644 index 0000000..6078d6a --- /dev/null +++ b/adaptive_number/lib/adaptive_number.dart @@ -0,0 +1,6 @@ +/// Support for doing something awesome. +/// +/// More dartdocs go here. +library adaptive_number; + +export 'src/number.dart'; diff --git a/adaptive_number/lib/src/int.dart b/adaptive_number/lib/src/int.dart new file mode 100644 index 0000000..9798828 --- /dev/null +++ b/adaptive_number/lib/src/int.dart @@ -0,0 +1,120 @@ +import 'package:adaptive_number/src/number.dart'; + +class NumberInt implements Number { + final int _value; + + NumberInt(this._value); + + @override + NumberInt operator +(Number value) { + return NumberInt(_value + (value.val as int)); + } + + @override + NumberInt operator -(Number value) { + return NumberInt(_value - (value.val as int)); + } + + @override + NumberInt operator -() { + return NumberInt(-(val)); + } + + @override + NumberInt operator *(Number value) { + return NumberInt(_value * (value.val as int)); + } + + @override + NumberInt operator &(Number value) { + return NumberInt(_value & (value.val as int)); + } + + @override + NumberInt operator >>(int value) { + return NumberInt(_value >> value); + } + + @override + NumberInt operator <<(int value) { + return NumberInt(_value << value); + } + + @override + NumberInt operator ^(Number value) { + return NumberInt(_value ^ (value.val as int)); + } + + @override + NumberInt operator |(Number value) { + return NumberInt(_value | (value.val as int)); + } + + @override + bool operator <(Number value) { + return (intValue < value.intValue); + } + + @override + bool operator <=(Number value) { + return (intValue <= value.intValue); + } + + @override + bool operator >(Number value) { + return (intValue > value.intValue); + } + + @override + bool operator >=(Number value) { + return (intValue >= value.intValue); + } + + @override + NumberInt operator %(Number value) { + return NumberInt(_value % (value.val as int)); + } + + @override + Number operator ~/(Number value) { + return NumberInt(_value ~/ (value.val as int)); + } + + @override + int get val => _value; + + @override + int get intValue => _value; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is NumberInt && + runtimeType == other.runtimeType && + _value == other._value; + + @override + int get hashCode => _value.hashCode; + + @override + String toString() { + return _value.toString(); + } + + @override + String toRadixString(int radix) { + return _value.toRadixString(radix); + } + + @override + NumberInt abs() { + return NumberInt(_value.abs()); + } + + @override + int compareTo(Number other) { + return _value.compareTo(other.intValue); + } +} + +Number createNumber(int val) => NumberInt(val); diff --git a/adaptive_number/lib/src/int64.dart b/adaptive_number/lib/src/int64.dart new file mode 100644 index 0000000..39b39e3 --- /dev/null +++ b/adaptive_number/lib/src/int64.dart @@ -0,0 +1,121 @@ +import 'package:adaptive_number/src/number.dart'; +import 'package:fixnum/fixnum.dart'; + +class NumberInt64 implements Number { + final Int64 _value; + + NumberInt64(this._value); + + @override + NumberInt64 operator +(Number value) { + return NumberInt64(_value + (value.val as Int64)); + } + + @override + NumberInt64 operator -(Number value) { + return NumberInt64(_value - (value.val as Int64)); + } + + @override + NumberInt64 operator -() { + return NumberInt64(-(val)); + } + + @override + NumberInt64 operator *(Number value) { + return NumberInt64(_value * (value.val as Int64)); + } + + @override + NumberInt64 operator &(Number value) { + return NumberInt64(_value & (value.val as Int64)); + } + + @override + NumberInt64 operator >>(int value) { + return NumberInt64(_value >> value); + } + + @override + NumberInt64 operator <<(int value) { + return NumberInt64(_value << value); + } + + @override + NumberInt64 operator ^(Number value) { + return NumberInt64(_value ^ (value.val as Int64)); + } + + @override + NumberInt64 operator |(Number value) { + return NumberInt64(_value | (value.val as Int64)); + } + + @override + bool operator <(Number value) { + return (intValue < value.intValue); + } + + @override + bool operator <=(Number value) { + return (intValue <= value.intValue); + } + + @override + bool operator >(Number value) { + return (intValue > value.intValue); + } + + @override + bool operator >=(Number value) { + return (intValue >= value.intValue); + } + + @override + NumberInt64 operator %(Number value) { + return NumberInt64(_value % (value.val as Int64)); + } + + @override + Number operator ~/(Number value) { + return NumberInt64(_value ~/ (value.val as Int64)); + } + + @override + Int64 get val => _value; + + @override + int get intValue => _value.toInt(); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is NumberInt64 && + runtimeType == other.runtimeType && + _value == other._value; + + @override + int get hashCode => _value.hashCode; + + @override + String toString() { + return _value.toString(); + } + + @override + String toRadixString(int radix) { + return _value.toRadixString(radix); + } + + @override + NumberInt64 abs() { + return NumberInt64(_value.abs()); + } + + @override + int compareTo(Number value) { + return _value.compareTo(value.val as Int64); + } +} + +Number createNumber(int val) => NumberInt64(Int64(val)); diff --git a/adaptive_number/lib/src/number.dart b/adaptive_number/lib/src/number.dart new file mode 100644 index 0000000..df64950 --- /dev/null +++ b/adaptive_number/lib/src/number.dart @@ -0,0 +1,78 @@ +import 'package:adaptive_number/src/stub.dart' +// ignore: uri_does_not_exist + if (dart.library.io) 'package:adaptive_number/src/int.dart' +// ignore: uri_does_not_exist + if (dart.library.html) 'package:adaptive_number/src/int64.dart'; + +abstract class Number { + static Number zero = Number(0); + static Number one = Number(1); + static Number two = Number(2); + + factory Number(int val) => createNumber(val); + + dynamic get val; + + /// Returns the value as int (caution: May overflow on JS runtimes) + int get intValue; + + @override + int get hashCode; + + /// Addition operator. + Number operator +(Number value); + + /// Subtraction operator. + Number operator -(Number value); + + /// Negate operator. + Number operator -(); + + /// Multiplication operator. + Number operator *(Number value); + + /// Bitwise and operator. + Number operator &(Number value); + + /// Right bit-shift operator. + Number operator >>(int value); + + /// Left bit-shift operator. + Number operator <<(int value); + + /// Bitwise xor operator. + Number operator ^(Number value); + + /// Bitwise or operator. + Number operator |(Number value); + + /// Relational less than operator. + bool operator <(Number value); + + /// Relational less than or equal to operator. + bool operator <=(Number value); + + /// Relational greater than operator. + bool operator >(Number value); + + /// Relational greater than or equal to operator. + bool operator >=(Number value); + + /// Euclidean modulo operator. + Number operator %(Number value); + + /// Truncating division operator. + Number operator ~/(Number value); + + @override + String toString(); + + /// Returns a string representing the value of this integer in the given radix. + String toRadixString(int radix); + + /// Returns the absolute value of this integer. + Number abs(); + + // Compares this to `other` + int compareTo(Number other); +} diff --git a/adaptive_number/lib/src/stub.dart b/adaptive_number/lib/src/stub.dart new file mode 100644 index 0000000..1e4ce05 --- /dev/null +++ b/adaptive_number/lib/src/stub.dart @@ -0,0 +1,4 @@ +import 'package:adaptive_number/src/number.dart'; + +Number createNumber(int val) => throw UnsupportedError( + 'Cannot create a Number without package dart.library.io or dart.library.html being available'); diff --git a/adaptive_number/pubspec.yaml b/adaptive_number/pubspec.yaml new file mode 100644 index 0000000..a408604 --- /dev/null +++ b/adaptive_number/pubspec.yaml @@ -0,0 +1,17 @@ +name: adaptive_number +version: 1.0.0 + +description: >- + Library providing an adaptive number implementation. On JS runtimes, a 64-bit signed fixed-width integer will be used and + for all other platforms the default Dart int data type. +homepage: https://github.com/lemoony/adaptive_number_dart + +environment: + sdk: '>=2.12.0 <3.0.0' + +dependencies: + fixnum: ^1.0.0 + +dev_dependencies: + pedantic: ^1.10.0 + test: ^1.16.0 diff --git a/adaptive_number/test/adaptive_number_test.dart b/adaptive_number/test/adaptive_number_test.dart new file mode 100644 index 0000000..52931d7 --- /dev/null +++ b/adaptive_number/test/adaptive_number_test.dart @@ -0,0 +1,128 @@ +import 'package:adaptive_number/adaptive_number.dart'; +import 'package:test/test.dart'; + +// Since both implementations of Number only forward most method call, +// tests are kept minimal and should mainly concentrate on verifying that no +// wrong operator and/or method is being called because of a mix up +void main() { + group('utility functions', () { + test('retrieve value as int', () { + expect(Number.zero.intValue, 0); + expect(Number.one.intValue, 1); + expect(Number.two.intValue, 2); + expect(Number(42).intValue, 42); + }); + }); + + group('other overwrites', () { + test('hash code', () { + expect(Number.zero.hashCode, 0.hashCode); + expect(Number.one.hashCode, 1.hashCode); + expect(Number.two.hashCode, 2.hashCode); + expect(Number(42).hashCode, 42); + }); + + test('to string', () { + expect(Number.one.toString(), '1'); + expect((-Number.one).toString(), '-1'); + }); + + test('toRadixString', () { + expect(Number(42).toRadixString(2), '101010'); + }); + + test('abs', () { + expect(Number(-42).abs(), Number(42)); + }); + + test('compare to', () { + expect(Number.one.compareTo(Number.two), -1); + expect(Number.two.compareTo(Number.one), 1); + expect(Number.one.compareTo(Number.one), 0); + }); + }); + + group('operator tests', () { + test('add', () { + expect(Number.one + Number.two, Number(3)); + }); + + test('subtract', () { + expect(Number.two - Number.one, Number.one); + }); + + test('invert', () { + expect((-Number.one).intValue, -1); + expect((-Number.zero).intValue, 0); + }); + + test('multiply', () { + expect(Number.two * Number(3), Number(6)); + }); + + test('& bitwise and', () { + expect(Number(1234) & Number(9876), Number(1168)); + expect(Number(-1234) & Number(9876), Number(8708)); + }); + + test('>> bitwise shift right', () { + expect(Number(23423) >> 8, Number(91)); + expect(Number(-87653) >> 12, Number(-22)); + }); + + test('<< bitwise shift left', () { + expect(Number(23423) << 8, Number(5996288)); + expect(Number(-87653) << 12, Number(-359026688)); + }); + + test('^ bitwise xor', () { + expect(Number(1234) ^ Number(9876), Number(8774)); + }); + + test('| bitwise or', () { + expect(Number(1234) | Number(9876), Number(9942)); + expect(Number(-1234) | Number(9876), Number(-66)); + }); + + test('< less than', () { + expect(Number.one < Number.two, isTrue); + expect(Number.two < Number.one, isFalse); + }); + + test('< less than or equal', () { + expect(Number.two <= Number.one, isFalse); + expect(Number.one <= Number.two, isTrue); + expect(Number.two <= Number.two, isTrue); + }); + + test('< greater than', () { + expect(Number.two > Number.one, isTrue); + expect(Number.one > Number.two, isFalse); + }); + + test('< greater than or equal', () { + expect(Number.two >= Number.one, isTrue); + expect(Number.one >= Number.two, isFalse); + expect(Number.two >= Number.two, isTrue); + }); + + test('modulo', () { + expect(Number.two % Number.one, Number.zero); + expect(Number(3) % Number.one, Number.zero); + expect(Number.one % Number.two, Number.one); + }); + + test('truncating division', () { + expect(Number(1000) ~/ Number(-3), Number(-333)); + }); + + test('equals', () { + expect(Number(0) == Number.zero, isTrue); + expect(Number(1) == Number.one, isTrue); + expect(Number(2) == Number.two, isTrue); + + expect(Number(1) == Number.zero, isFalse); + expect(Number.one == Number.zero, isFalse); + }); + }); +} diff --git a/config.lock.yaml b/config.lock.yaml new file mode 100644 index 0000000..f35cbdb --- /dev/null +++ b/config.lock.yaml @@ -0,0 +1,14 @@ +adaptive_number: ea9178fdd4d82ac45cf0ec966ac870dae661124f +dots_indicator: 508f5883ac79bdbc10254092de3f28f571d261cd +ed25519_edwards: 7353ba759ea9f4646cbf481c2ef949625c8ce4cf +hashlib: 983cdbd5ee2529b908876b57a7217c09c6bc148a +hashlib_codecs: 2a966c37c3b9b1f5541ae88e99ab34acf3fc968b +introduction_screen: 4a90e557630b28834479ed9c64a9d2d0185d8e48 +libsignal_protocol_dart: 618f0c0b49534245a640a31d204265440cbac9ee +lottie: 4f1a5a52bdf1e1c1e12fa97c96174dcb05419e19 +mutex: 84ca903a3ac863735e3228c75a212133621f680f +optional: 71c638891ce4f2aff35c7387727989f31f9d877d +photo_view: a13ca2fc387a3fb1276126959e092c44d0029987 +pointycastle: bbd8569f68a7fccbdf0b92d0b44a9219c126c8dd +qr_dart: ff808bb3f354e6a7029ec953cbe0144a42021db6 +x25519: ecb1d357714537bba6e276ef45f093846d4beaee diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..6e10d40 --- /dev/null +++ b/config.yaml @@ -0,0 +1,42 @@ +qr_dart: + git: https://github.com/kevmoo/qr.dart.git + +mutex: + git: https://github.com/hoylen/dart-mutex.git + +photo_view: + git: https://github.com/bluefireteam/photo_view.git + +introduction_screen: + git: https://github.com/Pyozer/introduction_screen.git + +dots_indicator: + git: https://github.com/Pyozer/dots_indicator.git + +hashlib: + git: https://github.com/bitanon/hashlib.git + replace: + - + - "abstract class MACHashBase" + - "abstract mixin class MACHashBase" + dependencies: + hashlib_codecs: + git: https://github.com/bitanon/hashlib_codecs.git + +lottie: + git: https://github.com/xvrh/lottie-flutter.git + + +libsignal_protocol_dart: + git: https://github.com/MixinNetwork/libsignal_protocol_dart.git + dependencies: + adaptive_number: + git: https://github.com/lemoony/adaptive_number_dart + ed25519_edwards: + git: https://github.com/Tougee/ed25519.git + optional: + git: https://github.com/tonio-ramirez/optional.dart.git + pointycastle: + git: https://github.com/bcgit/pc-dart.git + x25519: + git: https://github.com/Tougee/curve25519.git diff --git a/dots_indicator/LICENSE b/dots_indicator/LICENSE new file mode 100644 index 0000000..d195f29 --- /dev/null +++ b/dots_indicator/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Jean-Charles Moussé + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/dots_indicator/lib/dots_indicator.dart b/dots_indicator/lib/dots_indicator.dart new file mode 100644 index 0000000..9d8f13a --- /dev/null +++ b/dots_indicator/lib/dots_indicator.dart @@ -0,0 +1,4 @@ +library dots_indicator; + +export 'src/dots_indicator.dart' show DotsIndicator; +export 'src/dots_decorator.dart' show DotsDecorator; diff --git a/dots_indicator/lib/src/dots_decorator.dart b/dots_indicator/lib/src/dots_decorator.dart new file mode 100644 index 0000000..98d394d --- /dev/null +++ b/dots_indicator/lib/src/dots_decorator.dart @@ -0,0 +1,156 @@ +import 'package:flutter/material.dart'; + +const Size kDefaultSize = Size.square(9.0); +const Size kDefaultFadeOutSize = Size.square(6.0); +const EdgeInsets kDefaultSpacing = EdgeInsets.all(6.0); +const ShapeBorder kDefaultShape = CircleBorder(); + +class DotsDecorator { + /// Inactive dot color + /// + /// @Default `Colors.grey` + final Color color; + + /// List of inactive dot colors + /// One color by dot + /// + /// @Default `Value of color parameter applied to each dot` + final List colors; + + /// Active dot color + /// + /// @Default `Theme.of(context).primaryColor` + final Color? activeColor; + + /// List of active dot colors + /// One color by dot + /// + /// @Default `Value of activeColor parameter applied to each dot` + final List activeColors; + + /// Inactive dot size + /// + /// @Default `Size.square(9.0)` + final Size size; + + /// List of inactive dot size + /// One size by dot + /// + /// @Default `Value of size parameter applied to each dot` + final List sizes; + + /// Fade out dot size + /// + /// @Default `Size.square(6.0)` + final Size fadeOutSize; + + /// List of fade out dot size + /// One size by dot + /// + /// @Default `Value of activeSize parameter applied to each dot` + final List fadeOutSizes; + + /// Active dot size + /// + /// @Default `Size.square(9.0)` + final Size activeSize; + + /// List of active dot size + /// One size by dot + /// + /// @Default `Value of activeSize parameter applied to each dot` + final List activeSizes; + + /// Inactive dot shape + /// + /// @Default `CircleBorder()` + final ShapeBorder shape; + + /// List of inactive dot shape + /// One shape by dot + /// + /// @Default `Value of shape parameter applied to each dot` + final List shapes; + + /// Active dot shape + /// + /// @Default `CircleBorder()` + final ShapeBorder activeShape; + + /// List of active dot shapes + /// One shape by dot + /// + /// @Default `Value of activeShape parameter applied to each dot` + final List activeShapes; + + /// Spacing between dots + /// + /// @Default `EdgeInsets.all(6.0)` + final EdgeInsets spacing; + + /// Shadows of the dots + /// + /// @Default `null` + final List? shadows; + + /// Shadows of the active dots + /// + /// @Default `shadows` or `null` + final List? activeShadows; + + const DotsDecorator({ + this.color = Colors.grey, + this.colors = const [], + this.activeColor, + this.activeColors = const [], + this.size = kDefaultSize, + this.sizes = const [], + this.fadeOutSize = kDefaultFadeOutSize, + this.fadeOutSizes = const [], + this.activeSize = kDefaultSize, + this.activeSizes = const [], + this.shape = kDefaultShape, + this.shapes = const [], + this.activeShape = kDefaultShape, + this.activeShapes = const [], + this.spacing = kDefaultSpacing, + this.shadows, + this.activeShadows, + }); + + Color? getActiveColor(int index) { + return activeColors.isNotEmpty ? activeColors[index] : activeColor; + } + + Color getColor(int index) { + return colors.isNotEmpty ? colors[index] : color; + } + + Size getFadeOutSize(int index) { + return fadeOutSizes.isNotEmpty ? fadeOutSizes[index] : fadeOutSize; + } + + Size getActiveSize(int index) { + return activeSizes.isNotEmpty ? activeSizes[index] : activeSize; + } + + Size getSize(int index) { + return sizes.isNotEmpty ? sizes[index] : size; + } + + ShapeBorder getActiveShape(int index) { + return activeShapes.isNotEmpty ? activeShapes[index] : activeShape; + } + + ShapeBorder getShape(int index) { + return shapes.isNotEmpty ? shapes[index] : shape; + } + + List? getShadows(int index) { + return shadows; + } + + List? getActiveShadows(int index) { + return activeShadows ?? shadows; + } +} diff --git a/dots_indicator/lib/src/dots_indicator.dart b/dots_indicator/lib/src/dots_indicator.dart new file mode 100644 index 0000000..aa35b1a --- /dev/null +++ b/dots_indicator/lib/src/dots_indicator.dart @@ -0,0 +1,187 @@ +library dots_indicator; + +import 'dart:math'; + +import 'package:dots_indicator/src/dots_decorator.dart'; +import 'package:flutter/material.dart'; + +typedef OnTap = void Function(int position); + +class DotsIndicator extends StatelessWidget { + final int dotsCount; + final double position; + + /// If true, the last dot will fade out when the position is at the last dot. + final bool fadeOutLastDot; + + /// Distance from currently selected dot to the one that fades out. + final int fadeOutDistance; + final DotsDecorator decorator; + final Axis axis; + final bool reversed; + final OnTap? onTap; + final MainAxisSize mainAxisSize; + final MainAxisAlignment mainAxisAlignment; + + /// If true, the dots will animate when the position changes. + final bool animate; + + /// Duration of the animation when the position changes. + final Duration animationDuration; + + DotsIndicator({ + super.key, + required this.dotsCount, + this.position = 0.0, + this.decorator = const DotsDecorator(), + this.axis = Axis.horizontal, + this.reversed = false, + this.mainAxisSize = MainAxisSize.min, + this.mainAxisAlignment = MainAxisAlignment.center, + this.onTap, + this.fadeOutLastDot = false, + this.fadeOutDistance = 0, + this.animate = false, + this.animationDuration = const Duration(milliseconds: 200), + }) : assert(dotsCount > 0, 'dotsCount must be superior to zero'), + assert(position >= 0.0, 'position must be superior or equals to zero'), + assert( + position < dotsCount, + "position must be less than dotsCount", + ), + assert( + decorator.colors.isEmpty || decorator.colors.length == dotsCount, + "colors param in decorator must empty or have same length as dotsCount parameter", + ), + assert( + decorator.activeColors.isEmpty || + decorator.activeColors.length == dotsCount, + "activeColors param in decorator must empty or have same length as dotsCount parameter", + ), + assert( + decorator.sizes.isEmpty || decorator.sizes.length == dotsCount, + "sizes param in decorator must empty or have same length as dotsCount parameter", + ), + assert( + decorator.activeSizes.isEmpty || + decorator.activeSizes.length == dotsCount, + "activeSizes param in decorator must empty or have same length as dotsCount parameter", + ), + assert( + decorator.shapes.isEmpty || decorator.shapes.length == dotsCount, + "shapes param in decorator must empty or have same length as dotsCount parameter", + ), + assert( + decorator.activeShapes.isEmpty || + decorator.activeShapes.length == dotsCount, + "activeShapes param in decorator must empty or have same length as dotsCount parameter", + ), + assert( + fadeOutLastDot == false || fadeOutDistance > 0, + "fadeOutDistace must be superior to zero when fadeOutLastDot is true", + ), + assert( + fadeOutDistance < dotsCount, + "fadeOutDistace must be inferior to dotsCount", + ); + + Widget _wrapInkwell(Widget dot, int index) { + return InkWell( + customBorder: position == index + ? decorator.getActiveShape(index) + : decorator.getShape(index), + onTap: () => onTap!(index), + child: dot, + ); + } + + Widget _buildDot(BuildContext context, int index) { + final double absPositionIndexRelation = (position - index).abs(); + final bool isCurrentlyVisible = absPositionIndexRelation <= fadeOutDistance; + + final double lerpValue = min(1.0, absPositionIndexRelation).toDouble(); + + Size size = Size.lerp( + decorator.getActiveSize(index), + decorator.getSize(index), + lerpValue, + )!; + + if (fadeOutLastDot && absPositionIndexRelation >= fadeOutDistance) { + size = Size.lerp( + decorator.getSize(index), + decorator.getFadeOutSize(index), + absPositionIndexRelation == fadeOutDistance ? 1 : 0.0, + )!; + } + + final dot = Container( + height: fadeOutLastDot && isCurrentlyVisible + ? max( + max(decorator.getActiveSize(index).height, + decorator.getSize(index).height), + decorator.getFadeOutSize(index).height, + ) + + (axis == Axis.horizontal + ? decorator.spacing.vertical + : decorator.spacing.horizontal) + : null, + child: Center( + child: AnimatedOpacity( + duration: animate ? animationDuration : Duration.zero, + opacity: + !fadeOutLastDot || absPositionIndexRelation <= fadeOutDistance + ? 1.0 + : 0.0, + child: AnimatedContainer( + duration: animate ? animationDuration : Duration.zero, + width: size.width, + height: size.height, + margin: fadeOutLastDot && !isCurrentlyVisible + ? EdgeInsets.all(0) + : decorator.spacing, + decoration: ShapeDecoration( + color: Color.lerp( + decorator.getActiveColor(index) ?? Theme.of(context).primaryColor, + decorator.getColor(index), + lerpValue, + ), + shape: ShapeBorder.lerp( + decorator.getActiveShape(index), + decorator.getShape(index), + lerpValue, + )!, + shadows: BoxShadow.lerpList( + decorator.getActiveShadows(index), + decorator.getShadows(index), + lerpValue, + ), + ), + ), + ), + ), + ); + return onTap == null ? dot : _wrapInkwell(dot, index); + } + + @override + Widget build(BuildContext context) { + final dotsList = List.generate( + dotsCount, + (i) => _buildDot(context, i), + ); + final dots = reversed ? dotsList.reversed.toList() : dotsList; + + return axis == Axis.vertical + ? Column( + mainAxisAlignment: mainAxisAlignment, + mainAxisSize: mainAxisSize, + children: dots, + ) + : Row( + mainAxisAlignment: mainAxisAlignment, + mainAxisSize: mainAxisSize, + children: dots, + ); + } +} diff --git a/dots_indicator/pubspec.yaml b/dots_indicator/pubspec.yaml new file mode 100644 index 0000000..e195e28 --- /dev/null +++ b/dots_indicator/pubspec.yaml @@ -0,0 +1,14 @@ +name: dots_indicator +description: Dots indicator to show progression of a PageView for example +version: 4.0.1 +homepage: https://github.com/pyozer/dots_indicator + +environment: + sdk: '>=2.17.0 <4.0.0' + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_lints: ^5.0.0 diff --git a/ed25519_edwards/LICENSE b/ed25519_edwards/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/ed25519_edwards/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ed25519_edwards/lib/ed25519_edwards.dart b/ed25519_edwards/lib/ed25519_edwards.dart new file mode 100644 index 0000000..be808df --- /dev/null +++ b/ed25519_edwards/lib/ed25519_edwards.dart @@ -0,0 +1,204 @@ +/// Package ed25519 implements the Ed25519 signature algorithm. See +/// https://ed25519.cr.yp.to/. +/// +/// These functions are also compatible with the “Ed25519” function defined in +/// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +/// representation includes a public key suffix to make multiple signing +/// operations with the same key more efficient. This package refers to the RFC +/// 8032 private key as the “seed”. + +library edwards25519; + +import 'dart:typed_data'; +import 'package:convert/convert.dart'; +import 'package:collection/collection.dart'; +import 'package:crypto/crypto.dart'; +import 'package:ed25519_edwards/src/edwards25519.dart'; +import 'package:ed25519_edwards/src/util.dart'; + +/// PublicKeySize is the size, in bytes, of public keys as used in this package. +const PublicKeySize = 32; + +/// PrivateKeySize is the size, in bytes, of private keys as used in this package. +const PrivateKeySize = 64; + +/// SignatureSize is the size, in bytes, of signatures generated and verified by this package. +const SignatureSize = 64; + +/// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. +const SeedSize = 32; + +/// PublicKey is the type of Ed25519 public keys. +class PublicKey { + List bytes; + + PublicKey(this.bytes); +} + +/// PrivateKey is the type of Ed25519 private keys. +class PrivateKey { + List bytes; + + PrivateKey(this.bytes); +} + +/// KeyPair is the type of Ed25519 public/private key pair. +class KeyPair { + final PrivateKey privateKey; + + final PublicKey publicKey; + + KeyPair(this.privateKey, this.publicKey); + + @override + int get hashCode => publicKey.hashCode; + + @override + bool operator ==(other) => + other is KeyPair && + publicKey == other.publicKey && + privateKey == other.privateKey; +} + +/// public returns the PublicKey corresponding to PrivateKey. +PublicKey public(PrivateKey privateKey) { + var publicKey = privateKey.bytes.sublist(32, 32 + PublicKeySize); + return PublicKey(publicKey); +} + +/// Seed returns the private key seed corresponding to priv. It is provided for +/// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds +/// in this package. +Uint8List seed(PrivateKey privateKey) { + var seed = privateKey.bytes.sublist(0, SeedSize); + return seed as Uint8List; +} + +/// GenerateKey generates a public/private key pair using entropy from secure random. +KeyPair generateKey() { + var seed = Uint8List(32); + fillBytesWithSecureRandomNumbers(seed); + var privateKey = newKeyFromSeed(seed); + var publicKey = privateKey.bytes.sublist(32, PrivateKeySize); + return KeyPair(privateKey, PublicKey(publicKey)); +} + +/// NewKeyFromSeed calculates a private key from a seed. It will throw +/// ArgumentError if seed.length is not SeedSize. +/// This function is provided for interoperability with RFC 8032. +/// RFC 8032's private keys correspond to seeds in this package. +PrivateKey newKeyFromSeed(Uint8List seed) { + if (seed.length != SeedSize) { + throw ArgumentError('ed25519: bad seed length ${seed.length}'); + } + var h = sha512.convert(seed); + var digest = h.bytes.sublist(0, 32); + digest[0] &= 248; + digest[31] &= 127; + digest[31] |= 64; + + var A = ExtendedGroupElement(); + var hBytes = digest.sublist(0); + GeScalarMultBase(A, hBytes as Uint8List); + var publicKeyBytes = Uint8List(32); + A.ToBytes(publicKeyBytes); + + var privateKey = Uint8List(PrivateKeySize); + arrayCopy(seed, 0, privateKey, 0, 32); + arrayCopy(publicKeyBytes, 0, privateKey, 32, 32); + return PrivateKey(privateKey); +} + +/// Sign signs the message with privateKey and returns a signature. It will +/// throw ArumentError if privateKey.bytes.length is not PrivateKeySize. +Uint8List sign(PrivateKey privateKey, Uint8List message) { + if (privateKey.bytes.length != PrivateKeySize) { + throw ArgumentError( + 'ed25519: bad privateKey length ${privateKey.bytes.length}'); + } + var h = sha512.convert(privateKey.bytes.sublist(0, 32)); + var digest1 = h.bytes; + var expandedSecretKey = digest1.sublist(0, 32); + expandedSecretKey[0] &= 248; + expandedSecretKey[31] &= 63; + expandedSecretKey[31] |= 64; + + var output = AccumulatorSink(); + var input = sha512.startChunkedConversion(output); + input.add(digest1.sublist(32)); + input.add(message); + input.close(); + var messageDigest = output.events.single.bytes; + + var messageDigestReduced = Uint8List(32); + ScReduce(messageDigestReduced, messageDigest as Uint8List); + var R = ExtendedGroupElement(); + GeScalarMultBase(R, messageDigestReduced); + + var encodedR = Uint8List(32); + R.ToBytes(encodedR); + + output = AccumulatorSink(); + input = sha512.startChunkedConversion(output); + input.add(encodedR); + input.add(privateKey.bytes.sublist(32)); + input.add(message); + input.close(); + var hramDigest = output.events.single.bytes; + var hramDigestReduced = Uint8List(32); + ScReduce(hramDigestReduced, hramDigest as Uint8List); + + var s = Uint8List(32); + ScMulAdd(s, hramDigestReduced, expandedSecretKey as Uint8List, + messageDigestReduced); + + var signature = Uint8List(SignatureSize); + arrayCopy(encodedR, 0, signature, 0, 32); + arrayCopy(s, 0, signature, 32, 32); + + return signature; +} + +/// Verify reports whether sig is a valid signature of message by publicKey. It +/// will throw ArgumentError if publicKey.bytes.length is not PublicKeySize. +bool verify(PublicKey publicKey, Uint8List message, Uint8List sig) { + if (publicKey.bytes.length != PublicKeySize) { + throw ArgumentError( + 'ed25519: bad publicKey length ${publicKey.bytes.length}'); + } + if (sig.length != SignatureSize || sig[63] & 224 != 0) { + return false; + } + + var A = ExtendedGroupElement(); + var publicKeyBytes = Uint8List.fromList(publicKey.bytes); + if (!A.FromBytes(publicKeyBytes)) { + return false; + } + FeNeg(A.X, A.X); + FeNeg(A.T, A.T); + + var output = AccumulatorSink(); + var input = sha512.startChunkedConversion(output); + input.add(sig.sublist(0, 32)); + input.add(publicKeyBytes); + input.add(message); + input.close(); + var digest = output.events.single.bytes; + + var hReduced = Uint8List(32); + ScReduce(hReduced, digest as Uint8List); + + var R = ProjectiveGroupElement(); + var s = sig.sublist(32); + + if (!ScMinimal(s)) { + return false; + } + + GeDoubleScalarMultVartime(R, hReduced, A, s); + + var checkR = Uint8List(32); + R.ToBytes(checkR); + return ListEquality().equals(sig.sublist(0, 32), checkR); +} diff --git a/ed25519_edwards/lib/src/const.dart b/ed25519_edwards/lib/src/const.dart new file mode 100644 index 0000000..b8405d8 --- /dev/null +++ b/ed25519_edwards/lib/src/const.dart @@ -0,0 +1,10162 @@ +import 'edwards25519.dart'; + +var d = FieldElement.fromList([ + -10913610, + 13857413, + -15372611, + 6949391, + 114729, + -8787816, + -6275908, + -3247719, + -18696448, + -12055116, +]); + +/// d2 is 2*d. +var d2 = FieldElement.fromList([ + -21827239, + -5839606, + -30745221, + 13898782, + 229458, + 15978800, + -12551817, + -6495438, + 29715968, + 9444199, +]); + +/// SqrtM1 is the square-root of -1 in the field. +var SqrtM1 = FieldElement.fromList([ + -32595792, + -7943725, + 9377950, + 3500415, + 12389472, + -272473, + -25146209, + -2005654, + 326686, + 11406482, +]); + +/// A is a constant in the Montgomery-form of curve25519. +var A = FieldElement.fromList([ + 486662, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +]); + +/// bi contains precomputed multiples of the base-point. See the Ed25519 paper +/// for a discussion about how these values are used. +var bi = List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 25967493, + -14356035, + 29566456, + 3660896, + -12694345, + 4014787, + 27544626, + -11754271, + -6079156, + 2047605 + ]), + FieldElement.fromList([ + -12545711, + 934262, + -2722910, + 3049990, + -727428, + 9406986, + 12720692, + 5043384, + 19500929, + -15469378 + ]), + FieldElement.fromList([ + -8738181, + 4489570, + 9688441, + -14785194, + 10184609, + -12363380, + 29287919, + 11864899, + -24514362, + -4438546 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15636291, + -9688557, + 24204773, + -7912398, + 616977, + -16685262, + 27787600, + -14772189, + 28944400, + -1550024 + ]), + FieldElement.fromList([ + 16568933, + 4717097, + -11556148, + -1102322, + 15682896, + -11807043, + 16354577, + -11775962, + 7689662, + 11199574 + ]), + FieldElement.fromList([ + 30464156, + -5976125, + -11779434, + -15670865, + 23220365, + 15915852, + 7512774, + 10017326, + -17749093, + -9920357 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 10861363, + 11473154, + 27284546, + 1981175, + -30064349, + 12577861, + 32867885, + 14515107, + -15438304, + 10819380 + ]), + FieldElement.fromList([ + 4708026, + 6336745, + 20377586, + 9066809, + -11272109, + 6594696, + -25653668, + 12483688, + -12668491, + 5581306 + ]), + FieldElement.fromList([ + 19563160, + 16186464, + -29386857, + 4097519, + 10237984, + -4348115, + 28542350, + 13850243, + -23678021, + -15815942 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 5153746, + 9909285, + 1723747, + -2777874, + 30523605, + 5516873, + 19480852, + 5230134, + -23952439, + -15175766 + ]), + FieldElement.fromList([ + -30269007, + -3463509, + 7665486, + 10083793, + 28475525, + 1649722, + 20654025, + 16520125, + 30598449, + 7715701 + ]), + FieldElement.fromList([ + 28881845, + 14381568, + 9657904, + 3680757, + -20181635, + 7843316, + -31400660, + 1370708, + 29794553, + -1409300 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -22518993, + -6692182, + 14201702, + -8745502, + -23510406, + 8844726, + 18474211, + -1361450, + -13062696, + 13821877 + ]), + FieldElement.fromList([ + -6455177, + -7839871, + 3374702, + -4740862, + -27098617, + -10571707, + 31655028, + -7212327, + 18853322, + -14220951 + ]), + FieldElement.fromList([ + 4566830, + -12963868, + -28974889, + -12240689, + -7602672, + -2830569, + -8514358, + -10431137, + 2207753, + -3209784 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25154831, + -4185821, + 29681144, + 7868801, + -6854661, + -9423865, + -12437364, + -663000, + -31111463, + -16132436 + ]), + FieldElement.fromList([ + 25576264, + -2703214, + 7349804, + -11814844, + 16472782, + 9300885, + 3844789, + 15725684, + 171356, + 6466918 + ]), + FieldElement.fromList([ + 23103977, + 13316479, + 9739013, + -16149481, + 817875, + -15038942, + 8965339, + -14088058, + -30714912, + 16193877 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -33521811, + 3180713, + -2394130, + 14003687, + -16903474, + -16270840, + 17238398, + 4729455, + -18074513, + 9256800 + ]), + FieldElement.fromList([ + -25182317, + -4174131, + 32336398, + 5036987, + -21236817, + 11360617, + 22616405, + 9761698, + -19827198, + 630305 + ]), + FieldElement.fromList([ + -13720693, + 2639453, + -24237460, + -7406481, + 9494427, + -5774029, + -6554551, + -15960994, + -2449256, + -14291300 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -3151181, + -5046075, + 9282714, + 6866145, + -31907062, + -863023, + -18940575, + 15033784, + 25105118, + -7894876 + ]), + FieldElement.fromList([ + -24326370, + 15950226, + -31801215, + -14592823, + -11662737, + -5090925, + 1573892, + -2625887, + 2198790, + -15804619 + ]), + FieldElement.fromList([ + -3099351, + 10324967, + -2241613, + 7453183, + -5446979, + -2735503, + -13812022, + -16236442, + -32461234, + -12290683 + ]), + ) +]); + +/// base contains precomputed multiples of the base-point. See the Ed25519 paper +/// for a discussion about how these values are used. +var base = List.from([ + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 25967493, + -14356035, + 29566456, + 3660896, + -12694345, + 4014787, + 27544626, + -11754271, + -6079156, + 2047605 + ]), + FieldElement.fromList([ + -12545711, + 934262, + -2722910, + 3049990, + -727428, + 9406986, + 12720692, + 5043384, + 19500929, + -15469378 + ]), + FieldElement.fromList([ + -8738181, + 4489570, + 9688441, + -14785194, + 10184609, + -12363380, + 29287919, + 11864899, + -24514362, + -4438546 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12815894, + -12976347, + -21581243, + 11784320, + -25355658, + -2750717, + -11717903, + -3814571, + -358445, + -10211303 + ]), + FieldElement.fromList([ + -21703237, + 6903825, + 27185491, + 6451973, + -29577724, + -9554005, + -15616551, + 11189268, + -26829678, + -5319081 + ]), + FieldElement.fromList([ + 26966642, + 11152617, + 32442495, + 15396054, + 14353839, + -12752335, + -3128826, + -9541118, + -15472047, + -4166697 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15636291, + -9688557, + 24204773, + -7912398, + 616977, + -16685262, + 27787600, + -14772189, + 28944400, + -1550024 + ]), + FieldElement.fromList([ + 16568933, + 4717097, + -11556148, + -1102322, + 15682896, + -11807043, + 16354577, + -11775962, + 7689662, + 11199574 + ]), + FieldElement.fromList([ + 30464156, + -5976125, + -11779434, + -15670865, + 23220365, + 15915852, + 7512774, + 10017326, + -17749093, + -9920357 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -17036878, + 13921892, + 10945806, + -6033431, + 27105052, + -16084379, + -28926210, + 15006023, + 3284568, + -6276540 + ]), + FieldElement.fromList([ + 23599295, + -8306047, + -11193664, + -7687416, + 13236774, + 10506355, + 7464579, + 9656445, + 13059162, + 10374397 + ]), + FieldElement.fromList([ + 7798556, + 16710257, + 3033922, + 2874086, + 28997861, + 2835604, + 32406664, + -3839045, + -641708, + -101325 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 10861363, + 11473154, + 27284546, + 1981175, + -30064349, + 12577861, + 32867885, + 14515107, + -15438304, + 10819380 + ]), + FieldElement.fromList([ + 4708026, + 6336745, + 20377586, + 9066809, + -11272109, + 6594696, + -25653668, + 12483688, + -12668491, + 5581306 + ]), + FieldElement.fromList([ + 19563160, + 16186464, + -29386857, + 4097519, + 10237984, + -4348115, + 28542350, + 13850243, + -23678021, + -15815942 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -15371964, + -12862754, + 32573250, + 4720197, + -26436522, + 5875511, + -19188627, + -15224819, + -9818940, + -12085777 + ]), + FieldElement.fromList([ + -8549212, + 109983, + 15149363, + 2178705, + 22900618, + 4543417, + 3044240, + -15689887, + 1762328, + 14866737 + ]), + FieldElement.fromList([ + -18199695, + -15951423, + -10473290, + 1707278, + -17185920, + 3916101, + -28236412, + 3959421, + 27914454, + 4383652 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 5153746, + 9909285, + 1723747, + -2777874, + 30523605, + 5516873, + 19480852, + 5230134, + -23952439, + -15175766 + ]), + FieldElement.fromList([ + -30269007, + -3463509, + 7665486, + 10083793, + 28475525, + 1649722, + 20654025, + 16520125, + 30598449, + 7715701 + ]), + FieldElement.fromList([ + 28881845, + 14381568, + 9657904, + 3680757, + -20181635, + 7843316, + -31400660, + 1370708, + 29794553, + -1409300 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 14499471, + -2729599, + -33191113, + -4254652, + 28494862, + 14271267, + 30290735, + 10876454, + -33154098, + 2381726 + ]), + FieldElement.fromList([ + -7195431, + -2655363, + -14730155, + 462251, + -27724326, + 3941372, + -6236617, + 3696005, + -32300832, + 15351955 + ]), + FieldElement.fromList([ + 27431194, + 8222322, + 16448760, + -3907995, + -18707002, + 11938355, + -32961401, + -2970515, + 29551813, + 10109425 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -13657040, + -13155431, + -31283750, + 11777098, + 21447386, + 6519384, + -2378284, + -1627556, + 10092783, + -4764171 + ]), + FieldElement.fromList([ + 27939166, + 14210322, + 4677035, + 16277044, + -22964462, + -12398139, + -32508754, + 12005538, + -17810127, + 12803510 + ]), + FieldElement.fromList([ + 17228999, + -15661624, + -1233527, + 300140, + -1224870, + -11714777, + 30364213, + -9038194, + 18016357, + 4397660 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -10958843, + -7690207, + 4776341, + -14954238, + 27850028, + -15602212, + -26619106, + 14544525, + -17477504, + 982639 + ]), + FieldElement.fromList([ + 29253598, + 15796703, + -2863982, + -9908884, + 10057023, + 3163536, + 7332899, + -4120128, + -21047696, + 9934963 + ]), + FieldElement.fromList([ + 5793303, + 16271923, + -24131614, + -10116404, + 29188560, + 1206517, + -14747930, + 4559895, + -30123922, + -10897950 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -27643952, + -11493006, + 16282657, + -11036493, + 28414021, + -15012264, + 24191034, + 4541697, + -13338309, + 5500568 + ]), + FieldElement.fromList([ + 12650548, + -1497113, + 9052871, + 11355358, + -17680037, + -8400164, + -17430592, + 12264343, + 10874051, + 13524335 + ]), + FieldElement.fromList([ + 25556948, + -3045990, + 714651, + 2510400, + 23394682, + -10415330, + 33119038, + 5080568, + -22528059, + 5376628 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -26088264, + -4011052, + -17013699, + -3537628, + -6726793, + 1920897, + -22321305, + -9447443, + 4535768, + 1569007 + ]), + FieldElement.fromList([ + -2255422, + 14606630, + -21692440, + -8039818, + 28430649, + 8775819, + -30494562, + 3044290, + 31848280, + 12543772 + ]), + FieldElement.fromList([ + -22028579, + 2943893, + -31857513, + 6777306, + 13784462, + -4292203, + -27377195, + -2062731, + 7718482, + 14474653 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 2385315, + 2454213, + -22631320, + 46603, + -4437935, + -15680415, + 656965, + -7236665, + 24316168, + -5253567 + ]), + FieldElement.fromList([ + 13741529, + 10911568, + -33233417, + -8603737, + -20177830, + -1033297, + 33040651, + -13424532, + -20729456, + 8321686 + ]), + FieldElement.fromList([ + 21060490, + -2212744, + 15712757, + -4336099, + 1639040, + 10656336, + 23845965, + -11874838, + -9984458, + 608372 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -13672732, + -15087586, + -10889693, + -7557059, + -6036909, + 11305547, + 1123968, + -6780577, + 27229399, + 23887 + ]), + FieldElement.fromList([ + -23244140, + -294205, + -11744728, + 14712571, + -29465699, + -2029617, + 12797024, + -6440308, + -1633405, + 16678954 + ]), + FieldElement.fromList([ + -29500620, + 4770662, + -16054387, + 14001338, + 7830047, + 9564805, + -1508144, + -4795045, + -17169265, + 4904953 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 24059557, + 14617003, + 19037157, + -15039908, + 19766093, + -14906429, + 5169211, + 16191880, + 2128236, + -4326833 + ]), + FieldElement.fromList([ + -16981152, + 4124966, + -8540610, + -10653797, + 30336522, + -14105247, + -29806336, + 916033, + -6882542, + -2986532 + ]), + FieldElement.fromList([ + -22630907, + 12419372, + -7134229, + -7473371, + -16478904, + 16739175, + 285431, + 2763829, + 15736322, + 4143876 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 2379352, + 11839345, + -4110402, + -5988665, + 11274298, + 794957, + 212801, + -14594663, + 23527084, + -16458268 + ]), + FieldElement.fromList([ + 33431127, + -11130478, + -17838966, + -15626900, + 8909499, + 8376530, + -32625340, + 4087881, + -15188911, + -14416214 + ]), + FieldElement.fromList([ + 1767683, + 7197987, + -13205226, + -2022635, + -13091350, + 448826, + 5799055, + 4357868, + -4774191, + -16323038 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 6721966, + 13833823, + -23523388, + -1551314, + 26354293, + -11863321, + 23365147, + -3949732, + 7390890, + 2759800 + ]), + FieldElement.fromList([ + 4409041, + 2052381, + 23373853, + 10530217, + 7676779, + -12885954, + 21302353, + -4264057, + 1244380, + -12919645 + ]), + FieldElement.fromList([ + -4421239, + 7169619, + 4982368, + -2957590, + 30256825, + -2777540, + 14086413, + 9208236, + 15886429, + 16489664 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 1996075, + 10375649, + 14346367, + 13311202, + -6874135, + -16438411, + -13693198, + 398369, + -30606455, + -712933 + ]), + FieldElement.fromList([ + -25307465, + 9795880, + -2777414, + 14878809, + -33531835, + 14780363, + 13348553, + 12076947, + -30836462, + 5113182 + ]), + FieldElement.fromList([ + -17770784, + 11797796, + 31950843, + 13929123, + -25888302, + 12288344, + -30341101, + -7336386, + 13847711, + 5387222 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -18582163, + -3416217, + 17824843, + -2340966, + 22744343, + -10442611, + 8763061, + 3617786, + -19600662, + 10370991 + ]), + FieldElement.fromList([ + 20246567, + -14369378, + 22358229, + -543712, + 18507283, + -10413996, + 14554437, + -8746092, + 32232924, + 16763880 + ]), + FieldElement.fromList([ + 9648505, + 10094563, + 26416693, + 14745928, + -30374318, + -6472621, + 11094161, + 15689506, + 3140038, + -16510092 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -16160072, + 5472695, + 31895588, + 4744994, + 8823515, + 10365685, + -27224800, + 9448613, + -28774454, + 366295 + ]), + FieldElement.fromList([ + 19153450, + 11523972, + -11096490, + -6503142, + -24647631, + 5420647, + 28344573, + 8041113, + 719605, + 11671788 + ]), + FieldElement.fromList([ + 8678025, + 2694440, + -6808014, + 2517372, + 4964326, + 11152271, + -15432916, + -15266516, + 27000813, + -10195553 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -15157904, + 7134312, + 8639287, + -2814877, + -7235688, + 10421742, + 564065, + 5336097, + 6750977, + -14521026 + ]), + FieldElement.fromList([ + 11836410, + -3979488, + 26297894, + 16080799, + 23455045, + 15735944, + 1695823, + -8819122, + 8169720, + 16220347 + ]), + FieldElement.fromList([ + -18115838, + 8653647, + 17578566, + -6092619, + -8025777, + -16012763, + -11144307, + -2627664, + -5990708, + -14166033 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23308498, + -10968312, + 15213228, + -10081214, + -30853605, + -11050004, + 27884329, + 2847284, + 2655861, + 1738395 + ]), + FieldElement.fromList([ + -27537433, + -14253021, + -25336301, + -8002780, + -9370762, + 8129821, + 21651608, + -3239336, + -19087449, + -11005278 + ]), + FieldElement.fromList([ + 1533110, + 3437855, + 23735889, + 459276, + 29970501, + 11335377, + 26030092, + 5821408, + 10478196, + 8544890 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 32173121, + -16129311, + 24896207, + 3921497, + 22579056, + -3410854, + 19270449, + 12217473, + 17789017, + -3395995 + ]), + FieldElement.fromList([ + -30552961, + -2228401, + -15578829, + -10147201, + 13243889, + 517024, + 15479401, + -3853233, + 30460520, + 1052596 + ]), + FieldElement.fromList([ + -11614875, + 13323618, + 32618793, + 8175907, + -15230173, + 12596687, + 27491595, + -4612359, + 3179268, + -9478891 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 31947069, + -14366651, + -4640583, + -15339921, + -15125977, + -6039709, + -14756777, + -16411740, + 19072640, + -9511060 + ]), + FieldElement.fromList([ + 11685058, + 11822410, + 3158003, + -13952594, + 33402194, + -4165066, + 5977896, + -5215017, + 473099, + 5040608 + ]), + FieldElement.fromList([ + -20290863, + 8198642, + -27410132, + 11602123, + 1290375, + -2799760, + 28326862, + 1721092, + -19558642, + -3131606 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 7881532, + 10687937, + 7578723, + 7738378, + -18951012, + -2553952, + 21820786, + 8076149, + -27868496, + 11538389 + ]), + FieldElement.fromList([ + -19935666, + 3899861, + 18283497, + -6801568, + -15728660, + -11249211, + 8754525, + 7446702, + -5676054, + 5797016 + ]), + FieldElement.fromList([ + -11295600, + -3793569, + -15782110, + -7964573, + 12708869, + -8456199, + 2014099, + -9050574, + -2369172, + -5877341 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -22472376, + -11568741, + -27682020, + 1146375, + 18956691, + 16640559, + 1192730, + -3714199, + 15123619, + 10811505 + ]), + FieldElement.fromList([ + 14352098, + -3419715, + -18942044, + 10822655, + 32750596, + 4699007, + -70363, + 15776356, + -28886779, + -11974553 + ]), + FieldElement.fromList([ + -28241164, + -8072475, + -4978962, + -5315317, + 29416931, + 1847569, + -20654173, + -16484855, + 4714547, + -9600655 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15200332, + 8368572, + 19679101, + 15970074, + -31872674, + 1959451, + 24611599, + -4543832, + -11745876, + 12340220 + ]), + FieldElement.fromList([ + 12876937, + -10480056, + 33134381, + 6590940, + -6307776, + 14872440, + 9613953, + 8241152, + 15370987, + 9608631 + ]), + FieldElement.fromList([ + -4143277, + -12014408, + 8446281, + -391603, + 4407738, + 13629032, + -7724868, + 15866074, + -28210621, + -8814099 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 26660628, + -15677655, + 8393734, + 358047, + -7401291, + 992988, + -23904233, + 858697, + 20571223, + 8420556 + ]), + FieldElement.fromList([ + 14620715, + 13067227, + -15447274, + 8264467, + 14106269, + 15080814, + 33531827, + 12516406, + -21574435, + -12476749 + ]), + FieldElement.fromList([ + 236881, + 10476226, + 57258, + -14677024, + 6472998, + 2466984, + 17258519, + 7256740, + 8791136, + 15069930 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 1276410, + -9371918, + 22949635, + -16322807, + -23493039, + -5702186, + 14711875, + 4874229, + -30663140, + -2331391 + ]), + FieldElement.fromList([ + 5855666, + 4990204, + -13711848, + 7294284, + -7804282, + 1924647, + -1423175, + -7912378, + -33069337, + 9234253 + ]), + FieldElement.fromList([ + 20590503, + -9018988, + 31529744, + -7352666, + -2706834, + 10650548, + 31559055, + -11609587, + 18979186, + 13396066 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 24474287, + 4968103, + 22267082, + 4407354, + 24063882, + -8325180, + -18816887, + 13594782, + 33514650, + 7021958 + ]), + FieldElement.fromList([ + -11566906, + -6565505, + -21365085, + 15928892, + -26158305, + 4315421, + -25948728, + -3916677, + -21480480, + 12868082 + ]), + FieldElement.fromList([ + -28635013, + 13504661, + 19988037, + -2132761, + 21078225, + 6443208, + -21446107, + 2244500, + -12455797, + -8089383 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -30595528, + 13793479, + -5852820, + 319136, + -25723172, + -6263899, + 33086546, + 8957937, + -15233648, + 5540521 + ]), + FieldElement.fromList([ + -11630176, + -11503902, + -8119500, + -7643073, + 2620056, + 1022908, + -23710744, + -1568984, + -16128528, + -14962807 + ]), + FieldElement.fromList([ + 23152971, + 775386, + 27395463, + 14006635, + -9701118, + 4649512, + 1689819, + 892185, + -11513277, + -15205948 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 9770129, + 9586738, + 26496094, + 4324120, + 1556511, + -3550024, + 27453819, + 4763127, + -19179614, + 5867134 + ]), + FieldElement.fromList([ + -32765025, + 1927590, + 31726409, + -4753295, + 23962434, + -16019500, + 27846559, + 5931263, + -29749703, + -16108455 + ]), + FieldElement.fromList([ + 27461885, + -2977536, + 22380810, + 1815854, + -23033753, + -3031938, + 7283490, + -15148073, + -19526700, + 7734629 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -8010264, + -9590817, + -11120403, + 6196038, + 29344158, + -13430885, + 7585295, + -3176626, + 18549497, + 15302069 + ]), + FieldElement.fromList([ + -32658337, + -6171222, + -7672793, + -11051681, + 6258878, + 13504381, + 10458790, + -6418461, + -8872242, + 8424746 + ]), + FieldElement.fromList([ + 24687205, + 8613276, + -30667046, + -3233545, + 1863892, + -1830544, + 19206234, + 7134917, + -11284482, + -828919 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 11334899, + -9218022, + 8025293, + 12707519, + 17523892, + -10476071, + 10243738, + -14685461, + -5066034, + 16498837 + ]), + FieldElement.fromList([ + 8911542, + 6887158, + -9584260, + -6958590, + 11145641, + -9543680, + 17303925, + -14124238, + 6536641, + 10543906 + ]), + FieldElement.fromList([ + -28946384, + 15479763, + -17466835, + 568876, + -1497683, + 11223454, + -2669190, + -16625574, + -27235709, + 8876771 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25742899, + -12566864, + -15649966, + -846607, + -33026686, + -796288, + -33481822, + 15824474, + -604426, + -9039817 + ]), + FieldElement.fromList([ + 10330056, + 70051, + 7957388, + -9002667, + 9764902, + 15609756, + 27698697, + -4890037, + 1657394, + 3084098 + ]), + FieldElement.fromList([ + 10477963, + -7470260, + 12119566, + -13250805, + 29016247, + -5365589, + 31280319, + 14396151, + -30233575, + 15272409 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12288309, + 3169463, + 28813183, + 16658753, + 25116432, + -5630466, + -25173957, + -12636138, + -25014757, + 1950504 + ]), + FieldElement.fromList([ + -26180358, + 9489187, + 11053416, + -14746161, + -31053720, + 5825630, + -8384306, + -8767532, + 15341279, + 8373727 + ]), + FieldElement.fromList([ + 28685821, + 7759505, + -14378516, + -12002860, + -31971820, + 4079242, + 298136, + -10232602, + -2878207, + 15190420 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -32932876, + 13806336, + -14337485, + -15794431, + -24004620, + 10940928, + 8669718, + 2742393, + -26033313, + -6875003 + ]), + FieldElement.fromList([ + -1580388, + -11729417, + -25979658, + -11445023, + -17411874, + -10912854, + 9291594, + -16247779, + -12154742, + 6048605 + ]), + FieldElement.fromList([ + -30305315, + 14843444, + 1539301, + 11864366, + 20201677, + 1900163, + 13934231, + 5128323, + 11213262, + 9168384 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -26280513, + 11007847, + 19408960, + -940758, + -18592965, + -4328580, + -5088060, + -11105150, + 20470157, + -16398701 + ]), + FieldElement.fromList([ + -23136053, + 9282192, + 14855179, + -15390078, + -7362815, + -14408560, + -22783952, + 14461608, + 14042978, + 5230683 + ]), + FieldElement.fromList([ + 29969567, + -2741594, + -16711867, + -8552442, + 9175486, + -2468974, + 21556951, + 3506042, + -5933891, + -12449708 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -3144746, + 8744661, + 19704003, + 4581278, + -20430686, + 6830683, + -21284170, + 8971513, + -28539189, + 15326563 + ]), + FieldElement.fromList([ + -19464629, + 10110288, + -17262528, + -3503892, + -23500387, + 1355669, + -15523050, + 15300988, + -20514118, + 9168260 + ]), + FieldElement.fromList([ + -5353335, + 4488613, + -23803248, + 16314347, + 7780487, + -15638939, + -28948358, + 9601605, + 33087103, + -9011387 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -19443170, + -15512900, + -20797467, + -12445323, + -29824447, + 10229461, + -27444329, + -15000531, + -5996870, + 15664672 + ]), + FieldElement.fromList([ + 23294591, + -16632613, + -22650781, + -8470978, + 27844204, + 11461195, + 13099750, + -2460356, + 18151676, + 13417686 + ]), + FieldElement.fromList([ + -24722913, + -4176517, + -31150679, + 5988919, + -26858785, + 6685065, + 1661597, + -12551441, + 15271676, + -15452665 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 11433042, + -13228665, + 8239631, + -5279517, + -1985436, + -725718, + -18698764, + 2167544, + -6921301, + -13440182 + ]), + FieldElement.fromList([ + -31436171, + 15575146, + 30436815, + 12192228, + -22463353, + 9395379, + -9917708, + -8638997, + 12215110, + 12028277 + ]), + FieldElement.fromList([ + 14098400, + 6555944, + 23007258, + 5757252, + -15427832, + -12950502, + 30123440, + 4617780, + -16900089, + -655628 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -4026201, + -15240835, + 11893168, + 13718664, + -14809462, + 1847385, + -15819999, + 10154009, + 23973261, + -12684474 + ]), + FieldElement.fromList([ + -26531820, + -3695990, + -1908898, + 2534301, + -31870557, + -16550355, + 18341390, + -11419951, + 32013174, + -10103539 + ]), + FieldElement.fromList([ + -25479301, + 10876443, + -11771086, + -14625140, + -12369567, + 1838104, + 21911214, + 6354752, + 4425632, + -837822 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -10433389, + -14612966, + 22229858, + -3091047, + -13191166, + 776729, + -17415375, + -12020462, + 4725005, + 14044970 + ]), + FieldElement.fromList([ + 19268650, + -7304421, + 1555349, + 8692754, + -21474059, + -9910664, + 6347390, + -1411784, + -19522291, + -16109756 + ]), + FieldElement.fromList([ + -24864089, + 12986008, + -10898878, + -5558584, + -11312371, + -148526, + 19541418, + 8180106, + 9282262, + 10282508 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -26205082, + 4428547, + -8661196, + -13194263, + 4098402, + -14165257, + 15522535, + 8372215, + 5542595, + -10702683 + ]), + FieldElement.fromList([ + -10562541, + 14895633, + 26814552, + -16673850, + -17480754, + -2489360, + -2781891, + 6993761, + -18093885, + 10114655 + ]), + FieldElement.fromList([ + -20107055, + -929418, + 31422704, + 10427861, + -7110749, + 6150669, + -29091755, + -11529146, + 25953725, + -106158 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -4234397, + -8039292, + -9119125, + 3046000, + 2101609, + -12607294, + 19390020, + 6094296, + -3315279, + 12831125 + ]), + FieldElement.fromList([ + -15998678, + 7578152, + 5310217, + 14408357, + -33548620, + -224739, + 31575954, + 6326196, + 7381791, + -2421839 + ]), + FieldElement.fromList([ + -20902779, + 3296811, + 24736065, + -16328389, + 18374254, + 7318640, + 6295303, + 8082724, + -15362489, + 12339664 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 27724736, + 2291157, + 6088201, + -14184798, + 1792727, + 5857634, + 13848414, + 15768922, + 25091167, + 14856294 + ]), + FieldElement.fromList([ + -18866652, + 8331043, + 24373479, + 8541013, + -701998, + -9269457, + 12927300, + -12695493, + -22182473, + -9012899 + ]), + FieldElement.fromList([ + -11423429, + -5421590, + 11632845, + 3405020, + 30536730, + -11674039, + -27260765, + 13866390, + 30146206, + 9142070 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 3924129, + -15307516, + -13817122, + -10054960, + 12291820, + -668366, + -27702774, + 9326384, + -8237858, + 4171294 + ]), + FieldElement.fromList([ + -15921940, + 16037937, + 6713787, + 16606682, + -21612135, + 2790944, + 26396185, + 3731949, + 345228, + -5462949 + ]), + FieldElement.fromList([ + -21327538, + 13448259, + 25284571, + 1143661, + 20614966, + -8849387, + 2031539, + -12391231, + -16253183, + -13582083 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 31016211, + -16722429, + 26371392, + -14451233, + -5027349, + 14854137, + 17477601, + 3842657, + 28012650, + -16405420 + ]), + FieldElement.fromList([ + -5075835, + 9368966, + -8562079, + -4600902, + -15249953, + 6970560, + -9189873, + 16292057, + -8867157, + 3507940 + ]), + FieldElement.fromList([ + 29439664, + 3537914, + 23333589, + 6997794, + -17555561, + -11018068, + -15209202, + -15051267, + -9164929, + 6580396 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12185861, + -7679788, + 16438269, + 10826160, + -8696817, + -6235611, + 17860444, + -9273846, + -2095802, + 9304567 + ]), + FieldElement.fromList([ + 20714564, + -4336911, + 29088195, + 7406487, + 11426967, + -5095705, + 14792667, + -14608617, + 5289421, + -477127 + ]), + FieldElement.fromList([ + -16665533, + -10650790, + -6160345, + -13305760, + 9192020, + -1802462, + 17271490, + 12349094, + 26939669, + -3752294 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12889898, + 9373458, + 31595848, + 16374215, + 21471720, + 13221525, + -27283495, + -12348559, + -3698806, + 117887 + ]), + FieldElement.fromList([ + 22263325, + -6560050, + 3984570, + -11174646, + -15114008, + -566785, + 28311253, + 5358056, + -23319780, + 541964 + ]), + FieldElement.fromList([ + 16259219, + 3261970, + 2309254, + -15534474, + -16885711, + -4581916, + 24134070, + -16705829, + -13337066, + -13552195 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 9378160, + -13140186, + -22845982, + -12745264, + 28198281, + -7244098, + -2399684, + -717351, + 690426, + 14876244 + ]), + FieldElement.fromList([ + 24977353, + -314384, + -8223969, + -13465086, + 28432343, + -1176353, + -13068804, + -12297348, + -22380984, + 6618999 + ]), + FieldElement.fromList([ + -1538174, + 11685646, + 12944378, + 13682314, + -24389511, + -14413193, + 8044829, + -13817328, + 32239829, + -5652762 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -18603066, + 4762990, + -926250, + 8885304, + -28412480, + -3187315, + 9781647, + -10350059, + 32779359, + 5095274 + ]), + FieldElement.fromList([ + -33008130, + -5214506, + -32264887, + -3685216, + 9460461, + -9327423, + -24601656, + 14506724, + 21639561, + -2630236 + ]), + FieldElement.fromList([ + -16400943, + -13112215, + 25239338, + 15531969, + 3987758, + -4499318, + -1289502, + -6863535, + 17874574, + 558605 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -13600129, + 10240081, + 9171883, + 16131053, + -20869254, + 9599700, + 33499487, + 5080151, + 2085892, + 5119761 + ]), + FieldElement.fromList([ + -22205145, + -2519528, + -16381601, + 414691, + -25019550, + 2170430, + 30634760, + -8363614, + -31999993, + -5759884 + ]), + FieldElement.fromList([ + -6845704, + 15791202, + 8550074, + -1312654, + 29928809, + -12092256, + 27534430, + -7192145, + -22351378, + 12961482 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -24492060, + -9570771, + 10368194, + 11582341, + -23397293, + -2245287, + 16533930, + 8206996, + -30194652, + -5159638 + ]), + FieldElement.fromList([ + -11121496, + -3382234, + 2307366, + 6362031, + -135455, + 8868177, + -16835630, + 7031275, + 7589640, + 8945490 + ]), + FieldElement.fromList([ + -32152748, + 8917967, + 6661220, + -11677616, + -1192060, + -15793393, + 7251489, + -11182180, + 24099109, + -14456170 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 5019558, + -7907470, + 4244127, + -14714356, + -26933272, + 6453165, + -19118182, + -13289025, + -6231896, + -10280736 + ]), + FieldElement.fromList([ + 10853594, + 10721687, + 26480089, + 5861829, + -22995819, + 1972175, + -1866647, + -10557898, + -3363451, + -6441124 + ]), + FieldElement.fromList([ + -17002408, + 5906790, + 221599, + -6563147, + 7828208, + -13248918, + 24362661, + -2008168, + -13866408, + 7421392 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 8139927, + -6546497, + 32257646, + -5890546, + 30375719, + 1886181, + -21175108, + 15441252, + 28826358, + -4123029 + ]), + FieldElement.fromList([ + 6267086, + 9695052, + 7709135, + -16603597, + -32869068, + -1886135, + 14795160, + -7840124, + 13746021, + -1742048 + ]), + FieldElement.fromList([ + 28584902, + 7787108, + -6732942, + -15050729, + 22846041, + -7571236, + -3181936, + -363524, + 4771362, + -8419958 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 24949256, + 6376279, + -27466481, + -8174608, + -18646154, + -9930606, + 33543569, + -12141695, + 3569627, + 11342593 + ]), + FieldElement.fromList([ + 26514989, + 4740088, + 27912651, + 3697550, + 19331575, + -11472339, + 6809886, + 4608608, + 7325975, + -14801071 + ]), + FieldElement.fromList([ + -11618399, + -14554430, + -24321212, + 7655128, + -1369274, + 5214312, + -27400540, + 10258390, + -17646694, + -8186692 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 11431204, + 15823007, + 26570245, + 14329124, + 18029990, + 4796082, + -31446179, + 15580664, + 9280358, + -3973687 + ]), + FieldElement.fromList([ + -160783, + -10326257, + -22855316, + -4304997, + -20861367, + -13621002, + -32810901, + -11181622, + -15545091, + 4387441 + ]), + FieldElement.fromList([ + -20799378, + 12194512, + 3937617, + -5805892, + -27154820, + 9340370, + -24513992, + 8548137, + 20617071, + -7482001 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -938825, + -3930586, + -8714311, + 16124718, + 24603125, + -6225393, + -13775352, + -11875822, + 24345683, + 10325460 + ]), + FieldElement.fromList([ + -19855277, + -1568885, + -22202708, + 8714034, + 14007766, + 6928528, + 16318175, + -1010689, + 4766743, + 3552007 + ]), + FieldElement.fromList([ + -21751364, + -16730916, + 1351763, + -803421, + -4009670, + 3950935, + 3217514, + 14481909, + 10988822, + -3994762 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15564307, + -14311570, + 3101243, + 5684148, + 30446780, + -8051356, + 12677127, + -6505343, + -8295852, + 13296005 + ]), + FieldElement.fromList([ + -9442290, + 6624296, + -30298964, + -11913677, + -4670981, + -2057379, + 31521204, + 9614054, + -30000824, + 12074674 + ]), + FieldElement.fromList([ + 4771191, + -135239, + 14290749, + -13089852, + 27992298, + 14998318, + -1413936, + -1556716, + 29832613, + -16391035 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 7064884, + -7541174, + -19161962, + -5067537, + -18891269, + -2912736, + 25825242, + 5293297, + -27122660, + 13101590 + ]), + FieldElement.fromList([ + -2298563, + 2439670, + -7466610, + 1719965, + -27267541, + -16328445, + 32512469, + -5317593, + -30356070, + -4190957 + ]), + FieldElement.fromList([ + -30006540, + 10162316, + -33180176, + 3981723, + -16482138, + -13070044, + 14413974, + 9515896, + 19568978, + 9628812 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 33053803, + 199357, + 15894591, + 1583059, + 27380243, + -4580435, + -17838894, + -6106839, + -6291786, + 3437740 + ]), + FieldElement.fromList([ + -18978877, + 3884493, + 19469877, + 12726490, + 15913552, + 13614290, + -22961733, + 70104, + 7463304, + 4176122 + ]), + FieldElement.fromList([ + -27124001, + 10659917, + 11482427, + -16070381, + 12771467, + -6635117, + -32719404, + -5322751, + 24216882, + 5944158 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 8894125, + 7450974, + -2664149, + -9765752, + -28080517, + -12389115, + 19345746, + 14680796, + 11632993, + 5847885 + ]), + FieldElement.fromList([ + 26942781, + -2315317, + 9129564, + -4906607, + 26024105, + 11769399, + -11518837, + 6367194, + -9727230, + 4782140 + ]), + FieldElement.fromList([ + 19916461, + -4828410, + -22910704, + -11414391, + 25606324, + -5972441, + 33253853, + 8220911, + 6358847, + -1873857 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 801428, + -2081702, + 16569428, + 11065167, + 29875704, + 96627, + 7908388, + -4480480, + -13538503, + 1387155 + ]), + FieldElement.fromList([ + 19646058, + 5720633, + -11416706, + 12814209, + 11607948, + 12749789, + 14147075, + 15156355, + -21866831, + 11835260 + ]), + FieldElement.fromList([ + 19299512, + 1155910, + 28703737, + 14890794, + 2925026, + 7269399, + 26121523, + 15467869, + -26560550, + 5052483 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -3017432, + 10058206, + 1980837, + 3964243, + 22160966, + 12322533, + -6431123, + -12618185, + 12228557, + -7003677 + ]), + FieldElement.fromList([ + 32944382, + 14922211, + -22844894, + 5188528, + 21913450, + -8719943, + 4001465, + 13238564, + -6114803, + 8653815 + ]), + FieldElement.fromList([ + 22865569, + -4652735, + 27603668, + -12545395, + 14348958, + 8234005, + 24808405, + 5719875, + 28483275, + 2841751 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -16420968, + -1113305, + -327719, + -12107856, + 21886282, + -15552774, + -1887966, + -315658, + 19932058, + -12739203 + ]), + FieldElement.fromList([ + -11656086, + 10087521, + -8864888, + -5536143, + -19278573, + -3055912, + 3999228, + 13239134, + -4777469, + -13910208 + ]), + FieldElement.fromList([ + 1382174, + -11694719, + 17266790, + 9194690, + -13324356, + 9720081, + 20403944, + 11284705, + -14013818, + 3093230 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 16650921, + -11037932, + -1064178, + 1570629, + -8329746, + 7352753, + -302424, + 16271225, + -24049421, + -6691850 + ]), + FieldElement.fromList([ + -21911077, + -5927941, + -4611316, + -5560156, + -31744103, + -10785293, + 24123614, + 15193618, + -21652117, + -16739389 + ]), + FieldElement.fromList([ + -9935934, + -4289447, + -25279823, + 4372842, + 2087473, + 10399484, + 31870908, + 14690798, + 17361620, + 11864968 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -11307610, + 6210372, + 13206574, + 5806320, + -29017692, + -13967200, + -12331205, + -7486601, + -25578460, + -16240689 + ]), + FieldElement.fromList([ + 14668462, + -12270235, + 26039039, + 15305210, + 25515617, + 4542480, + 10453892, + 6577524, + 9145645, + -6443880 + ]), + FieldElement.fromList([ + 5974874, + 3053895, + -9433049, + -10385191, + -31865124, + 3225009, + -7972642, + 3936128, + -5652273, + -3050304 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30625386, + -4729400, + -25555961, + -12792866, + -20484575, + 7695099, + 17097188, + -16303496, + -27999779, + 1803632 + ]), + FieldElement.fromList([ + -3553091, + 9865099, + -5228566, + 4272701, + -5673832, + -16689700, + 14911344, + 12196514, + -21405489, + 7047412 + ]), + FieldElement.fromList([ + 20093277, + 9920966, + -11138194, + -5343857, + 13161587, + 12044805, + -32856851, + 4124601, + -32343828, + -10257566 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -20788824, + 14084654, + -13531713, + 7842147, + 19119038, + -13822605, + 4752377, + -8714640, + -21679658, + 2288038 + ]), + FieldElement.fromList([ + -26819236, + -3283715, + 29965059, + 3039786, + -14473765, + 2540457, + 29457502, + 14625692, + -24819617, + 12570232 + ]), + FieldElement.fromList([ + -1063558, + -11551823, + 16920318, + 12494842, + 1278292, + -5869109, + -21159943, + -3498680, + -11974704, + 4724943 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 17960970, + -11775534, + -4140968, + -9702530, + -8876562, + -1410617, + -12907383, + -8659932, + -29576300, + 1903856 + ]), + FieldElement.fromList([ + 23134274, + -14279132, + -10681997, + -1611936, + 20684485, + 15770816, + -12989750, + 3190296, + 26955097, + 14109738 + ]), + FieldElement.fromList([ + 15308788, + 5320727, + -30113809, + -14318877, + 22902008, + 7767164, + 29425325, + -11277562, + 31960942, + 11934971 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -27395711, + 8435796, + 4109644, + 12222639, + -24627868, + 14818669, + 20638173, + 4875028, + 10491392, + 1379718 + ]), + FieldElement.fromList([ + -13159415, + 9197841, + 3875503, + -8936108, + -1383712, + -5879801, + 33518459, + 16176658, + 21432314, + 12180697 + ]), + FieldElement.fromList([ + -11787308, + 11500838, + 13787581, + -13832590, + -22430679, + 10140205, + 1465425, + 12689540, + -10301319, + -13872883 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 5414091, + -15386041, + -21007664, + 9643570, + 12834970, + 1186149, + -2622916, + -1342231, + 26128231, + 6032912 + ]), + FieldElement.fromList([ + -26337395, + -13766162, + 32496025, + -13653919, + 17847801, + -12669156, + 3604025, + 8316894, + -25875034, + -10437358 + ]), + FieldElement.fromList([ + 3296484, + 6223048, + 24680646, + -12246460, + -23052020, + 5903205, + -8862297, + -4639164, + 12376617, + 3188849 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 29190488, + -14659046, + 27549113, + -1183516, + 3520066, + -10697301, + 32049515, + -7309113, + -16109234, + -9852307 + ]), + FieldElement.fromList([ + -14744486, + -9309156, + 735818, + -598978, + -20407687, + -5057904, + 25246078, + -15795669, + 18640741, + -960977 + ]), + FieldElement.fromList([ + -6928835, + -16430795, + 10361374, + 5642961, + 4910474, + 12345252, + -31638386, + -494430, + 10530747, + 1053335 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -29265967, + -14186805, + -13538216, + -12117373, + -19457059, + -10655384, + -31462369, + -2948985, + 24018831, + 15026644 + ]), + FieldElement.fromList([ + -22592535, + -3145277, + -2289276, + 5953843, + -13440189, + 9425631, + 25310643, + 13003497, + -2314791, + -15145616 + ]), + FieldElement.fromList([ + -27419985, + -603321, + -8043984, + -1669117, + -26092265, + 13987819, + -27297622, + 187899, + -23166419, + -2531735 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -21744398, + -13810475, + 1844840, + 5021428, + -10434399, + -15911473, + 9716667, + 16266922, + -5070217, + 726099 + ]), + FieldElement.fromList([ + 29370922, + -6053998, + 7334071, + -15342259, + 9385287, + 2247707, + -13661962, + -4839461, + 30007388, + -15823341 + ]), + FieldElement.fromList([ + -936379, + 16086691, + 23751945, + -543318, + -1167538, + -5189036, + 9137109, + 730663, + 9835848, + 4555336 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23376435, + 1410446, + -22253753, + -12899614, + 30867635, + 15826977, + 17693930, + 544696, + -11985298, + 12422646 + ]), + FieldElement.fromList([ + 31117226, + -12215734, + -13502838, + 6561947, + -9876867, + -12757670, + -5118685, + -4096706, + 29120153, + 13924425 + ]), + FieldElement.fromList([ + -17400879, + -14233209, + 19675799, + -2734756, + -11006962, + -5858820, + -9383939, + -11317700, + 7240931, + -237388 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -31361739, + -11346780, + -15007447, + -5856218, + -22453340, + -12152771, + 1222336, + 4389483, + 3293637, + -15551743 + ]), + FieldElement.fromList([ + -16684801, + -14444245, + 11038544, + 11054958, + -13801175, + -3338533, + -24319580, + 7733547, + 12796905, + -6335822 + ]), + FieldElement.fromList([ + -8759414, + -10817836, + -25418864, + 10783769, + -30615557, + -9746811, + -28253339, + 3647836, + 3222231, + -11160462 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 18606113, + 1693100, + -25448386, + -15170272, + 4112353, + 10045021, + 23603893, + -2048234, + -7550776, + 2484985 + ]), + FieldElement.fromList([ + 9255317, + -3131197, + -12156162, + -1004256, + 13098013, + -9214866, + 16377220, + -2102812, + -19802075, + -3034702 + ]), + FieldElement.fromList([ + -22729289, + 7496160, + -5742199, + 11329249, + 19991973, + -3347502, + -31718148, + 9936966, + -30097688, + -10618797 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 21878590, + -5001297, + 4338336, + 13643897, + -3036865, + 13160960, + 19708896, + 5415497, + -7360503, + -4109293 + ]), + FieldElement.fromList([ + 27736861, + 10103576, + 12500508, + 8502413, + -3413016, + -9633558, + 10436918, + -1550276, + -23659143, + -8132100 + ]), + FieldElement.fromList([ + 19492550, + -12104365, + -29681976, + -852630, + -3208171, + 12403437, + 30066266, + 8367329, + 13243957, + 8709688 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 12015105, + 2801261, + 28198131, + 10151021, + 24818120, + -4743133, + -11194191, + -5645734, + 5150968, + 7274186 + ]), + FieldElement.fromList([ + 2831366, + -12492146, + 1478975, + 6122054, + 23825128, + -12733586, + 31097299, + 6083058, + 31021603, + -9793610 + ]), + FieldElement.fromList([ + -2529932, + -2229646, + 445613, + 10720828, + -13849527, + -11505937, + -23507731, + 16354465, + 15067285, + -14147707 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 7840942, + 14037873, + -33364863, + 15934016, + -728213, + -3642706, + 21403988, + 1057586, + -19379462, + -12403220 + ]), + FieldElement.fromList([ + 915865, + -16469274, + 15608285, + -8789130, + -24357026, + 6060030, + -17371319, + 8410997, + -7220461, + 16527025 + ]), + FieldElement.fromList([ + 32922597, + -556987, + 20336074, + -16184568, + 10903705, + -5384487, + 16957574, + 52992, + 23834301, + 6588044 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 32752030, + 11232950, + 3381995, + -8714866, + 22652988, + -10744103, + 17159699, + 16689107, + -20314580, + -1305992 + ]), + FieldElement.fromList([ + -4689649, + 9166776, + -25710296, + -10847306, + 11576752, + 12733943, + 7924251, + -2752281, + 1976123, + -7249027 + ]), + FieldElement.fromList([ + 21251222, + 16309901, + -2983015, + -6783122, + 30810597, + 12967303, + 156041, + -3371252, + 12331345, + -8237197 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 8651614, + -4477032, + -16085636, + -4996994, + 13002507, + 2950805, + 29054427, + -5106970, + 10008136, + -4667901 + ]), + FieldElement.fromList([ + 31486080, + 15114593, + -14261250, + 12951354, + 14369431, + -7387845, + 16347321, + -13662089, + 8684155, + -10532952 + ]), + FieldElement.fromList([ + 19443825, + 11385320, + 24468943, + -9659068, + -23919258, + 2187569, + -26263207, + -6086921, + 31316348, + 14219878 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -28594490, + 1193785, + 32245219, + 11392485, + 31092169, + 15722801, + 27146014, + 6992409, + 29126555, + 9207390 + ]), + FieldElement.fromList([ + 32382935, + 1110093, + 18477781, + 11028262, + -27411763, + -7548111, + -4980517, + 10843782, + -7957600, + -14435730 + ]), + FieldElement.fromList([ + 2814918, + 7836403, + 27519878, + -7868156, + -20894015, + -11553689, + -21494559, + 8550130, + 28346258, + 1994730 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -19578299, + 8085545, + -14000519, + -3948622, + 2785838, + -16231307, + -19516951, + 7174894, + 22628102, + 8115180 + ]), + FieldElement.fromList([ + -30405132, + 955511, + -11133838, + -15078069, + -32447087, + -13278079, + -25651578, + 3317160, + -9943017, + 930272 + ]), + FieldElement.fromList([ + -15303681, + -6833769, + 28856490, + 1357446, + 23421993, + 1057177, + 24091212, + -1388970, + -22765376, + -10650715 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -22751231, + -5303997, + -12907607, + -12768866, + -15811511, + -7797053, + -14839018, + -16554220, + -1867018, + 8398970 + ]), + FieldElement.fromList([ + -31969310, + 2106403, + -4736360, + 1362501, + 12813763, + 16200670, + 22981545, + -6291273, + 18009408, + -15772772 + ]), + FieldElement.fromList([ + -17220923, + -9545221, + -27784654, + 14166835, + 29815394, + 7444469, + 29551787, + -3727419, + 19288549, + 1325865 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15100157, + -15835752, + -23923978, + -1005098, + -26450192, + 15509408, + 12376730, + -3479146, + 33166107, + -8042750 + ]), + FieldElement.fromList([ + 20909231, + 13023121, + -9209752, + 16251778, + -5778415, + -8094914, + 12412151, + 10018715, + 2213263, + -13878373 + ]), + FieldElement.fromList([ + 32529814, + -11074689, + 30361439, + -16689753, + -9135940, + 1513226, + 22922121, + 6382134, + -5766928, + 8371348 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 9923462, + 11271500, + 12616794, + 3544722, + -29998368, + -1721626, + 12891687, + -8193132, + -26442943, + 10486144 + ]), + FieldElement.fromList([ + -22597207, + -7012665, + 8587003, + -8257861, + 4084309, + -12970062, + 361726, + 2610596, + -23921530, + -11455195 + ]), + FieldElement.fromList([ + 5408411, + -1136691, + -4969122, + 10561668, + 24145918, + 14240566, + 31319731, + -4235541, + 19985175, + -3436086 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -13994457, + 16616821, + 14549246, + 3341099, + 32155958, + 13648976, + -17577068, + 8849297, + 65030, + 8370684 + ]), + FieldElement.fromList([ + -8320926, + -12049626, + 31204563, + 5839400, + -20627288, + -1057277, + -19442942, + 6922164, + 12743482, + -9800518 + ]), + FieldElement.fromList([ + -2361371, + 12678785, + 28815050, + 4759974, + -23893047, + 4884717, + 23783145, + 11038569, + 18800704, + 255233 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -5269658, + -1773886, + 13957886, + 7990715, + 23132995, + 728773, + 13393847, + 9066957, + 19258688, + -14753793 + ]), + FieldElement.fromList([ + -2936654, + -10827535, + -10432089, + 14516793, + -3640786, + 4372541, + -31934921, + 2209390, + -1524053, + 2055794 + ]), + FieldElement.fromList([ + 580882, + 16705327, + 5468415, + -2683018, + -30926419, + -14696000, + -7203346, + -8994389, + -30021019, + 7394435 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 23838809, + 1822728, + -15738443, + 15242727, + 8318092, + -3733104, + -21672180, + -3492205, + -4821741, + 14799921 + ]), + FieldElement.fromList([ + 13345610, + 9759151, + 3371034, + -16137791, + 16353039, + 8577942, + 31129804, + 13496856, + -9056018, + 7402518 + ]), + FieldElement.fromList([ + 2286874, + -4435931, + -20042458, + -2008336, + -13696227, + 5038122, + 11006906, + -15760352, + 8205061, + 1607563 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 14414086, + -8002132, + 3331830, + -3208217, + 22249151, + -5594188, + 18364661, + -2906958, + 30019587, + -9029278 + ]), + FieldElement.fromList([ + -27688051, + 1585953, + -10775053, + 931069, + -29120221, + -11002319, + -14410829, + 12029093, + 9944378, + 8024 + ]), + FieldElement.fromList([ + 4368715, + -3709630, + 29874200, + -15022983, + -20230386, + -11410704, + -16114594, + -999085, + -8142388, + 5640030 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 10299610, + 13746483, + 11661824, + 16234854, + 7630238, + 5998374, + 9809887, + -16694564, + 15219798, + -14327783 + ]), + FieldElement.fromList([ + 27425505, + -5719081, + 3055006, + 10660664, + 23458024, + 595578, + -15398605, + -1173195, + -18342183, + 9742717 + ]), + FieldElement.fromList([ + 6744077, + 2427284, + 26042789, + 2720740, + -847906, + 1118974, + 32324614, + 7406442, + 12420155, + 1994844 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 14012521, + -5024720, + -18384453, + -9578469, + -26485342, + -3936439, + -13033478, + -10909803, + 24319929, + -6446333 + ]), + FieldElement.fromList([ + 16412690, + -4507367, + 10772641, + 15929391, + -17068788, + -4658621, + 10555945, + -10484049, + -30102368, + -4739048 + ]), + FieldElement.fromList([ + 22397382, + -7767684, + -9293161, + -12792868, + 17166287, + -9755136, + -27333065, + 6199366, + 21880021, + -12250760 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -4283307, + 5368523, + -31117018, + 8163389, + -30323063, + 3209128, + 16557151, + 8890729, + 8840445, + 4957760 + ]), + FieldElement.fromList([ + -15447727, + 709327, + -6919446, + -10870178, + -29777922, + 6522332, + -21720181, + 12130072, + -14796503, + 5005757 + ]), + FieldElement.fromList([ + -2114751, + -14308128, + 23019042, + 15765735, + -25269683, + 6002752, + 10183197, + -13239326, + -16395286, + -2176112 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -19025756, + 1632005, + 13466291, + -7995100, + -23640451, + 16573537, + -32013908, + -3057104, + 22208662, + 2000468 + ]), + FieldElement.fromList([ + 3065073, + -1412761, + -25598674, + -361432, + -17683065, + -5703415, + -8164212, + 11248527, + -3691214, + -7414184 + ]), + FieldElement.fromList([ + 10379208, + -6045554, + 8877319, + 1473647, + -29291284, + -12507580, + 16690915, + 2553332, + -3132688, + 16400289 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15716668, + 1254266, + -18472690, + 7446274, + -8448918, + 6344164, + -22097271, + -7285580, + 26894937, + 9132066 + ]), + FieldElement.fromList([ + 24158887, + 12938817, + 11085297, + -8177598, + -28063478, + -4457083, + -30576463, + 64452, + -6817084, + -2692882 + ]), + FieldElement.fromList([ + 13488534, + 7794716, + 22236231, + 5989356, + 25426474, + -12578208, + 2350710, + -3418511, + -4688006, + 2364226 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 16335052, + 9132434, + 25640582, + 6678888, + 1725628, + 8517937, + -11807024, + -11697457, + 15445875, + -7798101 + ]), + FieldElement.fromList([ + 29004207, + -7867081, + 28661402, + -640412, + -12794003, + -7943086, + 31863255, + -4135540, + -278050, + -15759279 + ]), + FieldElement.fromList([ + -6122061, + -14866665, + -28614905, + 14569919, + -10857999, + -3591829, + 10343412, + -6976290, + -29828287, + -10815811 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 27081650, + 3463984, + 14099042, + -4517604, + 1616303, + -6205604, + 29542636, + 15372179, + 17293797, + 960709 + ]), + FieldElement.fromList([ + 20263915, + 11434237, + -5765435, + 11236810, + 13505955, + -10857102, + -16111345, + 6493122, + -19384511, + 7639714 + ]), + FieldElement.fromList([ + -2830798, + -14839232, + 25403038, + -8215196, + -8317012, + -16173699, + 18006287, + -16043750, + 29994677, + -15808121 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 9769828, + 5202651, + -24157398, + -13631392, + -28051003, + -11561624, + -24613141, + -13860782, + -31184575, + 709464 + ]), + FieldElement.fromList([ + 12286395, + 13076066, + -21775189, + -1176622, + -25003198, + 4057652, + -32018128, + -8890874, + 16102007, + 13205847 + ]), + FieldElement.fromList([ + 13733362, + 5599946, + 10557076, + 3195751, + -5557991, + 8536970, + -25540170, + 8525972, + 10151379, + 10394400 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 4024660, + -16137551, + 22436262, + 12276534, + -9099015, + -2686099, + 19698229, + 11743039, + -33302334, + 8934414 + ]), + FieldElement.fromList([ + -15879800, + -4525240, + -8580747, + -2934061, + 14634845, + -698278, + -9449077, + 3137094, + -11536886, + 11721158 + ]), + FieldElement.fromList([ + 17555939, + -5013938, + 8268606, + 2331751, + -22738815, + 9761013, + 9319229, + 8835153, + -9205489, + -1280045 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -461409, + -7830014, + 20614118, + 16688288, + -7514766, + -4807119, + 22300304, + 505429, + 6108462, + -6183415 + ]), + FieldElement.fromList([ + -5070281, + 12367917, + -30663534, + 3234473, + 32617080, + -8422642, + 29880583, + -13483331, + -26898490, + -7867459 + ]), + FieldElement.fromList([ + -31975283, + 5726539, + 26934134, + 10237677, + -3173717, + -605053, + 24199304, + 3795095, + 7592688, + -14992079 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 21594432, + -14964228, + 17466408, + -4077222, + 32537084, + 2739898, + 6407723, + 12018833, + -28256052, + 4298412 + ]), + FieldElement.fromList([ + -20650503, + -11961496, + -27236275, + 570498, + 3767144, + -1717540, + 13891942, + -1569194, + 13717174, + 10805743 + ]), + FieldElement.fromList([ + -14676630, + -15644296, + 15287174, + 11927123, + 24177847, + -8175568, + -796431, + 14860609, + -26938930, + -5863836 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 12962541, + 5311799, + -10060768, + 11658280, + 18855286, + -7954201, + 13286263, + -12808704, + -4381056, + 9882022 + ]), + FieldElement.fromList([ + 18512079, + 11319350, + -20123124, + 15090309, + 18818594, + 5271736, + -22727904, + 3666879, + -23967430, + -3299429 + ]), + FieldElement.fromList([ + -6789020, + -3146043, + 16192429, + 13241070, + 15898607, + -14206114, + -10084880, + -6661110, + -2403099, + 5276065 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30169808, + -5317648, + 26306206, + -11750859, + 27814964, + 7069267, + 7152851, + 3684982, + 1449224, + 13082861 + ]), + FieldElement.fromList([ + 10342826, + 3098505, + 2119311, + 193222, + 25702612, + 12233820, + 23697382, + 15056736, + -21016438, + -8202000 + ]), + FieldElement.fromList([ + -33150110, + 3261608, + 22745853, + 7948688, + 19370557, + -15177665, + -26171976, + 6482814, + -10300080, + -11060101 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 32869458, + -5408545, + 25609743, + 15678670, + -10687769, + -15471071, + 26112421, + 2521008, + -22664288, + 6904815 + ]), + FieldElement.fromList([ + 29506923, + 4457497, + 3377935, + -9796444, + -30510046, + 12935080, + 1561737, + 3841096, + -29003639, + -6657642 + ]), + FieldElement.fromList([ + 10340844, + -6630377, + -18656632, + -2278430, + 12621151, + -13339055, + 30878497, + -11824370, + -25584551, + 5181966 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 25940115, + -12658025, + 17324188, + -10307374, + -8671468, + 15029094, + 24396252, + -16450922, + -2322852, + -12388574 + ]), + FieldElement.fromList([ + -21765684, + 9916823, + -1300409, + 4079498, + -1028346, + 11909559, + 1782390, + 12641087, + 20603771, + -6561742 + ]), + FieldElement.fromList([ + -18882287, + -11673380, + 24849422, + 11501709, + 13161720, + -4768874, + 1925523, + 11914390, + 4662781, + 7820689 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 12241050, + -425982, + 8132691, + 9393934, + 32846760, + -1599620, + 29749456, + 12172924, + 16136752, + 15264020 + ]), + FieldElement.fromList([ + -10349955, + -14680563, + -8211979, + 2330220, + -17662549, + -14545780, + 10658213, + 6671822, + 19012087, + 3772772 + ]), + FieldElement.fromList([ + 3753511, + -3421066, + 10617074, + 2028709, + 14841030, + -6721664, + 28718732, + -15762884, + 20527771, + 12988982 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -14822485, + -5797269, + -3707987, + 12689773, + -898983, + -10914866, + -24183046, + -10564943, + 3299665, + -12424953 + ]), + FieldElement.fromList([ + -16777703, + -15253301, + -9642417, + 4978983, + 3308785, + 8755439, + 6943197, + 6461331, + -25583147, + 8991218 + ]), + FieldElement.fromList([ + -17226263, + 1816362, + -1673288, + -6086439, + 31783888, + -8175991, + -32948145, + 7417950, + -30242287, + 1507265 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 29692663, + 6829891, + -10498800, + 4334896, + 20945975, + -11906496, + -28887608, + 8209391, + 14606362, + -10647073 + ]), + FieldElement.fromList([ + -3481570, + 8707081, + 32188102, + 5672294, + 22096700, + 1711240, + -33020695, + 9761487, + 4170404, + -2085325 + ]), + FieldElement.fromList([ + -11587470, + 14855945, + -4127778, + -1531857, + -26649089, + 15084046, + 22186522, + 16002000, + -14276837, + -8400798 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -4811456, + 13761029, + -31703877, + -2483919, + -3312471, + 7869047, + -7113572, + -9620092, + 13240845, + 10965870 + ]), + FieldElement.fromList([ + -7742563, + -8256762, + -14768334, + -13656260, + -23232383, + 12387166, + 4498947, + 14147411, + 29514390, + 4302863 + ]), + FieldElement.fromList([ + -13413405, + -12407859, + 20757302, + -13801832, + 14785143, + 8976368, + -5061276, + -2144373, + 17846988, + -13971927 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -2244452, + -754728, + -4597030, + -1066309, + -6247172, + 1455299, + -21647728, + -9214789, + -5222701, + 12650267 + ]), + FieldElement.fromList([ + -9906797, + -16070310, + 21134160, + 12198166, + -27064575, + 708126, + 387813, + 13770293, + -19134326, + 10958663 + ]), + FieldElement.fromList([ + 22470984, + 12369526, + 23446014, + -5441109, + -21520802, + -9698723, + -11772496, + -11574455, + -25083830, + 4271862 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25169565, + -10053642, + -19909332, + 15361595, + -5984358, + 2159192, + 75375, + -4278529, + -32526221, + 8469673 + ]), + FieldElement.fromList([ + 15854970, + 4148314, + -8893890, + 7259002, + 11666551, + 13824734, + -30531198, + 2697372, + 24154791, + -9460943 + ]), + FieldElement.fromList([ + 15446137, + -15806644, + 29759747, + 14019369, + 30811221, + -9610191, + -31582008, + 12840104, + 24913809, + 9815020 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -4709286, + -5614269, + -31841498, + -12288893, + -14443537, + 10799414, + -9103676, + 13438769, + 18735128, + 9466238 + ]), + FieldElement.fromList([ + 11933045, + 9281483, + 5081055, + -5183824, + -2628162, + -4905629, + -7727821, + -10896103, + -22728655, + 16199064 + ]), + FieldElement.fromList([ + 14576810, + 379472, + -26786533, + -8317236, + -29426508, + -10812974, + -102766, + 1876699, + 30801119, + 2164795 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15995086, + 3199873, + 13672555, + 13712240, + -19378835, + -4647646, + -13081610, + -15496269, + -13492807, + 1268052 + ]), + FieldElement.fromList([ + -10290614, + -3659039, + -3286592, + 10948818, + 23037027, + 3794475, + -3470338, + -12600221, + -17055369, + 3565904 + ]), + FieldElement.fromList([ + 29210088, + -9419337, + -5919792, + -4952785, + 10834811, + -13327726, + -16512102, + -10820713, + -27162222, + -14030531 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -13161890, + 15508588, + 16663704, + -8156150, + -28349942, + 9019123, + -29183421, + -3769423, + 2244111, + -14001979 + ]), + FieldElement.fromList([ + -5152875, + -3800936, + -9306475, + -6071583, + 16243069, + 14684434, + -25673088, + -16180800, + 13491506, + 4641841 + ]), + FieldElement.fromList([ + 10813417, + 643330, + -19188515, + -728916, + 30292062, + -16600078, + 27548447, + -7721242, + 14476989, + -12767431 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 10292079, + 9984945, + 6481436, + 8279905, + -7251514, + 7032743, + 27282937, + -1644259, + -27912810, + 12651324 + ]), + FieldElement.fromList([ + -31185513, + -813383, + 22271204, + 11835308, + 10201545, + 15351028, + 17099662, + 3988035, + 21721536, + -3148940 + ]), + FieldElement.fromList([ + 10202177, + -6545839, + -31373232, + -9574638, + -32150642, + -8119683, + -12906320, + 3852694, + 13216206, + 14842320 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -15815640, + -10601066, + -6538952, + -7258995, + -6984659, + -6581778, + -31500847, + 13765824, + -27434397, + 9900184 + ]), + FieldElement.fromList([ + 14465505, + -13833331, + -32133984, + -14738873, + -27443187, + 12990492, + 33046193, + 15796406, + -7051866, + -8040114 + ]), + FieldElement.fromList([ + 30924417, + -8279620, + 6359016, + -12816335, + 16508377, + 9071735, + -25488601, + 15413635, + 9524356, + -7018878 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 12274201, + -13175547, + 32627641, + -1785326, + 6736625, + 13267305, + 5237659, + -5109483, + 15663516, + 4035784 + ]), + FieldElement.fromList([ + -2951309, + 8903985, + 17349946, + 601635, + -16432815, + -4612556, + -13732739, + -15889334, + -22258478, + 4659091 + ]), + FieldElement.fromList([ + -16916263, + -4952973, + -30393711, + -15158821, + 20774812, + 15897498, + 5736189, + 15026997, + -2178256, + -13455585 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -8858980, + -2219056, + 28571666, + -10155518, + -474467, + -10105698, + -3801496, + 278095, + 23440562, + -290208 + ]), + FieldElement.fromList([ + 10226241, + -5928702, + 15139956, + 120818, + -14867693, + 5218603, + 32937275, + 11551483, + -16571960, + -7442864 + ]), + FieldElement.fromList([ + 17932739, + -12437276, + -24039557, + 10749060, + 11316803, + 7535897, + 22503767, + 5561594, + -3646624, + 3898661 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 7749907, + -969567, + -16339731, + -16464, + -25018111, + 15122143, + -1573531, + 7152530, + 21831162, + 1245233 + ]), + FieldElement.fromList([ + 26958459, + -14658026, + 4314586, + 8346991, + -5677764, + 11960072, + -32589295, + -620035, + -30402091, + -16716212 + ]), + FieldElement.fromList([ + -12165896, + 9166947, + 33491384, + 13673479, + 29787085, + 13096535, + 6280834, + 14587357, + -22338025, + 13987525 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -24349909, + 7778775, + 21116000, + 15572597, + -4833266, + -5357778, + -4300898, + -5124639, + -7469781, + -2858068 + ]), + FieldElement.fromList([ + 9681908, + -6737123, + -31951644, + 13591838, + -6883821, + 386950, + 31622781, + 6439245, + -14581012, + 4091397 + ]), + FieldElement.fromList([ + -8426427, + 1470727, + -28109679, + -1596990, + 3978627, + -5123623, + -19622683, + 12092163, + 29077877, + -14741988 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 5269168, + -6859726, + -13230211, + -8020715, + 25932563, + 1763552, + -5606110, + -5505881, + -20017847, + 2357889 + ]), + FieldElement.fromList([ + 32264008, + -15407652, + -5387735, + -1160093, + -2091322, + -3946900, + 23104804, + -12869908, + 5727338, + 189038 + ]), + FieldElement.fromList([ + 14609123, + -8954470, + -6000566, + -16622781, + -14577387, + -7743898, + -26745169, + 10942115, + -25888931, + -14884697 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 20513500, + 5557931, + -15604613, + 7829531, + 26413943, + -2019404, + -21378968, + 7471781, + 13913677, + -5137875 + ]), + FieldElement.fromList([ + -25574376, + 11967826, + 29233242, + 12948236, + -6754465, + 4713227, + -8940970, + 14059180, + 12878652, + 8511905 + ]), + FieldElement.fromList([ + -25656801, + 3393631, + -2955415, + -7075526, + -2250709, + 9366908, + -30223418, + 6812974, + 5568676, + -3127656 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 11630004, + 12144454, + 2116339, + 13606037, + 27378885, + 15676917, + -17408753, + -13504373, + -14395196, + 8070818 + ]), + FieldElement.fromList([ + 27117696, + -10007378, + -31282771, + -5570088, + 1127282, + 12772488, + -29845906, + 10483306, + -11552749, + -1028714 + ]), + FieldElement.fromList([ + 10637467, + -5688064, + 5674781, + 1072708, + -26343588, + -6982302, + -1683975, + 9177853, + -27493162, + 15431203 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 20525145, + 10892566, + -12742472, + 12779443, + -29493034, + 16150075, + -28240519, + 14943142, + -15056790, + -7935931 + ]), + FieldElement.fromList([ + -30024462, + 5626926, + -551567, + -9981087, + 753598, + 11981191, + 25244767, + -3239766, + -3356550, + 9594024 + ]), + FieldElement.fromList([ + -23752644, + 2636870, + -5163910, + -10103818, + 585134, + 7877383, + 11345683, + -6492290, + 13352335, + -10977084 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -1931799, + -5407458, + 3304649, + -12884869, + 17015806, + -4877091, + -29783850, + -7752482, + -13215537, + -319204 + ]), + FieldElement.fromList([ + 20239939, + 6607058, + 6203985, + 3483793, + -18386976, + -779229, + -20723742, + 15077870, + -22750759, + 14523817 + ]), + FieldElement.fromList([ + 27406042, + -6041657, + 27423596, + -4497394, + 4996214, + 10002360, + -28842031, + -4545494, + -30172742, + -4805667 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 11374242, + 12660715, + 17861383, + -12540833, + 10935568, + 1099227, + -13886076, + -9091740, + -27727044, + 11358504 + ]), + FieldElement.fromList([ + -12730809, + 10311867, + 1510375, + 10778093, + -2119455, + -9145702, + 32676003, + 11149336, + -26123651, + 4985768 + ]), + FieldElement.fromList([ + -19096303, + 341147, + -6197485, + -239033, + 15756973, + -8796662, + -983043, + 13794114, + -19414307, + -15621255 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 6490081, + 11940286, + 25495923, + -7726360, + 8668373, + -8751316, + 3367603, + 6970005, + -1691065, + -9004790 + ]), + FieldElement.fromList([ + 1656497, + 13457317, + 15370807, + 6364910, + 13605745, + 8362338, + -19174622, + -5475723, + -16796596, + -5031438 + ]), + FieldElement.fromList([ + -22273315, + -13524424, + -64685, + -4334223, + -18605636, + -10921968, + -20571065, + -7007978, + -99853, + -10237333 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 17747465, + 10039260, + 19368299, + -4050591, + -20630635, + -16041286, + 31992683, + -15857976, + -29260363, + -5511971 + ]), + FieldElement.fromList([ + 31932027, + -4986141, + -19612382, + 16366580, + 22023614, + 88450, + 11371999, + -3744247, + 4882242, + -10626905 + ]), + FieldElement.fromList([ + 29796507, + 37186, + 19818052, + 10115756, + -11829032, + 3352736, + 18551198, + 3272828, + -5190932, + -4162409 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 12501286, + 4044383, + -8612957, + -13392385, + -32430052, + 5136599, + -19230378, + -3529697, + 330070, + -3659409 + ]), + FieldElement.fromList([ + 6384877, + 2899513, + 17807477, + 7663917, + -2358888, + 12363165, + 25366522, + -8573892, + -271295, + 12071499 + ]), + FieldElement.fromList([ + -8365515, + -4042521, + 25133448, + -4517355, + -6211027, + 2265927, + -32769618, + 1936675, + -5159697, + 3829363 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 28425966, + -5835433, + -577090, + -4697198, + -14217555, + 6870930, + 7921550, + -6567787, + 26333140, + 14267664 + ]), + FieldElement.fromList([ + -11067219, + 11871231, + 27385719, + -10559544, + -4585914, + -11189312, + 10004786, + -8709488, + -21761224, + 8930324 + ]), + FieldElement.fromList([ + -21197785, + -16396035, + 25654216, + -1725397, + 12282012, + 11008919, + 1541940, + 4757911, + -26491501, + -16408940 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 13537262, + -7759490, + -20604840, + 10961927, + -5922820, + -13218065, + -13156584, + 6217254, + -15943699, + 13814990 + ]), + FieldElement.fromList([ + -17422573, + 15157790, + 18705543, + 29619, + 24409717, + -260476, + 27361681, + 9257833, + -1956526, + -1776914 + ]), + FieldElement.fromList([ + -25045300, + -10191966, + 15366585, + 15166509, + -13105086, + 8423556, + -29171540, + 12361135, + -18685978, + 4578290 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 24579768, + 3711570, + 1342322, + -11180126, + -27005135, + 14124956, + -22544529, + 14074919, + 21964432, + 8235257 + ]), + FieldElement.fromList([ + -6528613, + -2411497, + 9442966, + -5925588, + 12025640, + -1487420, + -2981514, + -1669206, + 13006806, + 2355433 + ]), + FieldElement.fromList([ + -16304899, + -13605259, + -6632427, + -5142349, + 16974359, + -10911083, + 27202044, + 1719366, + 1141648, + -12796236 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12863944, + -13219986, + -8318266, + -11018091, + -6810145, + -4843894, + 13475066, + -3133972, + 32674895, + 13715045 + ]), + FieldElement.fromList([ + 11423335, + -5468059, + 32344216, + 8962751, + 24989809, + 9241752, + -13265253, + 16086212, + -28740881, + -15642093 + ]), + FieldElement.fromList([ + -1409668, + 12530728, + -6368726, + 10847387, + 19531186, + -14132160, + -11709148, + 7791794, + -27245943, + 4383347 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -28970898, + 5271447, + -1266009, + -9736989, + -12455236, + 16732599, + -4862407, + -4906449, + 27193557, + 6245191 + ]), + FieldElement.fromList([ + -15193956, + 5362278, + -1783893, + 2695834, + 4960227, + 12840725, + 23061898, + 3260492, + 22510453, + 8577507 + ]), + FieldElement.fromList([ + -12632451, + 11257346, + -32692994, + 13548177, + -721004, + 10879011, + 31168030, + 13952092, + -29571492, + -3635906 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 3877321, + -9572739, + 32416692, + 5405324, + -11004407, + -13656635, + 3759769, + 11935320, + 5611860, + 8164018 + ]), + FieldElement.fromList([ + -16275802, + 14667797, + 15906460, + 12155291, + -22111149, + -9039718, + 32003002, + -8832289, + 5773085, + -8422109 + ]), + FieldElement.fromList([ + -23788118, + -8254300, + 1950875, + 8937633, + 18686727, + 16459170, + -905725, + 12376320, + 31632953, + 190926 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -24593607, + -16138885, + -8423991, + 13378746, + 14162407, + 6901328, + -8288749, + 4508564, + -25341555, + -3627528 + ]), + FieldElement.fromList([ + 8884438, + -5884009, + 6023974, + 10104341, + -6881569, + -4941533, + 18722941, + -14786005, + -1672488, + 827625 + ]), + FieldElement.fromList([ + -32720583, + -16289296, + -32503547, + 7101210, + 13354605, + 2659080, + -1800575, + -14108036, + -24878478, + 1541286 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 2901347, + -1117687, + 3880376, + -10059388, + -17620940, + -3612781, + -21802117, + -3567481, + 20456845, + -1885033 + ]), + FieldElement.fromList([ + 27019610, + 12299467, + -13658288, + -1603234, + -12861660, + -4861471, + -19540150, + -5016058, + 29439641, + 15138866 + ]), + FieldElement.fromList([ + 21536104, + -6626420, + -32447818, + -10690208, + -22408077, + 5175814, + -5420040, + -16361163, + 7779328, + 109896 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30279744, + 14648750, + -8044871, + 6425558, + 13639621, + -743509, + 28698390, + 12180118, + 23177719, + -554075 + ]), + FieldElement.fromList([ + 26572847, + 3405927, + -31701700, + 12890905, + -19265668, + 5335866, + -6493768, + 2378492, + 4439158, + -13279347 + ]), + FieldElement.fromList([ + -22716706, + 3489070, + -9225266, + -332753, + 18875722, + -1140095, + 14819434, + -12731527, + -17717757, + -5461437 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -5056483, + 16566551, + 15953661, + 3767752, + -10436499, + 15627060, + -820954, + 2177225, + 8550082, + -15114165 + ]), + FieldElement.fromList([ + -18473302, + 16596775, + -381660, + 15663611, + 22860960, + 15585581, + -27844109, + -3582739, + -23260460, + -8428588 + ]), + FieldElement.fromList([ + -32480551, + 15707275, + -8205912, + -5652081, + 29464558, + 2713815, + -22725137, + 15860482, + -21902570, + 1494193 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -19562091, + -14087393, + -25583872, + -9299552, + 13127842, + 759709, + 21923482, + 16529112, + 8742704, + 12967017 + ]), + FieldElement.fromList([ + -28464899, + 1553205, + 32536856, + -10473729, + -24691605, + -406174, + -8914625, + -2933896, + -29903758, + 15553883 + ]), + FieldElement.fromList([ + 21877909, + 3230008, + 9881174, + 10539357, + -4797115, + 2841332, + 11543572, + 14513274, + 19375923, + -12647961 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 8832269, + -14495485, + 13253511, + 5137575, + 5037871, + 4078777, + 24880818, + -6222716, + 2862653, + 9455043 + ]), + FieldElement.fromList([ + 29306751, + 5123106, + 20245049, + -14149889, + 9592566, + 8447059, + -2077124, + -2990080, + 15511449, + 4789663 + ]), + FieldElement.fromList([ + -20679756, + 7004547, + 8824831, + -9434977, + -4045704, + -3750736, + -5754762, + 108893, + 23513200, + 16652362 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -33256173, + 4144782, + -4476029, + -6579123, + 10770039, + -7155542, + -6650416, + -12936300, + -18319198, + 10212860 + ]), + FieldElement.fromList([ + 2756081, + 8598110, + 7383731, + -6859892, + 22312759, + -1105012, + 21179801, + 2600940, + -9988298, + -12506466 + ]), + FieldElement.fromList([ + -24645692, + 13317462, + -30449259, + -15653928, + 21365574, + -10869657, + 11344424, + 864440, + -2499677, + -16710063 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -26432803, + 6148329, + -17184412, + -14474154, + 18782929, + -275997, + -22561534, + 211300, + 2719757, + 4940997 + ]), + FieldElement.fromList([ + -1323882, + 3911313, + -6948744, + 14759765, + -30027150, + 7851207, + 21690126, + 8518463, + 26699843, + 5276295 + ]), + FieldElement.fromList([ + -13149873, + -6429067, + 9396249, + 365013, + 24703301, + -10488939, + 1321586, + 149635, + -15452774, + 7159369 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 9987780, + -3404759, + 17507962, + 9505530, + 9731535, + -2165514, + 22356009, + 8312176, + 22477218, + -8403385 + ]), + FieldElement.fromList([ + 18155857, + -16504990, + 19744716, + 9006923, + 15154154, + -10538976, + 24256460, + -4864995, + -22548173, + 9334109 + ]), + FieldElement.fromList([ + 2986088, + -4911893, + 10776628, + -3473844, + 10620590, + -7083203, + -21413845, + 14253545, + -22587149, + 536906 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 4377756, + 8115836, + 24567078, + 15495314, + 11625074, + 13064599, + 7390551, + 10589625, + 10838060, + -15420424 + ]), + FieldElement.fromList([ + -19342404, + 867880, + 9277171, + -3218459, + -14431572, + -1986443, + 19295826, + -15796950, + 6378260, + 699185 + ]), + FieldElement.fromList([ + 7895026, + 4057113, + -7081772, + -13077756, + -17886831, + -323126, + -716039, + 15693155, + -5045064, + -13373962 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -7737563, + -5869402, + -14566319, + -7406919, + 11385654, + 13201616, + 31730678, + -10962840, + -3918636, + -9669325 + ]), + FieldElement.fromList([ + 10188286, + -15770834, + -7336361, + 13427543, + 22223443, + 14896287, + 30743455, + 7116568, + -21786507, + 5427593 + ]), + FieldElement.fromList([ + 696102, + 13206899, + 27047647, + -10632082, + 15285305, + -9853179, + 10798490, + -4578720, + 19236243, + 12477404 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -11229439, + 11243796, + -17054270, + -8040865, + -788228, + -8167967, + -3897669, + 11180504, + -23169516, + 7733644 + ]), + FieldElement.fromList([ + 17800790, + -14036179, + -27000429, + -11766671, + 23887827, + 3149671, + 23466177, + -10538171, + 10322027, + 15313801 + ]), + FieldElement.fromList([ + 26246234, + 11968874, + 32263343, + -5468728, + 6830755, + -13323031, + -15794704, + -101982, + -24449242, + 10890804 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -31365647, + 10271363, + -12660625, + -6267268, + 16690207, + -13062544, + -14982212, + 16484931, + 25180797, + -5334884 + ]), + FieldElement.fromList([ + -586574, + 10376444, + -32586414, + -11286356, + 19801893, + 10997610, + 2276632, + 9482883, + 316878, + 13820577 + ]), + FieldElement.fromList([ + -9882808, + -4510367, + -2115506, + 16457136, + -11100081, + 11674996, + 30756178, + -7515054, + 30696930, + -3712849 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 32988917, + -9603412, + 12499366, + 7910787, + -10617257, + -11931514, + -7342816, + -9985397, + -32349517, + 7392473 + ]), + FieldElement.fromList([ + -8855661, + 15927861, + 9866406, + -3649411, + -2396914, + -16655781, + -30409476, + -9134995, + 25112947, + -2926644 + ]), + FieldElement.fromList([ + -2504044, + -436966, + 25621774, + -5678772, + 15085042, + -5479877, + -24884878, + -13526194, + 5537438, + -13914319 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -11225584, + 2320285, + -9584280, + 10149187, + -33444663, + 5808648, + -14876251, + -1729667, + 31234590, + 6090599 + ]), + FieldElement.fromList([ + -9633316, + 116426, + 26083934, + 2897444, + -6364437, + -2688086, + 609721, + 15878753, + -6970405, + -9034768 + ]), + FieldElement.fromList([ + -27757857, + 247744, + -15194774, + -9002551, + 23288161, + -10011936, + -23869595, + 6503646, + 20650474, + 1804084 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -27589786, + 15456424, + 8972517, + 8469608, + 15640622, + 4439847, + 3121995, + -10329713, + 27842616, + -202328 + ]), + FieldElement.fromList([ + -15306973, + 2839644, + 22530074, + 10026331, + 4602058, + 5048462, + 28248656, + 5031932, + -11375082, + 12714369 + ]), + FieldElement.fromList([ + 20807691, + -7270825, + 29286141, + 11421711, + -27876523, + -13868230, + -21227475, + 1035546, + -19733229, + 12796920 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 12076899, + -14301286, + -8785001, + -11848922, + -25012791, + 16400684, + -17591495, + -12899438, + 3480665, + -15182815 + ]), + FieldElement.fromList([ + -32361549, + 5457597, + 28548107, + 7833186, + 7303070, + -11953545, + -24363064, + -15921875, + -33374054, + 2771025 + ]), + FieldElement.fromList([ + -21389266, + 421932, + 26597266, + 6860826, + 22486084, + -6737172, + -17137485, + -4210226, + -24552282, + 15673397 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -20184622, + 2338216, + 19788685, + -9620956, + -4001265, + -8740893, + -20271184, + 4733254, + 3727144, + -12934448 + ]), + FieldElement.fromList([ + 6120119, + 814863, + -11794402, + -622716, + 6812205, + -15747771, + 2019594, + 7975683, + 31123697, + -10958981 + ]), + FieldElement.fromList([ + 30069250, + -11435332, + 30434654, + 2958439, + 18399564, + -976289, + 12296869, + 9204260, + -16432438, + 9648165 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 32705432, + -1550977, + 30705658, + 7451065, + -11805606, + 9631813, + 3305266, + 5248604, + -26008332, + -11377501 + ]), + FieldElement.fromList([ + 17219865, + 2375039, + -31570947, + -5575615, + -19459679, + 9219903, + 294711, + 15298639, + 2662509, + -16297073 + ]), + FieldElement.fromList([ + -1172927, + -7558695, + -4366770, + -4287744, + -21346413, + -8434326, + 32087529, + -1222777, + 32247248, + -14389861 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 14312628, + 1221556, + 17395390, + -8700143, + -4945741, + -8684635, + -28197744, + -9637817, + -16027623, + -13378845 + ]), + FieldElement.fromList([ + -1428825, + -9678990, + -9235681, + 6549687, + -7383069, + -468664, + 23046502, + 9803137, + 17597934, + 2346211 + ]), + FieldElement.fromList([ + 18510800, + 15337574, + 26171504, + 981392, + -22241552, + 7827556, + -23491134, + -11323352, + 3059833, + -11782870 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 10141598, + 6082907, + 17829293, + -1947643, + 9830092, + 13613136, + -25556636, + -5544586, + -33502212, + 3592096 + ]), + FieldElement.fromList([ + 33114168, + -15889352, + -26525686, + -13343397, + 33076705, + 8716171, + 1151462, + 1521897, + -982665, + -6837803 + ]), + FieldElement.fromList([ + -32939165, + -4255815, + 23947181, + -324178, + -33072974, + -12305637, + -16637686, + 3891704, + 26353178, + 693168 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30374239, + 1595580, + -16884039, + 13186931, + 4600344, + 406904, + 9585294, + -400668, + 31375464, + 14369965 + ]), + FieldElement.fromList([ + -14370654, + -7772529, + 1510301, + 6434173, + -18784789, + -6262728, + 32732230, + -13108839, + 17901441, + 16011505 + ]), + FieldElement.fromList([ + 18171223, + -11934626, + -12500402, + 15197122, + -11038147, + -15230035, + -19172240, + -16046376, + 8764035, + 12309598 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 5975908, + -5243188, + -19459362, + -9681747, + -11541277, + 14015782, + -23665757, + 1228319, + 17544096, + -10593782 + ]), + FieldElement.fromList([ + 5811932, + -1715293, + 3442887, + -2269310, + -18367348, + -8359541, + -18044043, + -15410127, + -5565381, + 12348900 + ]), + FieldElement.fromList([ + -31399660, + 11407555, + 25755363, + 6891399, + -3256938, + 14872274, + -24849353, + 8141295, + -10632534, + -585479 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12675304, + 694026, + -5076145, + 13300344, + 14015258, + -14451394, + -9698672, + -11329050, + 30944593, + 1130208 + ]), + FieldElement.fromList([ + 8247766, + -6710942, + -26562381, + -7709309, + -14401939, + -14648910, + 4652152, + 2488540, + 23550156, + -271232 + ]), + FieldElement.fromList([ + 17294316, + -3788438, + 7026748, + 15626851, + 22990044, + 113481, + 2267737, + -5908146, + -408818, + -137719 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 16091085, + -16253926, + 18599252, + 7340678, + 2137637, + -1221657, + -3364161, + 14550936, + 3260525, + -7166271 + ]), + FieldElement.fromList([ + -4910104, + -13332887, + 18550887, + 10864893, + -16459325, + -7291596, + -23028869, + -13204905, + -12748722, + 2701326 + ]), + FieldElement.fromList([ + -8574695, + 16099415, + 4629974, + -16340524, + -20786213, + -6005432, + -10018363, + 9276971, + 11329923, + 1862132 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 14763076, + -15903608, + -30918270, + 3689867, + 3511892, + 10313526, + -21951088, + 12219231, + -9037963, + -940300 + ]), + FieldElement.fromList([ + 8894987, + -3446094, + 6150753, + 3013931, + 301220, + 15693451, + -31981216, + -2909717, + -15438168, + 11595570 + ]), + FieldElement.fromList([ + 15214962, + 3537601, + -26238722, + -14058872, + 4418657, + -15230761, + 13947276, + 10730794, + -13489462, + -4363670 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -2538306, + 7682793, + 32759013, + 263109, + -29984731, + -7955452, + -22332124, + -10188635, + 977108, + 699994 + ]), + FieldElement.fromList([ + -12466472, + 4195084, + -9211532, + 550904, + -15565337, + 12917920, + 19118110, + -439841, + -30534533, + -14337913 + ]), + FieldElement.fromList([ + 31788461, + -14507657, + 4799989, + 7372237, + 8808585, + -14747943, + 9408237, + -10051775, + 12493932, + -5409317 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25680606, + 5260744, + -19235809, + -6284470, + -3695942, + 16566087, + 27218280, + 2607121, + 29375955, + 6024730 + ]), + FieldElement.fromList([ + 842132, + -2794693, + -4763381, + -8722815, + 26332018, + -12405641, + 11831880, + 6985184, + -9940361, + 2854096 + ]), + FieldElement.fromList([ + -4847262, + -7969331, + 2516242, + -5847713, + 9695691, + -7221186, + 16512645, + 960770, + 12121869, + 16648078 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -15218652, + 14667096, + -13336229, + 2013717, + 30598287, + -464137, + -31504922, + -7882064, + 20237806, + 2838411 + ]), + FieldElement.fromList([ + -19288047, + 4453152, + 15298546, + -16178388, + 22115043, + -15972604, + 12544294, + -13470457, + 1068881, + -12499905 + ]), + FieldElement.fromList([ + -9558883, + -16518835, + 33238498, + 13506958, + 30505848, + -1114596, + -8486907, + -2630053, + 12521378, + 4845654 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -28198521, + 10744108, + -2958380, + 10199664, + 7759311, + -13088600, + 3409348, + -873400, + -6482306, + -12885870 + ]), + FieldElement.fromList([ + -23561822, + 6230156, + -20382013, + 10655314, + -24040585, + -11621172, + 10477734, + -1240216, + -3113227, + 13974498 + ]), + FieldElement.fromList([ + 12966261, + 15550616, + -32038948, + -1615346, + 21025980, + -629444, + 5642325, + 7188737, + 18895762, + 12629579 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 14741879, + -14946887, + 22177208, + -11721237, + 1279741, + 8058600, + 11758140, + 789443, + 32195181, + 3895677 + ]), + FieldElement.fromList([ + 10758205, + 15755439, + -4509950, + 9243698, + -4879422, + 6879879, + -2204575, + -3566119, + -8982069, + 4429647 + ]), + FieldElement.fromList([ + -2453894, + 15725973, + -20436342, + -10410672, + -5803908, + -11040220, + -7135870, + -11642895, + 18047436, + -15281743 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25173001, + -11307165, + 29759956, + 11776784, + -22262383, + -15820455, + 10993114, + -12850837, + -17620701, + -9408468 + ]), + FieldElement.fromList([ + 21987233, + 700364, + -24505048, + 14972008, + -7774265, + -5718395, + 32155026, + 2581431, + -29958985, + 8773375 + ]), + FieldElement.fromList([ + -25568350, + 454463, + -13211935, + 16126715, + 25240068, + 8594567, + 20656846, + 12017935, + -7874389, + -13920155 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 6028182, + 6263078, + -31011806, + -11301710, + -818919, + 2461772, + -31841174, + -5468042, + -1721788, + -2776725 + ]), + FieldElement.fromList([ + -12278994, + 16624277, + 987579, + -5922598, + 32908203, + 1248608, + 7719845, + -4166698, + 28408820, + 6816612 + ]), + FieldElement.fromList([ + -10358094, + -8237829, + 19549651, + -12169222, + 22082623, + 16147817, + 20613181, + 13982702, + -10339570, + 5067943 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -30505967, + -3821767, + 12074681, + 13582412, + -19877972, + 2443951, + -19719286, + 12746132, + 5331210, + -10105944 + ]), + FieldElement.fromList([ + 30528811, + 3601899, + -1957090, + 4619785, + -27361822, + -15436388, + 24180793, + -12570394, + 27679908, + -1648928 + ]), + FieldElement.fromList([ + 9402404, + -13957065, + 32834043, + 10838634, + -26580150, + -13237195, + 26653274, + -8685565, + 22611444, + -12715406 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 22190590, + 1118029, + 22736441, + 15130463, + -30460692, + -5991321, + 19189625, + -4648942, + 4854859, + 6622139 + ]), + FieldElement.fromList([ + -8310738, + -2953450, + -8262579, + -3388049, + -10401731, + -271929, + 13424426, + -3567227, + 26404409, + 13001963 + ]), + FieldElement.fromList([ + -31241838, + -15415700, + -2994250, + 8939346, + 11562230, + -12840670, + -26064365, + -11621720, + -15405155, + 11020693 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 1866042, + -7949489, + -7898649, + -10301010, + 12483315, + 13477547, + 3175636, + -12424163, + 28761762, + 1406734 + ]), + FieldElement.fromList([ + -448555, + -1777666, + 13018551, + 3194501, + -9580420, + -11161737, + 24760585, + -4347088, + 25577411, + -13378680 + ]), + FieldElement.fromList([ + -24290378, + 4759345, + -690653, + -1852816, + 2066747, + 10693769, + -29595790, + 9884936, + -9368926, + 4745410 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -9141284, + 6049714, + -19531061, + -4341411, + -31260798, + 9944276, + -15462008, + -11311852, + 10931924, + -11931931 + ]), + FieldElement.fromList([ + -16561513, + 14112680, + -8012645, + 4817318, + -8040464, + -11414606, + -22853429, + 10856641, + -20470770, + 13434654 + ]), + FieldElement.fromList([ + 22759489, + -10073434, + -16766264, + -1871422, + 13637442, + -10168091, + 1765144, + -12654326, + 28445307, + -5364710 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 29875063, + 12493613, + 2795536, + -3786330, + 1710620, + 15181182, + -10195717, + -8788675, + 9074234, + 1167180 + ]), + FieldElement.fromList([ + -26205683, + 11014233, + -9842651, + -2635485, + -26908120, + 7532294, + -18716888, + -9535498, + 3843903, + 9367684 + ]), + FieldElement.fromList([ + -10969595, + -6403711, + 9591134, + 9582310, + 11349256, + 108879, + 16235123, + 8601684, + -139197, + 4242895 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 22092954, + -13191123, + -2042793, + -11968512, + 32186753, + -11517388, + -6574341, + 2470660, + -27417366, + 16625501 + ]), + FieldElement.fromList([ + -11057722, + 3042016, + 13770083, + -9257922, + 584236, + -544855, + -7770857, + 2602725, + -27351616, + 14247413 + ]), + FieldElement.fromList([ + 6314175, + -10264892, + -32772502, + 15957557, + -10157730, + 168750, + -8618807, + 14290061, + 27108877, + -1180880 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -8586597, + -7170966, + 13241782, + 10960156, + -32991015, + -13794596, + 33547976, + -11058889, + -27148451, + 981874 + ]), + FieldElement.fromList([ + 22833440, + 9293594, + -32649448, + -13618667, + -9136966, + 14756819, + -22928859, + -13970780, + -10479804, + -16197962 + ]), + FieldElement.fromList([ + -7768587, + 3326786, + -28111797, + 10783824, + 19178761, + 14905060, + 22680049, + 13906969, + -15933690, + 3797899 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 21721356, + -4212746, + -12206123, + 9310182, + -3882239, + -13653110, + 23740224, + -2709232, + 20491983, + -8042152 + ]), + FieldElement.fromList([ + 9209270, + -15135055, + -13256557, + -6167798, + -731016, + 15289673, + 25947805, + 15286587, + 30997318, + -6703063 + ]), + FieldElement.fromList([ + 7392032, + 16618386, + 23946583, + -8039892, + -13265164, + -1533858, + -14197445, + -2321576, + 17649998, + -250080 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -9301088, + -14193827, + 30609526, + -3049543, + -25175069, + -1283752, + -15241566, + -9525724, + -2233253, + 7662146 + ]), + FieldElement.fromList([ + -17558673, + 1763594, + -33114336, + 15908610, + -30040870, + -12174295, + 7335080, + -8472199, + -3174674, + 3440183 + ]), + FieldElement.fromList([ + -19889700, + -5977008, + -24111293, + -9688870, + 10799743, + -16571957, + 40450, + -4431835, + 4862400, + 1133 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -32856209, + -7873957, + -5422389, + 14860950, + -16319031, + 7956142, + 7258061, + 311861, + -30594991, + -7379421 + ]), + FieldElement.fromList([ + -3773428, + -1565936, + 28985340, + 7499440, + 24445838, + 9325937, + 29727763, + 16527196, + 18278453, + 15405622 + ]), + FieldElement.fromList([ + -4381906, + 8508652, + -19898366, + -3674424, + -5984453, + 15149970, + -13313598, + 843523, + -21875062, + 13626197 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 2281448, + -13487055, + -10915418, + -2609910, + 1879358, + 16164207, + -10783882, + 3953792, + 13340839, + 15928663 + ]), + FieldElement.fromList([ + 31727126, + -7179855, + -18437503, + -8283652, + 2875793, + -16390330, + -25269894, + -7014826, + -23452306, + 5964753 + ]), + FieldElement.fromList([ + 4100420, + -5959452, + -17179337, + 6017714, + -18705837, + 12227141, + -26684835, + 11344144, + 2538215, + -7570755 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -9433605, + 6123113, + 11159803, + -2156608, + 30016280, + 14966241, + -20474983, + 1485421, + -629256, + -15958862 + ]), + FieldElement.fromList([ + -26804558, + 4260919, + 11851389, + 9658551, + -32017107, + 16367492, + -20205425, + -13191288, + 11659922, + -11115118 + ]), + FieldElement.fromList([ + 26180396, + 10015009, + -30844224, + -8581293, + 5418197, + 9480663, + 2231568, + -10170080, + 33100372, + -1306171 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15121113, + -5201871, + -10389905, + 15427821, + -27509937, + -15992507, + 21670947, + 4486675, + -5931810, + -14466380 + ]), + FieldElement.fromList([ + 16166486, + -9483733, + -11104130, + 6023908, + -31926798, + -1364923, + 2340060, + -16254968, + -10735770, + -10039824 + ]), + FieldElement.fromList([ + 28042865, + -3557089, + -12126526, + 12259706, + -3717498, + -6945899, + 6766453, + -8689599, + 18036436, + 5803270 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -817581, + 6763912, + 11803561, + 1585585, + 10958447, + -2671165, + 23855391, + 4598332, + -6159431, + -14117438 + ]), + FieldElement.fromList([ + -31031306, + -14256194, + 17332029, + -2383520, + 31312682, + -5967183, + 696309, + 50292, + -20095739, + 11763584 + ]), + FieldElement.fromList([ + -594563, + -2514283, + -32234153, + 12643980, + 12650761, + 14811489, + 665117, + -12613632, + -19773211, + -10713562 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30464590, + -11262872, + -4127476, + -12734478, + 19835327, + -7105613, + -24396175, + 2075773, + -17020157, + 992471 + ]), + FieldElement.fromList([ + 18357185, + -6994433, + 7766382, + 16342475, + -29324918, + 411174, + 14578841, + 8080033, + -11574335, + -10601610 + ]), + FieldElement.fromList([ + 19598397, + 10334610, + 12555054, + 2555664, + 18821899, + -10339780, + 21873263, + 16014234, + 26224780, + 16452269 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -30223925, + 5145196, + 5944548, + 16385966, + 3976735, + 2009897, + -11377804, + -7618186, + -20533829, + 3698650 + ]), + FieldElement.fromList([ + 14187449, + 3448569, + -10636236, + -10810935, + -22663880, + -3433596, + 7268410, + -10890444, + 27394301, + 12015369 + ]), + FieldElement.fromList([ + 19695761, + 16087646, + 28032085, + 12999827, + 6817792, + 11427614, + 20244189, + -1312777, + -13259127, + -3402461 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30860103, + 12735208, + -1888245, + -4699734, + -16974906, + 2256940, + -8166013, + 12298312, + -8550524, + -10393462 + ]), + FieldElement.fromList([ + -5719826, + -11245325, + -1910649, + 15569035, + 26642876, + -7587760, + -5789354, + -15118654, + -4976164, + 12651793 + ]), + FieldElement.fromList([ + -2848395, + 9953421, + 11531313, + -5282879, + 26895123, + -12697089, + -13118820, + -16517902, + 9768698, + -2533218 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -24719459, + 1894651, + -287698, + -4704085, + 15348719, + -8156530, + 32767513, + 12765450, + 4940095, + 10678226 + ]), + FieldElement.fromList([ + 18860224, + 15980149, + -18987240, + -1562570, + -26233012, + -11071856, + -7843882, + 13944024, + -24372348, + 16582019 + ]), + FieldElement.fromList([ + -15504260, + 4970268, + -29893044, + 4175593, + -20993212, + -2199756, + -11704054, + 15444560, + -11003761, + 7989037 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 31490452, + 5568061, + -2412803, + 2182383, + -32336847, + 4531686, + -32078269, + 6200206, + -19686113, + -14800171 + ]), + FieldElement.fromList([ + -17308668, + -15879940, + -31522777, + -2831, + -32887382, + 16375549, + 8680158, + -16371713, + 28550068, + -6857132 + ]), + FieldElement.fromList([ + -28126887, + -5688091, + 16837845, + -1820458, + -6850681, + 12700016, + -30039981, + 4364038, + 1155602, + 5988841 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 21890435, + -13272907, + -12624011, + 12154349, + -7831873, + 15300496, + 23148983, + -4470481, + 24618407, + 8283181 + ]), + FieldElement.fromList([ + -33136107, + -10512751, + 9975416, + 6841041, + -31559793, + 16356536, + 3070187, + -7025928, + 1466169, + 10740210 + ]), + FieldElement.fromList([ + -1509399, + -15488185, + -13503385, + -10655916, + 32799044, + 909394, + -13938903, + -5779719, + -32164649, + -15327040 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 3960823, + -14267803, + -28026090, + -15918051, + -19404858, + 13146868, + 15567327, + 951507, + -3260321, + -573935 + ]), + FieldElement.fromList([ + 24740841, + 5052253, + -30094131, + 8961361, + 25877428, + 6165135, + -24368180, + 14397372, + -7380369, + -6144105 + ]), + FieldElement.fromList([ + -28888365, + 3510803, + -28103278, + -1158478, + -11238128, + -10631454, + -15441463, + -14453128, + -1625486, + -6494814 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 793299, + -9230478, + 8836302, + -6235707, + -27360908, + -2369593, + 33152843, + -4885251, + -9906200, + -621852 + ]), + FieldElement.fromList([ + 5666233, + 525582, + 20782575, + -8038419, + -24538499, + 14657740, + 16099374, + 1468826, + -6171428, + -15186581 + ]), + FieldElement.fromList([ + -4859255, + -3779343, + -2917758, + -6748019, + 7778750, + 11688288, + -30404353, + -9871238, + -1558923, + -9863646 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 10896332, + -7719704, + 824275, + 472601, + -19460308, + 3009587, + 25248958, + 14783338, + -30581476, + -15757844 + ]), + FieldElement.fromList([ + 10566929, + 12612572, + -31944212, + 11118703, + -12633376, + 12362879, + 21752402, + 8822496, + 24003793, + 14264025 + ]), + FieldElement.fromList([ + 27713862, + -7355973, + -11008240, + 9227530, + 27050101, + 2504721, + 23886875, + -13117525, + 13958495, + -5732453 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23481610, + 4867226, + -27247128, + 3900521, + 29838369, + -8212291, + -31889399, + -10041781, + 7340521, + -15410068 + ]), + FieldElement.fromList([ + 4646514, + -8011124, + -22766023, + -11532654, + 23184553, + 8566613, + 31366726, + -1381061, + -15066784, + -10375192 + ]), + FieldElement.fromList([ + -17270517, + 12723032, + -16993061, + 14878794, + 21619651, + -6197576, + 27584817, + 3093888, + -8843694, + 3849921 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -9064912, + 2103172, + 25561640, + -15125738, + -5239824, + 9582958, + 32477045, + -9017955, + 5002294, + -15550259 + ]), + FieldElement.fromList([ + -12057553, + -11177906, + 21115585, + -13365155, + 8808712, + -12030708, + 16489530, + 13378448, + -25845716, + 12741426 + ]), + FieldElement.fromList([ + -5946367, + 10645103, + -30911586, + 15390284, + -3286982, + -7118677, + 24306472, + 15852464, + 28834118, + -7646072 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -17335748, + -9107057, + -24531279, + 9434953, + -8472084, + -583362, + -13090771, + 455841, + 20461858, + 5491305 + ]), + FieldElement.fromList([ + 13669248, + -16095482, + -12481974, + -10203039, + -14569770, + -11893198, + -24995986, + 11293807, + -28588204, + -9421832 + ]), + FieldElement.fromList([ + 28497928, + 6272777, + -33022994, + 14470570, + 8906179, + -1225630, + 18504674, + -14165166, + 29867745, + -8795943 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -16207023, + 13517196, + -27799630, + -13697798, + 24009064, + -6373891, + -6367600, + -13175392, + 22853429, + -4012011 + ]), + FieldElement.fromList([ + 24191378, + 16712145, + -13931797, + 15217831, + 14542237, + 1646131, + 18603514, + -11037887, + 12876623, + -2112447 + ]), + FieldElement.fromList([ + 17902668, + 4518229, + -411702, + -2829247, + 26878217, + 5258055, + -12860753, + 608397, + 16031844, + 3723494 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -28632773, + 12763728, + -20446446, + 7577504, + 33001348, + -13017745, + 17558842, + -7872890, + 23896954, + -4314245 + ]), + FieldElement.fromList([ + -20005381, + -12011952, + 31520464, + 605201, + 2543521, + 5991821, + -2945064, + 7229064, + -9919646, + -8826859 + ]), + FieldElement.fromList([ + 28816045, + 298879, + -28165016, + -15920938, + 19000928, + -1665890, + -12680833, + -2949325, + -18051778, + -2082915 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 16000882, + -344896, + 3493092, + -11447198, + -29504595, + -13159789, + 12577740, + 16041268, + -19715240, + 7847707 + ]), + FieldElement.fromList([ + 10151868, + 10572098, + 27312476, + 7922682, + 14825339, + 4723128, + -32855931, + -6519018, + -10020567, + 3852848 + ]), + FieldElement.fromList([ + -11430470, + 15697596, + -21121557, + -4420647, + 5386314, + 15063598, + 16514493, + -15932110, + 29330899, + -15076224 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25499735, + -4378794, + -15222908, + -6901211, + 16615731, + 2051784, + 3303702, + 15490, + -27548796, + 12314391 + ]), + FieldElement.fromList([ + 15683520, + -6003043, + 18109120, + -9980648, + 15337968, + -5997823, + -16717435, + 15921866, + 16103996, + -3731215 + ]), + FieldElement.fromList([ + -23169824, + -10781249, + 13588192, + -1628807, + -3798557, + -1074929, + -19273607, + 5402699, + -29815713, + -9841101 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 23190676, + 2384583, + -32714340, + 3462154, + -29903655, + -1529132, + -11266856, + 8911517, + -25205859, + 2739713 + ]), + FieldElement.fromList([ + 21374101, + -3554250, + -33524649, + 9874411, + 15377179, + 11831242, + -33529904, + 6134907, + 4931255, + 11987849 + ]), + FieldElement.fromList([ + -7732, + -2978858, + -16223486, + 7277597, + 105524, + -322051, + -31480539, + 13861388, + -30076310, + 10117930 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -29501170, + -10744872, + -26163768, + 13051539, + -25625564, + 5089643, + -6325503, + 6704079, + 12890019, + 15728940 + ]), + FieldElement.fromList([ + -21972360, + -11771379, + -951059, + -4418840, + 14704840, + 2695116, + 903376, + -10428139, + 12885167, + 8311031 + ]), + FieldElement.fromList([ + -17516482, + 5352194, + 10384213, + -13811658, + 7506451, + 13453191, + 26423267, + 4384730, + 1888765, + -5435404 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25817338, + -3107312, + -13494599, + -3182506, + 30896459, + -13921729, + -32251644, + -12707869, + -19464434, + -3340243 + ]), + FieldElement.fromList([ + -23607977, + -2665774, + -526091, + 4651136, + 5765089, + 4618330, + 6092245, + 14845197, + 17151279, + -9854116 + ]), + FieldElement.fromList([ + -24830458, + -12733720, + -15165978, + 10367250, + -29530908, + -265356, + 22825805, + -7087279, + -16866484, + 16176525 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23583256, + 6564961, + 20063689, + 3798228, + -4740178, + 7359225, + 2006182, + -10363426, + -28746253, + -10197509 + ]), + FieldElement.fromList([ + -10626600, + -4486402, + -13320562, + -5125317, + 3432136, + -6393229, + 23632037, + -1940610, + 32808310, + 1099883 + ]), + FieldElement.fromList([ + 15030977, + 5768825, + -27451236, + -2887299, + -6427378, + -15361371, + -15277896, + -6809350, + 2051441, + -15225865 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -3362323, + -7239372, + 7517890, + 9824992, + 23555850, + 295369, + 5148398, + -14154188, + -22686354, + 16633660 + ]), + FieldElement.fromList([ + 4577086, + -16752288, + 13249841, + -15304328, + 19958763, + -14537274, + 18559670, + -10759549, + 8402478, + -9864273 + ]), + FieldElement.fromList([ + -28406330, + -1051581, + -26790155, + -907698, + -17212414, + -11030789, + 9453451, + -14980072, + 17983010, + 9967138 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25762494, + 6524722, + 26585488, + 9969270, + 24709298, + 1220360, + -1677990, + 7806337, + 17507396, + 3651560 + ]), + FieldElement.fromList([ + -10420457, + -4118111, + 14584639, + 15971087, + -15768321, + 8861010, + 26556809, + -5574557, + -18553322, + -11357135 + ]), + FieldElement.fromList([ + 2839101, + 14284142, + 4029895, + 3472686, + 14402957, + 12689363, + -26642121, + 8459447, + -5605463, + -7621941 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -4839289, + -3535444, + 9744961, + 2871048, + 25113978, + 3187018, + -25110813, + -849066, + 17258084, + -7977739 + ]), + FieldElement.fromList([ + 18164541, + -10595176, + -17154882, + -1542417, + 19237078, + -9745295, + 23357533, + -15217008, + 26908270, + 12150756 + ]), + FieldElement.fromList([ + -30264870, + -7647865, + 5112249, + -7036672, + -1499807, + -6974257, + 43168, + -5537701, + -32302074, + 16215819 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -6898905, + 9824394, + -12304779, + -4401089, + -31397141, + -6276835, + 32574489, + 12532905, + -7503072, + -8675347 + ]), + FieldElement.fromList([ + -27343522, + -16515468, + -27151524, + -10722951, + 946346, + 16291093, + 254968, + 7168080, + 21676107, + -1943028 + ]), + FieldElement.fromList([ + 21260961, + -8424752, + -16831886, + -11920822, + -23677961, + 3968121, + -3651949, + -6215466, + -3556191, + -7913075 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 16544754, + 13250366, + -16804428, + 15546242, + -4583003, + 12757258, + -2462308, + -8680336, + -18907032, + -9662799 + ]), + FieldElement.fromList([ + -2415239, + -15577728, + 18312303, + 4964443, + -15272530, + -12653564, + 26820651, + 16690659, + 25459437, + -4564609 + ]), + FieldElement.fromList([ + -25144690, + 11425020, + 28423002, + -11020557, + -6144921, + -15826224, + 9142795, + -2391602, + -6432418, + -1644817 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23104652, + 6253476, + 16964147, + -3768872, + -25113972, + -12296437, + -27457225, + -16344658, + 6335692, + 7249989 + ]), + FieldElement.fromList([ + -30333227, + 13979675, + 7503222, + -12368314, + -11956721, + -4621693, + -30272269, + 2682242, + 25993170, + -12478523 + ]), + FieldElement.fromList([ + 4364628, + 5930691, + 32304656, + -10044554, + -8054781, + 15091131, + 22857016, + -10598955, + 31820368, + 15075278 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 31879134, + -8918693, + 17258761, + 90626, + -8041836, + -4917709, + 24162788, + -9650886, + -17970238, + 12833045 + ]), + FieldElement.fromList([ + 19073683, + 14851414, + -24403169, + -11860168, + 7625278, + 11091125, + -19619190, + 2074449, + -9413939, + 14905377 + ]), + FieldElement.fromList([ + 24483667, + -11935567, + -2518866, + -11547418, + -1553130, + 15355506, + -25282080, + 9253129, + 27628530, + -7555480 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 17597607, + 8340603, + 19355617, + 552187, + 26198470, + -3176583, + 4593324, + -9157582, + -14110875, + 15297016 + ]), + FieldElement.fromList([ + 510886, + 14337390, + -31785257, + 16638632, + 6328095, + 2713355, + -20217417, + -11864220, + 8683221, + 2921426 + ]), + FieldElement.fromList([ + 18606791, + 11874196, + 27155355, + -5281482, + -24031742, + 6265446, + -25178240, + -1278924, + 4674690, + 13890525 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 13609624, + 13069022, + -27372361, + -13055908, + 24360586, + 9592974, + 14977157, + 9835105, + 4389687, + 288396 + ]), + FieldElement.fromList([ + 9922506, + -519394, + 13613107, + 5883594, + -18758345, + -434263, + -12304062, + 8317628, + 23388070, + 16052080 + ]), + FieldElement.fromList([ + 12720016, + 11937594, + -31970060, + -5028689, + 26900120, + 8561328, + -20155687, + -11632979, + -14754271, + -10812892 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 15961858, + 14150409, + 26716931, + -665832, + -22794328, + 13603569, + 11829573, + 7467844, + -28822128, + 929275 + ]), + FieldElement.fromList([ + 11038231, + -11582396, + -27310482, + -7316562, + -10498527, + -16307831, + -23479533, + -9371869, + -21393143, + 2465074 + ]), + FieldElement.fromList([ + 20017163, + -4323226, + 27915242, + 1529148, + 12396362, + 15675764, + 13817261, + -9658066, + 2463391, + -4622140 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -16358878, + -12663911, + -12065183, + 4996454, + -1256422, + 1073572, + 9583558, + 12851107, + 4003896, + 12673717 + ]), + FieldElement.fromList([ + -1731589, + -15155870, + -3262930, + 16143082, + 19294135, + 13385325, + 14741514, + -9103726, + 7903886, + 2348101 + ]), + FieldElement.fromList([ + 24536016, + -16515207, + 12715592, + -3862155, + 1511293, + 10047386, + -3842346, + -7129159, + -28377538, + 10048127 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -12622226, + -6204820, + 30718825, + 2591312, + -10617028, + 12192840, + 18873298, + -7297090, + -32297756, + 15221632 + ]), + FieldElement.fromList([ + -26478122, + -11103864, + 11546244, + -1852483, + 9180880, + 7656409, + -21343950, + 2095755, + 29769758, + 6593415 + ]), + FieldElement.fromList([ + -31994208, + -2907461, + 4176912, + 3264766, + 12538965, + -868111, + 26312345, + -6118678, + 30958054, + 8292160 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 31429822, + -13959116, + 29173532, + 15632448, + 12174511, + -2760094, + 32808831, + 3977186, + 26143136, + -3148876 + ]), + FieldElement.fromList([ + 22648901, + 1402143, + -22799984, + 13746059, + 7936347, + 365344, + -8668633, + -1674433, + -3758243, + -2304625 + ]), + FieldElement.fromList([ + -15491917, + 8012313, + -2514730, + -12702462, + -23965846, + -10254029, + -1612713, + -1535569, + -16664475, + 8194478 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 27338066, + -7507420, + -7414224, + 10140405, + -19026427, + -6589889, + 27277191, + 8855376, + 28572286, + 3005164 + ]), + FieldElement.fromList([ + 26287124, + 4821776, + 25476601, + -4145903, + -3764513, + -15788984, + -18008582, + 1182479, + -26094821, + -13079595 + ]), + FieldElement.fromList([ + -7171154, + 3178080, + 23970071, + 6201893, + -17195577, + -4489192, + -21876275, + -13982627, + 32208683, + -1198248 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -16657702, + 2817643, + -10286362, + 14811298, + 6024667, + 13349505, + -27315504, + -10497842, + -27672585, + -11539858 + ]), + FieldElement.fromList([ + 15941029, + -9405932, + -21367050, + 8062055, + 31876073, + -238629, + -15278393, + -1444429, + 15397331, + -4130193 + ]), + FieldElement.fromList([ + 8934485, + -13485467, + -23286397, + -13423241, + -32446090, + 14047986, + 31170398, + -1441021, + -27505566, + 15087184 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -18357243, + -2156491, + 24524913, + -16677868, + 15520427, + -6360776, + -15502406, + 11461896, + 16788528, + -5868942 + ]), + FieldElement.fromList([ + -1947386, + 16013773, + 21750665, + 3714552, + -17401782, + -16055433, + -3770287, + -10323320, + 31322514, + -11615635 + ]), + FieldElement.fromList([ + 21426655, + -5650218, + -13648287, + -5347537, + -28812189, + -4920970, + -18275391, + -14621414, + 13040862, + -12112948 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 11293895, + 12478086, + -27136401, + 15083750, + -29307421, + 14748872, + 14555558, + -13417103, + 1613711, + 4896935 + ]), + FieldElement.fromList([ + -25894883, + 15323294, + -8489791, + -8057900, + 25967126, + -13425460, + 2825960, + -4897045, + -23971776, + -11267415 + ]), + FieldElement.fromList([ + -15924766, + -5229880, + -17443532, + 6410664, + 3622847, + 10243618, + 20615400, + 12405433, + -23753030, + -8436416 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -7091295, + 12556208, + -20191352, + 9025187, + -17072479, + 4333801, + 4378436, + 2432030, + 23097949, + -566018 + ]), + FieldElement.fromList([ + 4565804, + -16025654, + 20084412, + -7842817, + 1724999, + 189254, + 24767264, + 10103221, + -18512313, + 2424778 + ]), + FieldElement.fromList([ + 366633, + -11976806, + 8173090, + -6890119, + 30788634, + 5745705, + -7168678, + 1344109, + -3642553, + 12412659 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -24001791, + 7690286, + 14929416, + -168257, + -32210835, + -13412986, + 24162697, + -15326504, + -3141501, + 11179385 + ]), + FieldElement.fromList([ + 18289522, + -14724954, + 8056945, + 16430056, + -21729724, + 7842514, + -6001441, + -1486897, + -18684645, + -11443503 + ]), + FieldElement.fromList([ + 476239, + 6601091, + -6152790, + -9723375, + 17503545, + -4863900, + 27672959, + 13403813, + 11052904, + 5219329 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 20678546, + -8375738, + -32671898, + 8849123, + -5009758, + 14574752, + 31186971, + -3973730, + 9014762, + -8579056 + ]), + FieldElement.fromList([ + -13644050, + -10350239, + -15962508, + 5075808, + -1514661, + -11534600, + -33102500, + 9160280, + 8473550, + -3256838 + ]), + FieldElement.fromList([ + 24900749, + 14435722, + 17209120, + -15292541, + -22592275, + 9878983, + -7689309, + -16335821, + -24568481, + 11788948 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -3118155, + -11395194, + -13802089, + 14797441, + 9652448, + -6845904, + -20037437, + 10410733, + -24568470, + -1458691 + ]), + FieldElement.fromList([ + -15659161, + 16736706, + -22467150, + 10215878, + -9097177, + 7563911, + 11871841, + -12505194, + -18513325, + 8464118 + ]), + FieldElement.fromList([ + -23400612, + 8348507, + -14585951, + -861714, + -3950205, + -6373419, + 14325289, + 8628612, + 33313881, + -8370517 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -20186973, + -4967935, + 22367356, + 5271547, + -1097117, + -4788838, + -24805667, + -10236854, + -8940735, + -5818269 + ]), + FieldElement.fromList([ + -6948785, + -1795212, + -32625683, + -16021179, + 32635414, + -7374245, + 15989197, + -12838188, + 28358192, + -4253904 + ]), + FieldElement.fromList([ + -23561781, + -2799059, + -32351682, + -1661963, + -9147719, + 10429267, + -16637684, + 4072016, + -5351664, + 5596589 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -28236598, + -3390048, + 12312896, + 6213178, + 3117142, + 16078565, + 29266239, + 2557221, + 1768301, + 15373193 + ]), + FieldElement.fromList([ + -7243358, + -3246960, + -4593467, + -7553353, + -127927, + -912245, + -1090902, + -4504991, + -24660491, + 3442910 + ]), + FieldElement.fromList([ + -30210571, + 5124043, + 14181784, + 8197961, + 18964734, + -11939093, + 22597931, + 7176455, + -18585478, + 13365930 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -7877390, + -1499958, + 8324673, + 4690079, + 6261860, + 890446, + 24538107, + -8570186, + -9689599, + -3031667 + ]), + FieldElement.fromList([ + 25008904, + -10771599, + -4305031, + -9638010, + 16265036, + 15721635, + 683793, + -11823784, + 15723479, + -15163481 + ]), + FieldElement.fromList([ + -9660625, + 12374379, + -27006999, + -7026148, + -7724114, + -12314514, + 11879682, + 5400171, + 519526, + -1235876 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 22258397, + -16332233, + -7869817, + 14613016, + -22520255, + -2950923, + -20353881, + 7315967, + 16648397, + 7605640 + ]), + FieldElement.fromList([ + -8081308, + -8464597, + -8223311, + 9719710, + 19259459, + -15348212, + 23994942, + -5281555, + -9468848, + 4763278 + ]), + FieldElement.fromList([ + -21699244, + 9220969, + -15730624, + 1084137, + -25476107, + -2852390, + 31088447, + -7764523, + -11356529, + 728112 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 26047220, + -11751471, + -6900323, + -16521798, + 24092068, + 9158119, + -4273545, + -12555558, + -29365436, + -5498272 + ]), + FieldElement.fromList([ + 17510331, + -322857, + 5854289, + 8403524, + 17133918, + -3112612, + -28111007, + 12327945, + 10750447, + 10014012 + ]), + FieldElement.fromList([ + -10312768, + 3936952, + 9156313, + -8897683, + 16498692, + -994647, + -27481051, + -666732, + 3424691, + 7540221 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30322361, + -6964110, + 11361005, + -4143317, + 7433304, + 4989748, + -7071422, + -16317219, + -9244265, + 15258046 + ]), + FieldElement.fromList([ + 13054562, + -2779497, + 19155474, + 469045, + -12482797, + 4566042, + 5631406, + 2711395, + 1062915, + -5136345 + ]), + FieldElement.fromList([ + -19240248, + -11254599, + -29509029, + -7499965, + -5835763, + 13005411, + -6066489, + 12194497, + 32960380, + 1459310 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 19852034, + 7027924, + 23669353, + 10020366, + 8586503, + -6657907, + 394197, + -6101885, + 18638003, + -11174937 + ]), + FieldElement.fromList([ + 31395534, + 15098109, + 26581030, + 8030562, + -16527914, + -5007134, + 9012486, + -7584354, + -6643087, + -5442636 + ]), + FieldElement.fromList([ + -9192165, + -2347377, + -1997099, + 4529534, + 25766844, + 607986, + -13222, + 9677543, + -32294889, + -6456008 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -2444496, + -149937, + 29348902, + 8186665, + 1873760, + 12489863, + -30934579, + -7839692, + -7852844, + -8138429 + ]), + FieldElement.fromList([ + -15236356, + -15433509, + 7766470, + 746860, + 26346930, + -10221762, + -27333451, + 10754588, + -9431476, + 5203576 + ]), + FieldElement.fromList([ + 31834314, + 14135496, + -770007, + 5159118, + 20917671, + -16768096, + -7467973, + -7337524, + 31809243, + 7347066 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -9606723, + -11874240, + 20414459, + 13033986, + 13716524, + -11691881, + 19797970, + -12211255, + 15192876, + -2087490 + ]), + FieldElement.fromList([ + -12663563, + -2181719, + 1168162, + -3804809, + 26747877, + -14138091, + 10609330, + 12694420, + 33473243, + -13382104 + ]), + FieldElement.fromList([ + 33184999, + 11180355, + 15832085, + -11385430, + -1633671, + 225884, + 15089336, + -11023903, + -6135662, + 14480053 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 31308717, + -5619998, + 31030840, + -1897099, + 15674547, + -6582883, + 5496208, + 13685227, + 27595050, + 8737275 + ]), + FieldElement.fromList([ + -20318852, + -15150239, + 10933843, + -16178022, + 8335352, + -7546022, + -31008351, + -12610604, + 26498114, + 66511 + ]), + FieldElement.fromList([ + 22644454, + -8761729, + -16671776, + 4884562, + -3105614, + -13559366, + 30540766, + -4286747, + -13327787, + -7515095 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -28017847, + 9834845, + 18617207, + -2681312, + -3401956, + -13307506, + 8205540, + 13585437, + -17127465, + 15115439 + ]), + FieldElement.fromList([ + 23711543, + -672915, + 31206561, + -8362711, + 6164647, + -9709987, + -33535882, + -1426096, + 8236921, + 16492939 + ]), + FieldElement.fromList([ + -23910559, + -13515526, + -26299483, + -4503841, + 25005590, + -7687270, + 19574902, + 10071562, + 6708380, + -6222424 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 2101391, + -4930054, + 19702731, + 2367575, + -15427167, + 1047675, + 5301017, + 9328700, + 29955601, + -11678310 + ]), + FieldElement.fromList([ + 3096359, + 9271816, + -21620864, + -15521844, + -14847996, + -7592937, + -25892142, + -12635595, + -9917575, + 6216608 + ]), + FieldElement.fromList([ + -32615849, + 338663, + -25195611, + 2510422, + -29213566, + -13820213, + 24822830, + -6146567, + -26767480, + 7525079 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23066649, + -13985623, + 16133487, + -7896178, + -3389565, + 778788, + -910336, + -2782495, + -19386633, + 11994101 + ]), + FieldElement.fromList([ + 21691500, + -13624626, + -641331, + -14367021, + 3285881, + -3483596, + -25064666, + 9718258, + -7477437, + 13381418 + ]), + FieldElement.fromList([ + 18445390, + -4202236, + 14979846, + 11622458, + -1727110, + -3582980, + 23111648, + -6375247, + 28535282, + 15779576 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30098053, + 3089662, + -9234387, + 16662135, + -21306940, + 11308411, + -14068454, + 12021730, + 9955285, + -16303356 + ]), + FieldElement.fromList([ + 9734894, + -14576830, + -7473633, + -9138735, + 2060392, + 11313496, + -18426029, + 9924399, + 20194861, + 13380996 + ]), + FieldElement.fromList([ + -26378102, + -7965207, + -22167821, + 15789297, + -18055342, + -6168792, + -1984914, + 15707771, + 26342023, + 10146099 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -26016874, + -219943, + 21339191, + -41388, + 19745256, + -2878700, + -29637280, + 2227040, + 21612326, + -545728 + ]), + FieldElement.fromList([ + -13077387, + 1184228, + 23562814, + -5970442, + -20351244, + -6348714, + 25764461, + 12243797, + -20856566, + 11649658 + ]), + FieldElement.fromList([ + -10031494, + 11262626, + 27384172, + 2271902, + 26947504, + -15997771, + 39944, + 6114064, + 33514190, + 2333242 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -21433588, + -12421821, + 8119782, + 7219913, + -21830522, + -9016134, + -6679750, + -12670638, + 24350578, + -13450001 + ]), + FieldElement.fromList([ + -4116307, + -11271533, + -23886186, + 4843615, + -30088339, + 690623, + -31536088, + -10406836, + 8317860, + 12352766 + ]), + FieldElement.fromList([ + 18200138, + -14475911, + -33087759, + -2696619, + -23702521, + -9102511, + -23552096, + -2287550, + 20712163, + 6719373 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 26656208, + 6075253, + -7858556, + 1886072, + -28344043, + 4262326, + 11117530, + -3763210, + 26224235, + -3297458 + ]), + FieldElement.fromList([ + -17168938, + -14854097, + -3395676, + -16369877, + -19954045, + 14050420, + 21728352, + 9493610, + 18620611, + -16428628 + ]), + FieldElement.fromList([ + -13323321, + 13325349, + 11432106, + 5964811, + 18609221, + 6062965, + -5269471, + -9725556, + -30701573, + -16479657 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -23860538, + -11233159, + 26961357, + 1640861, + -32413112, + -16737940, + 12248509, + -5240639, + 13735342, + 1934062 + ]), + FieldElement.fromList([ + 25089769, + 6742589, + 17081145, + -13406266, + 21909293, + -16067981, + -15136294, + -3765346, + -21277997, + 5473616 + ]), + FieldElement.fromList([ + 31883677, + -7961101, + 1083432, + -11572403, + 22828471, + 13290673, + -7125085, + 12469656, + 29111212, + -5451014 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 24244947, + -15050407, + -26262976, + 2791540, + -14997599, + 16666678, + 24367466, + 6388839, + -10295587, + 452383 + ]), + FieldElement.fromList([ + -25640782, + -3417841, + 5217916, + 16224624, + 19987036, + -4082269, + -24236251, + -5915248, + 15766062, + 8407814 + ]), + FieldElement.fromList([ + -20406999, + 13990231, + 15495425, + 16395525, + 5377168, + 15166495, + -8917023, + -4388953, + -8067909, + 2276718 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 30157918, + 12924066, + -17712050, + 9245753, + 19895028, + 3368142, + -23827587, + 5096219, + 22740376, + -7303417 + ]), + FieldElement.fromList([ + 2041139, + -14256350, + 7783687, + 13876377, + -25946985, + -13352459, + 24051124, + 13742383, + -15637599, + 13295222 + ]), + FieldElement.fromList([ + 33338237, + -8505733, + 12532113, + 7977527, + 9106186, + -1715251, + -17720195, + -4612972, + -4451357, + -14669444 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -20045281, + 5454097, + -14346548, + 6447146, + 28862071, + 1883651, + -2469266, + -4141880, + 7770569, + 9620597 + ]), + FieldElement.fromList([ + 23208068, + 7979712, + 33071466, + 8149229, + 1758231, + -10834995, + 30945528, + -1694323, + -33502340, + -14767970 + ]), + FieldElement.fromList([ + 1439958, + -16270480, + -1079989, + -793782, + 4625402, + 10647766, + -5043801, + 1220118, + 30494170, + -11440799 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -5037580, + -13028295, + -2970559, + -3061767, + 15640974, + -6701666, + -26739026, + 926050, + -1684339, + -13333647 + ]), + FieldElement.fromList([ + 13908495, + -3549272, + 30919928, + -6273825, + -21521863, + 7989039, + 9021034, + 9078865, + 3353509, + 4033511 + ]), + FieldElement.fromList([ + -29663431, + -15113610, + 32259991, + -344482, + 24295849, + -12912123, + 23161163, + 8839127, + 27485041, + 7356032 + ]), + ), + ]), + List.from([ + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 9661027, + 705443, + 11980065, + -5370154, + -1628543, + 14661173, + -6346142, + 2625015, + 28431036, + -16771834 + ]), + FieldElement.fromList([ + -23839233, + -8311415, + -25945511, + 7480958, + -17681669, + -8354183, + -22545972, + 14150565, + 15970762, + 4099461 + ]), + FieldElement.fromList([ + 29262576, + 16756590, + 26350592, + -8793563, + 8529671, + -11208050, + 13617293, + -9937143, + 11465739, + 8317062 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -25493081, + -6962928, + 32500200, + -9419051, + -23038724, + -2302222, + 14898637, + 3848455, + 20969334, + -5157516 + ]), + FieldElement.fromList([ + -20384450, + -14347713, + -18336405, + 13884722, + -33039454, + 2842114, + -21610826, + -3649888, + 11177095, + 14989547 + ]), + FieldElement.fromList([ + -24496721, + -11716016, + 16959896, + 2278463, + 12066309, + 10137771, + 13515641, + 2581286, + -28487508, + 9930240 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -17751622, + -2097826, + 16544300, + -13009300, + -15914807, + -14949081, + 18345767, + -13403753, + 16291481, + -5314038 + ]), + FieldElement.fromList([ + -33229194, + 2553288, + 32678213, + 9875984, + 8534129, + 6889387, + -9676774, + 6957617, + 4368891, + 9788741 + ]), + FieldElement.fromList([ + 16660756, + 7281060, + -10830758, + 12911820, + 20108584, + -8101676, + -21722536, + -8613148, + 16250552, + -11111103 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -19765507, + 2390526, + -16551031, + 14161980, + 1905286, + 6414907, + 4689584, + 10604807, + -30190403, + 4782747 + ]), + FieldElement.fromList([ + -1354539, + 14736941, + -7367442, + -13292886, + 7710542, + -14155590, + -9981571, + 4383045, + 22546403, + 437323 + ]), + FieldElement.fromList([ + 31665577, + -12180464, + -16186830, + 1491339, + -18368625, + 3294682, + 27343084, + 2786261, + -30633590, + -14097016 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -14467279, + -683715, + -33374107, + 7448552, + 19294360, + 14334329, + -19690631, + 2355319, + -19284671, + -6114373 + ]), + FieldElement.fromList([ + 15121312, + -15796162, + 6377020, + -6031361, + -10798111, + -12957845, + 18952177, + 15496498, + -29380133, + 11754228 + ]), + FieldElement.fromList([ + -2637277, + -13483075, + 8488727, + -14303896, + 12728761, + -1622493, + 7141596, + 11724556, + 22761615, + -10134141 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + 16918416, + 11729663, + -18083579, + 3022987, + -31015732, + -13339659, + -28741185, + -12227393, + 32851222, + 11717399 + ]), + FieldElement.fromList([ + 11166634, + 7338049, + -6722523, + 4531520, + -29468672, + -7302055, + 31474879, + 3483633, + -1193175, + -4030831 + ]), + FieldElement.fromList([ + -185635, + 9921305, + 31456609, + -13536438, + -12013818, + 13348923, + 33142652, + 6546660, + -19985279, + -3948376 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -32460596, + 11266712, + -11197107, + -7899103, + 31703694, + 3855903, + -8537131, + -12833048, + -30772034, + -15486313 + ]), + FieldElement.fromList([ + -18006477, + 12709068, + 3991746, + -6479188, + -21491523, + -10550425, + -31135347, + -16049879, + 10928917, + 3011958 + ]), + FieldElement.fromList([ + -6957757, + -15594337, + 31696059, + 334240, + 29576716, + 14796075, + -30831056, + -12805180, + 18008031, + 10258577 + ]), + ), + PreComputedGroupElement.fromList( + FieldElement.fromList([ + -22448644, + 15655569, + 7018479, + -4410003, + -30314266, + -1201591, + -1853465, + 1367120, + 25127874, + 6671743 + ]), + FieldElement.fromList([ + 29701166, + -14373934, + -10878120, + 9279288, + -17568, + 13127210, + 21382910, + 11042292, + 25838796, + 4642684 + ]), + FieldElement.fromList([ + -20430234, + 14955537, + -24126347, + 8124619, + -5369288, + -5990470, + 30468147, + -13900640, + 18423289, + 4177476 + ]), + ), + ]), +]); diff --git a/ed25519_edwards/lib/src/edwards25519.dart b/ed25519_edwards/lib/src/edwards25519.dart new file mode 100644 index 0000000..c9f1b5b --- /dev/null +++ b/ed25519_edwards/lib/src/edwards25519.dart @@ -0,0 +1,2127 @@ +import 'dart:typed_data'; + +import 'package:adaptive_number/adaptive_number.dart'; +import 'package:ed25519_edwards/src/numbers.dart'; + +import 'const.dart'; + +class FieldElement { + late List innerList; + + FieldElement() { + innerList = List.generate(10, (index) => Number.zero); + } + + FieldElement.fromList(List list) { + innerList = list.map((e) => Number(e)).toList(); + } + + Number operator [](int index) { + return innerList[index]; + } + + void operator []=(int index, Number value) { + innerList[index] = value; + } + + int get length => innerList.length; +} + +void fieldElementCopy( + FieldElement src, int srcPos, FieldElement dest, int destPos, int length) { + dest.innerList.setRange(destPos, length + destPos, src.innerList, srcPos); +} + +void fieldElementFullCopy(FieldElement src, FieldElement dest) { + fieldElementCopy(src, 0, dest, 0, dest.length); +} + +var zero = FieldElement(); + +void FeZero(FieldElement fe) { + fieldElementFullCopy(zero, fe); +} + +void FeOne(FieldElement fe) { + FeZero(fe); + fe[0] = Number.one; +} + +void FeAdd(FieldElement dst, FieldElement a, FieldElement b) { + dst[0] = a[0] + b[0]; + dst[1] = a[1] + b[1]; + dst[2] = a[2] + b[2]; + dst[3] = a[3] + b[3]; + dst[4] = a[4] + b[4]; + dst[5] = a[5] + b[5]; + dst[6] = a[6] + b[6]; + dst[7] = a[7] + b[7]; + dst[8] = a[8] + b[8]; + dst[9] = a[9] + b[9]; +} + +void FeSub(FieldElement dst, FieldElement a, FieldElement b) { + dst[0] = a[0] - b[0]; + dst[1] = a[1] - b[1]; + dst[2] = a[2] - b[2]; + dst[3] = a[3] - b[3]; + dst[4] = a[4] - b[4]; + dst[5] = a[5] - b[5]; + dst[6] = a[6] - b[6]; + dst[7] = a[7] - b[7]; + dst[8] = a[8] - b[8]; + dst[9] = a[9] - b[9]; +} + +void FeCopy(FieldElement dst, FieldElement src) { + fieldElementFullCopy(src, dst); +} + +/// Replace (f,g) with (g,g) if b == 1; +/// replace (f,g) with (f,g) if b == 0. +/// +/// Preconditions: b in {0,1}. +void FeCMove(FieldElement f, FieldElement g, Number b) { + b = -b; + f[0] ^= b & (f[0] ^ g[0]); + f[1] ^= b & (f[1] ^ g[1]); + f[2] ^= b & (f[2] ^ g[2]); + f[3] ^= b & (f[3] ^ g[3]); + f[4] ^= b & (f[4] ^ g[4]); + f[5] ^= b & (f[5] ^ g[5]); + f[6] ^= b & (f[6] ^ g[6]); + f[7] ^= b & (f[7] ^ g[7]); + f[8] ^= b & (f[8] ^ g[8]); + f[9] ^= b & (f[9] ^ g[9]); +} + +Number load3(Uint8List input) { + int r; + r = input[0]; + r |= input[1] << 8; + r |= input[2] << 16; + return Number(r); +} + +Number load4(Uint8List input) { + int r; + r = input[0]; + r |= input[1] << 8; + r |= input[2] << 16; + r |= input[3] << 24; + return Number(r); +} + +void FeFromBytes(FieldElement dst, Uint8List src) { + var h0 = load4(src.sublist(0, src.length)); + var h1 = load3(src.sublist(4, src.length)) << 6; + var h2 = load3(src.sublist(7, src.length)) << 5; + var h3 = load3(src.sublist(10, src.length)) << 3; + var h4 = load3(src.sublist(13, src.length)) << 2; + var h5 = load4(src.sublist(16, src.length)); + var h6 = load3(src.sublist(20, src.length)) << 7; + var h7 = load3(src.sublist(23, src.length)) << 5; + var h8 = load3(src.sublist(26, src.length)) << 4; + var h9 = (load3(src.sublist(29, src.length)) & Number(8388607)) << 2; + + FeCombine(dst, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9); +} + +/// FeToBytes marshals h to s. +/// Preconditions: +/// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +/// +/// Write p=2^255-19; q=floor(h/p). +/// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). +/// +/// Proof: +/// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. +/// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. +/// +/// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). +/// Then 0.filled(10, Number.zero); + + var q = (Numbers.v19 * h[9] + (Number.one << 24)) >> 25; + q = (h[0] + q) >> 26; + q = (h[1] + q) >> 25; + q = (h[2] + q) >> 26; + q = (h[3] + q) >> 25; + q = (h[4] + q) >> 26; + q = (h[5] + q) >> 25; + q = (h[6] + q) >> 26; + q = (h[7] + q) >> 25; + q = (h[8] + q) >> 26; + q = (h[9] + q) >> 25; + + // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. + h[0] += Numbers.v19 * q; + // Goal: Output h-2^255 q, which is between 0 and 2^255-20. + + carry[0] = h[0] >> 26; + h[1] += carry[0]; + h[0] -= carry[0] << 26; + carry[1] = h[1] >> 25; + h[2] += carry[1]; + h[1] -= carry[1] << 25; + carry[2] = h[2] >> 26; + h[3] += carry[2]; + h[2] -= carry[2] << 26; + carry[3] = h[3] >> 25; + h[4] += carry[3]; + h[3] -= carry[3] << 25; + carry[4] = h[4] >> 26; + h[5] += carry[4]; + h[4] -= carry[4] << 26; + carry[5] = h[5] >> 25; + h[6] += carry[5]; + h[5] -= carry[5] << 25; + carry[6] = h[6] >> 26; + h[7] += carry[6]; + h[6] -= carry[6] << 26; + carry[7] = h[7] >> 25; + h[8] += carry[7]; + h[7] -= carry[7] << 25; + carry[8] = h[8] >> 26; + h[9] += carry[8]; + h[8] -= carry[8] << 26; + carry[9] = h[9] >> 25; + h[9] -= carry[9] << 25; + // h10 = carry9 + + // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; + // evidently 2^255 h10-2^255 q = 0. + // Goal: Output h[0]+...+2^230 h[9]. + + s[0] = (h[0] >> 0).intValue; + s[1] = (h[0] >> 8).intValue; + s[2] = (h[0] >> 16).intValue; + s[3] = ((h[0] >> 24) | (h[1] << 2)).intValue; + s[4] = (h[1] >> 6).intValue; + s[5] = (h[1] >> 14).intValue; + s[6] = ((h[1] >> 22) | (h[2] << 3)).intValue; + s[7] = (h[2] >> 5).intValue; + s[8] = (h[2] >> 13).intValue; + s[9] = ((h[2] >> 21) | (h[3] << 5)).intValue; + s[10] = (h[3] >> 3).intValue; + s[11] = (h[3] >> 11).intValue; + s[12] = ((h[3] >> 19) | (h[4] << 6)).intValue; + s[13] = (h[4] >> 2).intValue; + s[14] = (h[4] >> 10).intValue; + s[15] = (h[4] >> 18).intValue; + s[16] = (h[5] >> 0).intValue; + s[17] = (h[5] >> 8).intValue; + s[18] = (h[5] >> 16).intValue; + s[19] = ((h[5] >> 24) | (h[6] << 1)).intValue; + s[20] = (h[6] >> 7).intValue; + s[21] = (h[6] >> 15).intValue; + s[22] = ((h[6] >> 23) | (h[7] << 3)).intValue; + s[23] = (h[7] >> 5).intValue; + s[24] = (h[7] >> 13).intValue; + s[25] = ((h[7] >> 21) | (h[8] << 4)).intValue; + s[26] = (h[8] >> 4).intValue; + s[27] = (h[8] >> 12).intValue; + s[28] = ((h[8] >> 20) | (h[9] << 6)).intValue; + s[29] = (h[9] >> 2).intValue; + s[30] = (h[9] >> 10).intValue; + s[31] = (h[9] >> 18).intValue; +} + +int FeIsNegative(FieldElement f) { + var s = Uint8List(32); + FeToBytes(s, f); + return s[0] & 1; +} + +int FeIsNonZero(FieldElement f) { + var s = Uint8List(32); + FeToBytes(s, f); + var x = 0; + for (var i = 0; i < s.length; i++) { + x |= s[i]; + } + x |= x >> 4; + x |= x >> 2; + x |= x >> 1; + return x & 1; +} + +/// FeNeg sets h = -f +/// +/// Preconditions: +/// |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +/// +/// Postconditions: +/// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +void FeNeg(FieldElement h, FieldElement f) { + h[0] = -f[0]; + h[1] = -f[1]; + h[2] = -f[2]; + h[3] = -f[3]; + h[4] = -f[4]; + h[5] = -f[5]; + h[6] = -f[6]; + h[7] = -f[7]; + h[8] = -f[8]; + h[9] = -f[9]; +} + +void FeCombine(FieldElement h, Number h0, Number h1, Number h2, Number h3, + Number h4, Number h5, Number h6, Number h7, Number h8, Number h9) { + var c0 = Number.zero; + var c1 = Number.zero; + var c2 = Number.zero; + var c3 = Number.zero; + var c4 = Number.zero; + var c5 = Number.zero; + var c6 = Number.zero; + var c7 = Number.zero; + var c8 = Number.zero; + var c9 = Number.zero; + + /* + |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 + */ + + c0 = (h0 + (Number.one << 25)) >> 26; + h1 += c0; + h0 -= c0 << 26; + c4 = (h4 + (Number.one << 25)) >> 26; + h5 += c4; + h4 -= c4 << 26; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.51*2^58 */ + /* |h5| <= 1.51*2^58 */ + + c1 = (h1 + (Number.one << 24)) >> 25; + h2 += c1; + h1 -= c1 << 25; + c5 = (h5 + (Number.one << 24)) >> 25; + h6 += c5; + h5 -= c5 << 25; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.21*2^59 */ + /* |h6| <= 1.21*2^59 */ + + c2 = (h2 + (Number.one << 25)) >> 26; + h3 += c2; + h2 -= c2 << 26; + c6 = (h6 + (Number.one << 25)) >> 26; + h7 += c6; + h6 -= c6 << 26; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.51*2^58 */ + /* |h7| <= 1.51*2^58 */ + + c3 = (h3 + (Number.one << 24)) >> 25; + h4 += c3; + h3 -= c3 << 25; + c7 = (h7 + (Number.one << 24)) >> 25; + h8 += c7; + h7 -= c7 << 25; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.52*2^33 */ + /* |h8| <= 1.52*2^33 */ + + c4 = (h4 + (Number.one << 25)) >> 26; + h5 += c4; + h4 -= c4 << 26; + c8 = (h8 + (Number.one << 25)) >> 26; + h9 += c8; + h8 -= c8 << 26; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.51*2^58 */ + + c9 = (h9 + (Number.one << 24)) >> 25; + h0 += c9 * Numbers.v19; + h9 -= c9 << 25; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.8*2^37 */ + + c0 = (h0 + (Number.one << 25)) >> 26; + h1 += c0; + h0 -= c0 << 26; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/// FeMul calculates h = f * g +/// Can overlap h with f or g. +/// +/// Preconditions: +/// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +/// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +/// +/// Postconditions: +/// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +/// +/// Notes on implementation strategy: +/// +/// Using schoolbook multiplication. +/// Karatsuba would save a little in some cost models. +/// +/// Most multiplications by 2 and 19 are 32-bit precomputations; +/// cheaper than 64-bit postcomputations. +/// +/// There is one remaining multiplication by 19 in the carry chain; +/// one *19 precomputation can be merged into this, +/// but the resulting data flow is considerably less clean. +/// +/// There are 12 carries below. +/// 10 of them are 2-way parallelizable and vectorizable. +/// Can get away with 11 carries, but then data flow is much deeper. +/// +/// With tighter constraints on inputs, can squeeze carries into int32. +void FeMul(FieldElement h, FieldElement f, FieldElement g) { + var f0 = f[0]; + var f1 = f[1]; + var f2 = f[2]; + var f3 = f[3]; + var f4 = f[4]; + var f5 = f[5]; + var f6 = f[6]; + var f7 = f[7]; + var f8 = f[8]; + var f9 = f[9]; + + var f1_2 = Number.two * f[1]; + var f3_2 = Number.two * f[3]; + var f5_2 = Number.two * f[5]; + var f7_2 = Number.two * f[7]; + var f9_2 = Number.two * f[9]; + + var g0 = g[0]; + var g1 = g[1]; + var g2 = g[2]; + var g3 = g[3]; + var g4 = g[4]; + var g5 = g[5]; + var g6 = g[6]; + var g7 = g[7]; + var g8 = g[8]; + var g9 = g[9]; + + var g1_19 = Numbers.v19 * g[1]; /* 1.4*2^29 */ + var g2_19 = Numbers.v19 * g[2]; /* 1.4*2^30; still ok */ + var g3_19 = Numbers.v19 * g[3]; + var g4_19 = Numbers.v19 * g[4]; + var g5_19 = Numbers.v19 * g[5]; + var g6_19 = Numbers.v19 * g[6]; + var g7_19 = Numbers.v19 * g[7]; + var g8_19 = Numbers.v19 * g[8]; + var g9_19 = Numbers.v19 * g[9]; + + var h0 = f0 * g0 + + f1_2 * g9_19 + + f2 * g8_19 + + f3_2 * g7_19 + + f4 * g6_19 + + f5_2 * g5_19 + + f6 * g4_19 + + f7_2 * g3_19 + + f8 * g2_19 + + f9_2 * g1_19; + var h1 = f0 * g1 + + f1 * g0 + + f2 * g9_19 + + f3 * g8_19 + + f4 * g7_19 + + f5 * g6_19 + + f6 * g5_19 + + f7 * g4_19 + + f8 * g3_19 + + f9 * g2_19; + var h2 = f0 * g2 + + f1_2 * g1 + + f2 * g0 + + f3_2 * g9_19 + + f4 * g8_19 + + f5_2 * g7_19 + + f6 * g6_19 + + f7_2 * g5_19 + + f8 * g4_19 + + f9_2 * g3_19; + var h3 = f0 * g3 + + f1 * g2 + + f2 * g1 + + f3 * g0 + + f4 * g9_19 + + f5 * g8_19 + + f6 * g7_19 + + f7 * g6_19 + + f8 * g5_19 + + f9 * g4_19; + var h4 = f0 * g4 + + f1_2 * g3 + + f2 * g2 + + f3_2 * g1 + + f4 * g0 + + f5_2 * g9_19 + + f6 * g8_19 + + f7_2 * g7_19 + + f8 * g6_19 + + f9_2 * g5_19; + var h5 = f0 * g5 + + f1 * g4 + + f2 * g3 + + f3 * g2 + + f4 * g1 + + f5 * g0 + + f6 * g9_19 + + f7 * g8_19 + + f8 * g7_19 + + f9 * g6_19; + var h6 = f0 * g6 + + f1_2 * g5 + + f2 * g4 + + f3_2 * g3 + + f4 * g2 + + f5_2 * g1 + + f6 * g0 + + f7_2 * g9_19 + + f8 * g8_19 + + f9_2 * g7_19; + var h7 = f0 * g7 + + f1 * g6 + + f2 * g5 + + f3 * g4 + + f4 * g3 + + f5 * g2 + + f6 * g1 + + f7 * g0 + + f8 * g9_19 + + f9 * g8_19; + var h8 = f0 * g8 + + f1_2 * g7 + + f2 * g6 + + f3_2 * g5 + + f4 * g4 + + f5_2 * g3 + + f6 * g2 + + f7_2 * g1 + + f8 * g0 + + f9_2 * g9_19; + var h9 = f0 * g9 + + f1 * g8 + + f2 * g7 + + f3 * g6 + + f4 * g5 + + f5 * g4 + + f6 * g3 + + f7 * g2 + + f8 * g1 + + f9 * g0; + + FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9); +} + +List feSquare(FieldElement f) { + var f0 = f[0]; + var f1 = f[1]; + var f2 = f[2]; + var f3 = f[3]; + var f4 = f[4]; + var f5 = f[5]; + var f6 = f[6]; + var f7 = f[7]; + var f8 = f[8]; + var f9 = f[9]; + var f0_2 = Number.two * f[0]; + var f1_2 = Number.two * f[1]; + var f2_2 = Number.two * f[2]; + var f3_2 = Number.two * f[3]; + var f4_2 = Number.two * f[4]; + var f5_2 = Number.two * f[5]; + var f6_2 = Number.two * f[6]; + var f7_2 = Number.two * f[7]; + var f5_38 = Numbers.v38 * f5; // 1.31*2^30 + var f6_19 = Numbers.v19 * f6; // 1.31*2^30 + var f7_38 = Numbers.v38 * f7; // 1.31*2^30 + var f8_19 = Numbers.v19 * f8; // 1.31*2^30 + var f9_38 = Numbers.v38 * f9; // 1.31*2^30 + + var h0 = f0 * f0 + + f1_2 * f9_38 + + f2_2 * f8_19 + + f3_2 * f7_38 + + f4_2 * f6_19 + + f5 * f5_38; + var h1 = f0_2 * f1 + f2 * f9_38 + f3_2 * f8_19 + f4 * f7_38 + f5_2 * f6_19; + var h2 = f0_2 * f2 + + f1_2 * f1 + + f3_2 * f9_38 + + f4_2 * f8_19 + + f5_2 * f7_38 + + f6 * f6_19; + var h3 = f0_2 * f3 + f1_2 * f2 + f4 * f9_38 + f5_2 * f8_19 + f6 * f7_38; + var h4 = f0_2 * f4 + + f1_2 * f3_2 + + f2 * f2 + + f5_2 * f9_38 + + f6_2 * f8_19 + + f7 * f7_38; + var h5 = f0_2 * f5 + f1_2 * f4 + f2_2 * f3 + f6 * f9_38 + f7_2 * f8_19; + var h6 = f0_2 * f6 + + f1_2 * f5_2 + + f2_2 * f4 + + f3_2 * f3 + + f7_2 * f9_38 + + f8 * f8_19; + var h7 = f0_2 * f7 + f1_2 * f6 + f2_2 * f5 + f3_2 * f4 + f8 * f9_38; + var h8 = + f0_2 * f8 + f1_2 * f7_2 + f2_2 * f6 + f3_2 * f5_2 + f4 * f4 + f9 * f9_38; + var h9 = f0_2 * f9 + f1_2 * f8 + f2_2 * f7 + f3_2 * f6 + f4_2 * f5; + + return [h0, h1, h2, h3, h4, h5, h6, h7, h8, h9]; +} + +/// FeSquare calculates h = f*f. Can overlap h with f. +/// +/// Preconditions: +/// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +/// +/// Postconditions: +/// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +void FeSquare(FieldElement h, FieldElement f) { + var fs = feSquare(f); + var h0 = fs[0]; + var h1 = fs[1]; + var h2 = fs[2]; + var h3 = fs[3]; + var h4 = fs[4]; + var h5 = fs[5]; + var h6 = fs[6]; + var h7 = fs[7]; + var h8 = fs[8]; + var h9 = fs[9]; + FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9); +} + +/// FeSquare2 sets h = 2 * f * f +/// +/// Can overlap h with f. +/// +/// Preconditions: +/// |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. +/// +/// Postconditions: +/// |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +/// See fe_mul.c for discussion of implementation strategy. +void FeSquare2(FieldElement h, FieldElement f) { + var fs = feSquare(f); + var h0 = fs[0]; + var h1 = fs[1]; + var h2 = fs[2]; + var h3 = fs[3]; + var h4 = fs[4]; + var h5 = fs[5]; + var h6 = fs[6]; + var h7 = fs[7]; + var h8 = fs[8]; + var h9 = fs[9]; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9); +} + +void FeInvert(FieldElement out, FieldElement z) { + var t0 = FieldElement(); + var t1 = FieldElement(); + var t2 = FieldElement(); + var t3 = FieldElement(); + var i = 0; + + FeSquare(t0, z); // 2^1 + FeSquare(t1, t0); // 2^2 + for (i = 1; i < 2; i++) { + // 2^3 + FeSquare(t1, t1); + } + FeMul(t1, z, t1); // 2^3 + 2^0 + FeMul(t0, t0, t1); // 2^3 + 2^1 + 2^0 + FeSquare(t2, t0); // 2^4 + 2^2 + 2^1 + FeMul(t1, t1, t2); // 2^4 + 2^3 + 2^2 + 2^1 + 2^0 + FeSquare(t2, t1); // 5,4,3,2,1 + for (i = 1; i < 5; i++) { + // 9,8,7,6,5 + FeSquare(t2, t2); + } + FeMul(t1, t2, t1); // 9,8,7,6,5,4,3,2,1,0 + FeSquare(t2, t1); // 10..1 + for (i = 1; i < 10; i++) { + // 19..10 + FeSquare(t2, t2); + } + FeMul(t2, t2, t1); // 19..0 + FeSquare(t3, t2); // 20..1 + for (i = 1; i < 20; i++) { + // 39..20 + FeSquare(t3, t3); + } + FeMul(t2, t3, t2); // 39..0 + FeSquare(t2, t2); // 40..1 + for (i = 1; i < 10; i++) { + // 49..10 + FeSquare(t2, t2); + } + FeMul(t1, t2, t1); // 49..0 + FeSquare(t2, t1); // 50..1 + for (i = 1; i < 50; i++) { + // 99..50 + FeSquare(t2, t2); + } + FeMul(t2, t2, t1); // 99..0 + FeSquare(t3, t2); // 100..1 + for (i = 1; i < 100; i++) { + // 199..100 + FeSquare(t3, t3); + } + FeMul(t2, t3, t2); // 199..0 + FeSquare(t2, t2); // 200..1 + for (i = 1; i < 50; i++) { + // 249..50 + FeSquare(t2, t2); + } + FeMul(t1, t2, t1); // 249..0 + FeSquare(t1, t1); // 250..1 + for (i = 1; i < 5; i++) { + // 254..5 + FeSquare(t1, t1); + } + FeMul(out, t1, t0); // 254..5,3,1,0 +} + +void fePow22523(FieldElement out, FieldElement z) { + var t0 = FieldElement(); + var t1 = FieldElement(); + var t2 = FieldElement(); + var i = 0; + + FeSquare(t0, z); + for (i = 1; i < 1; i++) { + FeSquare(t0, t0); + } + FeSquare(t1, t0); + for (i = 1; i < 2; i++) { + FeSquare(t1, t1); + } + FeMul(t1, z, t1); + FeMul(t0, t0, t1); + FeSquare(t0, t0); + for (i = 1; i < 1; i++) { + FeSquare(t0, t0); + } + FeMul(t0, t1, t0); + FeSquare(t1, t0); + for (i = 1; i < 5; i++) { + FeSquare(t1, t1); + } + FeMul(t0, t1, t0); + FeSquare(t1, t0); + for (i = 1; i < 10; i++) { + FeSquare(t1, t1); + } + FeMul(t1, t1, t0); + FeSquare(t2, t1); + for (i = 1; i < 20; i++) { + FeSquare(t2, t2); + } + FeMul(t1, t2, t1); + FeSquare(t1, t1); + for (i = 1; i < 10; i++) { + FeSquare(t1, t1); + } + FeMul(t0, t1, t0); + FeSquare(t1, t0); + for (i = 1; i < 50; i++) { + FeSquare(t1, t1); + } + FeMul(t1, t1, t0); + FeSquare(t2, t1); + for (i = 1; i < 100; i++) { + FeSquare(t2, t2); + } + FeMul(t1, t2, t1); + FeSquare(t1, t1); + for (i = 1; i < 50; i++) { + FeSquare(t1, t1); + } + FeMul(t0, t1, t0); + FeSquare(t0, t0); + for (i = 1; i < 2; i++) { + FeSquare(t0, t0); + } + FeMul(out, t0, z); +} + +/// Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 * +/// y^2 where d = -121665/121666. +/// +/// Several representations are used: +/// ProjectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z +/// ExtendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT +/// CompletedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T +/// PreComputedGroupElement: (y+x,y-x,2dxy) +class ProjectiveGroupElement { + FieldElement X = FieldElement(); + FieldElement Y = FieldElement(); + FieldElement Z = FieldElement(); + + void Zero() { + FeZero(X); + FeOne(Y); + FeOne(Z); + } + + void Double(CompletedGroupElement r) { + var t0 = FieldElement(); + + FeSquare(r.X, X); + FeSquare(r.Z, Y); + FeSquare2(r.T, Z); + FeAdd(r.Y, X, Y); + FeSquare(t0, r.Y); + FeAdd(r.Y, r.Z, r.X); + FeSub(r.Z, r.Z, r.X); + FeSub(r.X, t0, r.Y); + FeSub(r.T, r.T, r.Z); + } + + void ToBytes(Uint8List s) { + var recip = FieldElement(); + var x = FieldElement(); + var y = FieldElement(); + + FeInvert(recip, Z); + FeMul(x, X, recip); + FeMul(y, Y, recip); + FeToBytes(s, y); + s[31] ^= FeIsNegative(x) << 7; + } +} + +class ExtendedGroupElement { + FieldElement X = FieldElement(); + FieldElement Y = FieldElement(); + FieldElement Z = FieldElement(); + FieldElement T = FieldElement(); + + void Zero() { + FeZero(X); + FeOne(Y); + FeOne(Z); + FeZero(T); + } + + void Double(CompletedGroupElement r) { + var q = ProjectiveGroupElement(); + ToProjective(q); + q.Double(r); + } + + void ToCached(CachedGroupElement r) { + FeAdd(r.yPlusX, Y, X); + FeSub(r.yMinusX, Y, X); + FeCopy(r.Z, Z); + FeMul(r.T2d, T, d2); + } + + void ToProjective(ProjectiveGroupElement r) { + FeCopy(r.X, X); + FeCopy(r.Y, Y); + FeCopy(r.Z, Z); + } + + void ToBytes(Uint8List s) { + var recip = FieldElement(); + var x = FieldElement(); + var y = FieldElement(); + + FeInvert(recip, Z); + FeMul(x, X, recip); + FeMul(y, Y, recip); + FeToBytes(s, y); + s[31] ^= FeIsNegative(x) << 7; + } + + bool FromBytes(Uint8List s) { + var u = FieldElement(); + var v = FieldElement(); + var v3 = FieldElement(); + var vxx = FieldElement(); + var check = FieldElement(); + + FeFromBytes(Y, s); + FeOne(Z); + FeSquare(u, Y); + FeMul(v, u, d); + FeSub(u, u, Z); // y = y^2-1 + FeAdd(v, v, Z); // v = dy^2+1 + + FeSquare(v3, v); + FeMul(v3, v3, v); // v3 = v^3 + FeSquare(X, v3); + FeMul(X, X, v); + FeMul(X, X, u); // x = uv^7 + + fePow22523(X, X); // x = (uv^7)^((q-5)/8) + FeMul(X, X, v3); + FeMul(X, X, u); // x = uv^3(uv^7)^((q-5)/8) + + var tmpX = Uint8List(32); + var tmp2 = Uint8List(32); + + FeSquare(vxx, X); + FeMul(vxx, vxx, v); + FeSub(check, vxx, u); // vx^2-u + if (FeIsNonZero(check) == 1) { + FeAdd(check, vxx, u); // vx^2+u + if (FeIsNonZero(check) == 1) { + return false; + } + FeMul(X, X, SqrtM1); + + FeToBytes(tmpX, X); + for (var i = 0; i < tmp2.length; i++) { + tmp2[31 - i] = tmp2[i]; + } + } + + if (FeIsNegative(X) != (s[31] >> 7)) { + FeNeg(X, X); + } + + FeMul(T, X, Y); + return true; + } +} + +class CompletedGroupElement { + FieldElement X = FieldElement(); + FieldElement Y = FieldElement(); + FieldElement Z = FieldElement(); + FieldElement T = FieldElement(); + + void ToProjective(ProjectiveGroupElement r) { + FeMul(r.X, X, T); + FeMul(r.Y, Y, Z); + FeMul(r.Z, Z, T); + } + + void ToExtended(ExtendedGroupElement r) { + FeMul(r.X, X, T); + FeMul(r.Y, Y, Z); + FeMul(r.Z, Z, T); + FeMul(r.T, X, Y); + } +} + +class PreComputedGroupElement { + FieldElement yPlusX = FieldElement(); + FieldElement yMinusX = FieldElement(); + FieldElement xy2d = FieldElement(); + + PreComputedGroupElement(); + + PreComputedGroupElement.fromList( + FieldElement ypx, FieldElement ymx, FieldElement xy2d) { + yPlusX = ypx; + yMinusX = ymx; + this.xy2d = xy2d; + } + + void Zero() { + FeOne(yPlusX); + FeOne(yMinusX); + FeZero(xy2d); + } +} + +class CachedGroupElement { + FieldElement yPlusX = FieldElement(); + FieldElement yMinusX = FieldElement(); + FieldElement Z = FieldElement(); + FieldElement T2d = FieldElement(); +} + +void geAdd( + CompletedGroupElement r, ExtendedGroupElement p, CachedGroupElement q) { + var t0 = FieldElement(); + + FeAdd(r.X, p.Y, p.X); + FeSub(r.Y, p.Y, p.X); + FeMul(r.Z, r.X, q.yPlusX); + FeMul(r.Y, r.Y, q.yMinusX); + FeMul(r.T, q.T2d, p.T); + FeMul(r.X, p.Z, q.Z); + FeAdd(t0, r.X, r.X); + FeSub(r.X, r.Z, r.Y); + FeAdd(r.Y, r.Z, r.Y); + FeAdd(r.Z, t0, r.T); + FeSub(r.T, t0, r.T); +} + +void geSub( + CompletedGroupElement r, ExtendedGroupElement p, CachedGroupElement q) { + var t0 = FieldElement(); + + FeAdd(r.X, p.Y, p.X); + FeSub(r.Y, p.Y, p.X); + FeMul(r.Z, r.X, q.yMinusX); + FeMul(r.Y, r.Y, q.yPlusX); + FeMul(r.T, q.T2d, p.T); + FeMul(r.X, p.Z, q.Z); + FeAdd(t0, r.X, r.X); + FeSub(r.X, r.Z, r.Y); + FeAdd(r.Y, r.Z, r.Y); + FeSub(r.Z, t0, r.T); + FeAdd(r.T, t0, r.T); +} + +void geMixedAdd(CompletedGroupElement r, ExtendedGroupElement p, + PreComputedGroupElement q) { + var t0 = FieldElement(); + + FeAdd(r.X, p.Y, p.X); + FeSub(r.Y, p.Y, p.X); + FeMul(r.Z, r.X, q.yPlusX); + FeMul(r.Y, r.Y, q.yMinusX); + FeMul(r.T, q.xy2d, p.T); + FeAdd(t0, p.Z, p.Z); + FeSub(r.X, r.Z, r.Y); + FeAdd(r.Y, r.Z, r.Y); + FeAdd(r.Z, t0, r.T); + FeSub(r.T, t0, r.T); +} + +void geMixedSub(CompletedGroupElement r, ExtendedGroupElement p, + PreComputedGroupElement q) { + var t0 = FieldElement(); + + FeAdd(r.X, p.Y, p.X); + FeSub(r.Y, p.Y, p.X); + FeMul(r.Z, r.X, q.yMinusX); + FeMul(r.Y, r.Y, q.yPlusX); + FeMul(r.T, q.xy2d, p.T); + FeAdd(t0, p.Z, p.Z); + FeSub(r.X, r.Z, r.Y); + FeAdd(r.Y, r.Z, r.Y); + FeSub(r.Z, t0, r.T); + FeAdd(r.T, t0, r.T); +} + +void slide(Int8List r, Uint8List a) { + for (var i = 0; i < r.length; i++) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (var i = 0; i < r.length; i++) { + if (r[i] != 0) { + for (var b = 1; b <= 6 && i + b < 256; b++) { + if (r[i + b] != 0) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (var k = i + b; k < 256; k++) { + if (r[k] == 0) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } +} + +/// GeDoubleScalarMultVartime sets r = a*A + b*B +/// where a = a[0]+256*a[1]+...+256^31 a[31]. +/// and b = b[0]+256*b[1]+...+256^31 b[31]. +/// B is the Ed25519 base point (x,4/5) with x positive. +void GeDoubleScalarMultVartime(ProjectiveGroupElement r, Uint8List a, + ExtendedGroupElement A, Uint8List b) { + var aSlide = Int8List(256); + var bSlide = Int8List(256); + var Ai = List.generate( + 8, (index) => CachedGroupElement()); // A,3A,5A,7A,9A,11A,13A,15A + var t = CompletedGroupElement(); + var u = ExtendedGroupElement(); + var A2 = ExtendedGroupElement(); + int i; + + slide(aSlide, a); + slide(bSlide, b); + + A.ToCached(Ai[0]); + A.Double(t); + t.ToExtended(A2); + + for (i = 0; i < 7; i++) { + geAdd(t, A2, Ai[i]); + t.ToExtended(u); + u.ToCached(Ai[i + 1]); + } + + r.Zero(); + + for (i = 255; i >= 0; i--) { + if (aSlide[i] != 0 || bSlide[i] != 0) { + break; + } + } + + for (; i >= 0; i--) { + r.Double(t); + + if (aSlide[i] > 0) { + t.ToExtended(u); + geAdd(t, u, Ai[aSlide[i] ~/ 2]); + } else if (aSlide[i] < 0) { + t.ToExtended(u); + geSub(t, u, Ai[(-aSlide[i]) ~/ 2]); + } + + if (bSlide[i] > 0) { + t.ToExtended(u); + geMixedAdd(t, u, bi[bSlide[i] ~/ 2]); + } else if (bSlide[i] < 0) { + t.ToExtended(u); + geMixedSub(t, u, bi[(-bSlide[i]) ~/ 2]); + } + + t.ToProjective(r); + } +} + +/// equal returns 1 if b == c and 0 otherwise, assuming that b and c are +/// non-negative. +Number equal(Number b, Number c) { + if (b == c) { + return Number.one; + } else { + return Number.zero; + } +// var x = b ^ c; +// x--; +// return x >> 31; +} + +/// negative returns 1 if b < 0 and 0 otherwise. +Number negative(Number b) { + if (b < Number.zero) { + return Number.one; + } else { + return Number.zero; + } +// return (b >> 31) & 1; +} + +void PreComputedGroupElementCMove( + PreComputedGroupElement t, PreComputedGroupElement u, Number b) { + FeCMove(t.yPlusX, u.yPlusX, b); + FeCMove(t.yMinusX, u.yMinusX, b); + FeCMove(t.xy2d, u.xy2d, b); +} + +void selectPoint(PreComputedGroupElement t, int pos, Number b) { + var minusT = PreComputedGroupElement(); + var bNegative = negative(b); + var bAbs = b - (((-bNegative) & b) << 1); + + t.Zero(); + for (var i = 0; i < 8; i++) { + PreComputedGroupElementCMove(t, base[pos][i], equal(bAbs, Number(i + 1))); + } + FeCopy(minusT.yPlusX, t.yMinusX); + FeCopy(minusT.yMinusX, t.yPlusX); + FeNeg(minusT.xy2d, t.xy2d); + PreComputedGroupElementCMove(t, minusT, bNegative); +} + +/// GeScalarMultBase computes h = a*B, where +/// a = a[0]+256*a[1]+...+256^31 a[31] +/// B is the Ed25519 base point (x,4/5) with x positive. +/// +/// Preconditions: +/// a[31] <= 127 +void GeScalarMultBase(ExtendedGroupElement h, Uint8List a) { + var e = List.filled(64, Number.zero); + + for (var i = 0; i < a.length; i++) { + var v = a[i]; + e[2 * i] = Number(v) & Numbers.v15; + e[2 * i + 1] = Number((v >> 4)) & Numbers.v15; + } + + // each e[i] is between 0 and 15 and e[63] is between 0 and 7. + + var carry = Number.zero; + for (var i = 0; i < 63; i++) { + e[i] += carry; + carry = (e[i] + Numbers.v8) >> 4; + e[i] -= carry << 4; + } + e[63] += carry; + // each e[i] is between -8 and 8. + + h.Zero(); + var t = PreComputedGroupElement(); + var r = CompletedGroupElement(); + for (var i = 1; i < 64; i += 2) { + selectPoint(t, i ~/ 2, e[i]); + geMixedAdd(r, h, t); + r.ToExtended(h); + } + + var s = ProjectiveGroupElement(); + + h.Double(r); + r.ToProjective(s); + s.Double(r); + r.ToProjective(s); + s.Double(r); + r.ToProjective(s); + s.Double(r); + r.ToExtended(h); + + for (var i = 0; i < 64; i += 2) { + selectPoint(t, i ~/ 2, e[i]); + geMixedAdd(r, h, t); + r.ToExtended(h); + } +} + +/// The scalars are GF(2^252 + 27742317777372353535851937790883648493). + +/// Input: +/// a[0]+256*a[1]+...+256^31*a[31] = a +/// b[0]+256*b[1]+...+256^31*b[31] = b +/// c[0]+256*c[1]+...+256^31*c[31] = c +/// +/// Output: +/// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l +/// where l = 2^252 + 27742317777372353535851937790883648493. +void ScMulAdd(Uint8List s, Uint8List a, Uint8List b, Uint8List c) { + var a0 = Numbers.v2097151 & load3(a.sublist(0, a.length)); + var a1 = Numbers.v2097151 & (load4(a.sublist(2, a.length)) >> 5); + var a2 = Numbers.v2097151 & (load3(a.sublist(5, a.length)) >> 2); + var a3 = Numbers.v2097151 & (load4(a.sublist(7, a.length)) >> 7); + var a4 = Numbers.v2097151 & (load4(a.sublist(10, a.length)) >> 4); + var a5 = Numbers.v2097151 & (load3(a.sublist(13, a.length)) >> 1); + var a6 = Numbers.v2097151 & (load4(a.sublist(15, a.length)) >> 6); + var a7 = Numbers.v2097151 & (load3(a.sublist(18, a.length)) >> 3); + var a8 = Numbers.v2097151 & load3(a.sublist(21, a.length)); + var a9 = Numbers.v2097151 & (load4(a.sublist(23, a.length)) >> 5); + var a10 = Numbers.v2097151 & (load3(a.sublist(26, a.length)) >> 2); + var a11 = (load4(a.sublist(28, a.length)) >> 7); + + var b0 = Numbers.v2097151 & load3(b.sublist(0, b.length)); + var b1 = Numbers.v2097151 & (load4(b.sublist(2, b.length)) >> 5); + var b2 = Numbers.v2097151 & (load3(b.sublist(5, b.length)) >> 2); + var b3 = Numbers.v2097151 & (load4(b.sublist(7, b.length)) >> 7); + var b4 = Numbers.v2097151 & (load4(b.sublist(10, b.length)) >> 4); + var b5 = Numbers.v2097151 & (load3(b.sublist(13, b.length)) >> 1); + var b6 = Numbers.v2097151 & (load4(b.sublist(15, b.length)) >> 6); + var b7 = Numbers.v2097151 & (load3(b.sublist(18, b.length)) >> 3); + var b8 = Numbers.v2097151 & load3(b.sublist(21, b.length)); + var b9 = Numbers.v2097151 & (load4(b.sublist(23, b.length)) >> 5); + var b10 = Numbers.v2097151 & (load3(b.sublist(26, b.length)) >> 2); + var b11 = (load4(b.sublist(28, b.length)) >> 7); + + var c0 = Numbers.v2097151 & load3(c.sublist(0, c.length)); + var c1 = Numbers.v2097151 & (load4(c.sublist(2, c.length)) >> 5); + var c2 = Numbers.v2097151 & (load3(c.sublist(5, c.length)) >> 2); + var c3 = Numbers.v2097151 & (load4(c.sublist(7, c.length)) >> 7); + var c4 = Numbers.v2097151 & (load4(c.sublist(10, c.length)) >> 4); + var c5 = Numbers.v2097151 & (load3(c.sublist(13, c.length)) >> 1); + var c6 = Numbers.v2097151 & (load4(c.sublist(15, c.length)) >> 6); + var c7 = Numbers.v2097151 & (load3(c.sublist(18, c.length)) >> 3); + var c8 = Numbers.v2097151 & load3(c.sublist(21, c.length)); + var c9 = Numbers.v2097151 & (load4(c.sublist(23, c.length)) >> 5); + var c10 = Numbers.v2097151 & (load3(c.sublist(26, c.length)) >> 2); + var c11 = (load4(c.sublist(28, c.length)) >> 7); + + var carry = List.filled(23, Number.zero); + + var s0 = c0 + a0 * b0; + var s1 = c1 + a0 * b1 + a1 * b0; + var s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + var s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + var s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + var s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + var s6 = + c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + var s7 = c7 + + a0 * b7 + + a1 * b6 + + a2 * b5 + + a3 * b4 + + a4 * b3 + + a5 * b2 + + a6 * b1 + + a7 * b0; + var s8 = c8 + + a0 * b8 + + a1 * b7 + + a2 * b6 + + a3 * b5 + + a4 * b4 + + a5 * b3 + + a6 * b2 + + a7 * b1 + + a8 * b0; + var s9 = c9 + + a0 * b9 + + a1 * b8 + + a2 * b7 + + a3 * b6 + + a4 * b5 + + a5 * b4 + + a6 * b3 + + a7 * b2 + + a8 * b1 + + a9 * b0; + var s10 = c10 + + a0 * b10 + + a1 * b9 + + a2 * b8 + + a3 * b7 + + a4 * b6 + + a5 * b5 + + a6 * b4 + + a7 * b3 + + a8 * b2 + + a9 * b1 + + a10 * b0; + var s11 = c11 + + a0 * b11 + + a1 * b10 + + a2 * b9 + + a3 * b8 + + a4 * b7 + + a5 * b6 + + a6 * b5 + + a7 * b4 + + a8 * b3 + + a9 * b2 + + a10 * b1 + + a11 * b0; + var s12 = a1 * b11 + + a2 * b10 + + a3 * b9 + + a4 * b8 + + a5 * b7 + + a6 * b6 + + a7 * b5 + + a8 * b4 + + a9 * b3 + + a10 * b2 + + a11 * b1; + var s13 = a2 * b11 + + a3 * b10 + + a4 * b9 + + a5 * b8 + + a6 * b7 + + a7 * b6 + + a8 * b5 + + a9 * b4 + + a10 * b3 + + a11 * b2; + var s14 = a3 * b11 + + a4 * b10 + + a5 * b9 + + a6 * b8 + + a7 * b7 + + a8 * b6 + + a9 * b5 + + a10 * b4 + + a11 * b3; + var s15 = a4 * b11 + + a5 * b10 + + a6 * b9 + + a7 * b8 + + a8 * b7 + + a9 * b6 + + a10 * b5 + + a11 * b4; + var s16 = + a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + var s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + var s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + var s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + var s20 = a9 * b11 + a10 * b10 + a11 * b9; + var s21 = a10 * b11 + a11 * b10; + var s22 = a11 * b11; + var s23 = Number.zero; + + carry[0] = (s0 + (Number.one << 20)) >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[2] = (s2 + (Number.one << 20)) >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[4] = (s4 + (Number.one << 20)) >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[6] = (s6 + (Number.one << 20)) >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[8] = (s8 + (Number.one << 20)) >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[10] = (s10 + (Number.one << 20)) >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + carry[12] = (s12 + (Number.one << 20)) >> 21; + s13 += carry[12]; + s12 -= carry[12] << 21; + carry[14] = (s14 + (Number.one << 20)) >> 21; + s15 += carry[14]; + s14 -= carry[14] << 21; + carry[16] = (s16 + (Number.one << 20)) >> 21; + s17 += carry[16]; + s16 -= carry[16] << 21; + carry[18] = (s18 + (Number.one << 20)) >> 21; + s19 += carry[18]; + s18 -= carry[18] << 21; + carry[20] = (s20 + (Number.one << 20)) >> 21; + s21 += carry[20]; + s20 -= carry[20] << 21; + carry[22] = (s22 + (Number.one << 20)) >> 21; + s23 += carry[22]; + s22 -= carry[22] << 21; + + carry[1] = (s1 + (Number.one << 20)) >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[3] = (s3 + (Number.one << 20)) >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[5] = (s5 + (Number.one << 20)) >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[7] = (s7 + (Number.one << 20)) >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[9] = (s9 + (Number.one << 20)) >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[11] = (s11 + (Number.one << 20)) >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + carry[13] = (s13 + (Number.one << 20)) >> 21; + s14 += carry[13]; + s13 -= carry[13] << 21; + carry[15] = (s15 + (Number.one << 20)) >> 21; + s16 += carry[15]; + s15 -= carry[15] << 21; + carry[17] = (s17 + (Number.one << 20)) >> 21; + s18 += carry[17]; + s17 -= carry[17] << 21; + carry[19] = (s19 + (Number.one << 20)) >> 21; + s20 += carry[19]; + s19 -= carry[19] << 21; + carry[21] = (s21 + (Number.one << 20)) >> 21; + s22 += carry[21]; + s21 -= carry[21] << 21; + + s11 += s23 * Numbers.v666643; + s12 += s23 * Numbers.v470296; + s13 += s23 * Numbers.v654183; + s14 -= s23 * Numbers.v997805; + s15 += s23 * Numbers.v136657; + s16 -= s23 * Numbers.v683901; + s23 = Number.zero; + + s10 += s22 * Numbers.v666643; + s11 += s22 * Numbers.v470296; + s12 += s22 * Numbers.v654183; + s13 -= s22 * Numbers.v997805; + s14 += s22 * Numbers.v136657; + s15 -= s22 * Numbers.v683901; + s22 = Number.zero; + + s9 += s21 * Numbers.v666643; + s10 += s21 * Numbers.v470296; + s11 += s21 * Numbers.v654183; + s12 -= s21 * Numbers.v997805; + s13 += s21 * Numbers.v136657; + s14 -= s21 * Numbers.v683901; + s21 = Number.zero; + + s8 += s20 * Numbers.v666643; + s9 += s20 * Numbers.v470296; + s10 += s20 * Numbers.v654183; + s11 -= s20 * Numbers.v997805; + s12 += s20 * Numbers.v136657; + s13 -= s20 * Numbers.v683901; + s20 = Number.zero; + + s7 += s19 * Numbers.v666643; + s8 += s19 * Numbers.v470296; + s9 += s19 * Numbers.v654183; + s10 -= s19 * Numbers.v997805; + s11 += s19 * Numbers.v136657; + s12 -= s19 * Numbers.v683901; + s19 = Number.zero; + + s6 += s18 * Numbers.v666643; + s7 += s18 * Numbers.v470296; + s8 += s18 * Numbers.v654183; + s9 -= s18 * Numbers.v997805; + s10 += s18 * Numbers.v136657; + s11 -= s18 * Numbers.v683901; + s18 = Number.zero; + + carry[6] = (s6 + (Number.one << 20)) >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[8] = (s8 + (Number.one << 20)) >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[10] = (s10 + (Number.one << 20)) >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + carry[12] = (s12 + (Number.one << 20)) >> 21; + s13 += carry[12]; + s12 -= carry[12] << 21; + carry[14] = (s14 + (Number.one << 20)) >> 21; + s15 += carry[14]; + s14 -= carry[14] << 21; + carry[16] = (s16 + (Number.one << 20)) >> 21; + s17 += carry[16]; + s16 -= carry[16] << 21; + + carry[7] = (s7 + (Number.one << 20)) >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[9] = (s9 + (Number.one << 20)) >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[11] = (s11 + (Number.one << 20)) >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + carry[13] = (s13 + (Number.one << 20)) >> 21; + s14 += carry[13]; + s13 -= carry[13] << 21; + carry[15] = (s15 + (Number.one << 20)) >> 21; + s16 += carry[15]; + s15 -= carry[15] << 21; + + s5 += s17 * Numbers.v666643; + s6 += s17 * Numbers.v470296; + s7 += s17 * Numbers.v654183; + s8 -= s17 * Numbers.v997805; + s9 += s17 * Numbers.v136657; + s10 -= s17 * Numbers.v683901; + s17 = Number.zero; + + s4 += s16 * Numbers.v666643; + s5 += s16 * Numbers.v470296; + s6 += s16 * Numbers.v654183; + s7 -= s16 * Numbers.v997805; + s8 += s16 * Numbers.v136657; + s9 -= s16 * Numbers.v683901; + s16 = Number.zero; + + s3 += s15 * Numbers.v666643; + s4 += s15 * Numbers.v470296; + s5 += s15 * Numbers.v654183; + s6 -= s15 * Numbers.v997805; + s7 += s15 * Numbers.v136657; + s8 -= s15 * Numbers.v683901; + s15 = Number.zero; + + s2 += s14 * Numbers.v666643; + s3 += s14 * Numbers.v470296; + s4 += s14 * Numbers.v654183; + s5 -= s14 * Numbers.v997805; + s6 += s14 * Numbers.v136657; + s7 -= s14 * Numbers.v683901; + s14 = Number.zero; + + s1 += s13 * Numbers.v666643; + s2 += s13 * Numbers.v470296; + s3 += s13 * Numbers.v654183; + s4 -= s13 * Numbers.v997805; + s5 += s13 * Numbers.v136657; + s6 -= s13 * Numbers.v683901; + s13 = Number.zero; + + s0 += s12 * Numbers.v666643; + s1 += s12 * Numbers.v470296; + s2 += s12 * Numbers.v654183; + s3 -= s12 * Numbers.v997805; + s4 += s12 * Numbers.v136657; + s5 -= s12 * Numbers.v683901; + s12 = Number.zero; + + carry[0] = (s0 + (Number.one << 20)) >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[2] = (s2 + (Number.one << 20)) >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[4] = (s4 + (Number.one << 20)) >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[6] = (s6 + (Number.one << 20)) >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[8] = (s8 + (Number.one << 20)) >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[10] = (s10 + (Number.one << 20)) >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + + carry[1] = (s1 + (Number.one << 20)) >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[3] = (s3 + (Number.one << 20)) >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[5] = (s5 + (Number.one << 20)) >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[7] = (s7 + (Number.one << 20)) >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[9] = (s9 + (Number.one << 20)) >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[11] = (s11 + (Number.one << 20)) >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + + s0 += s12 * Numbers.v666643; + s1 += s12 * Numbers.v470296; + s2 += s12 * Numbers.v654183; + s3 -= s12 * Numbers.v997805; + s4 += s12 * Numbers.v136657; + s5 -= s12 * Numbers.v683901; + s12 = Number.zero; + + carry[0] = s0 >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[1] = s1 >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[2] = s2 >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[3] = s3 >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[4] = s4 >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[5] = s5 >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[6] = s6 >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[7] = s7 >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[8] = s8 >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[9] = s9 >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[10] = s10 >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + carry[11] = s11 >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + + s0 += s12 * Numbers.v666643; + s1 += s12 * Numbers.v470296; + s2 += s12 * Numbers.v654183; + s3 -= s12 * Numbers.v997805; + s4 += s12 * Numbers.v136657; + s5 -= s12 * Numbers.v683901; + s12 = Number.zero; + + carry[0] = s0 >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[1] = s1 >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[2] = s2 >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[3] = s3 >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[4] = s4 >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[5] = s5 >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[6] = s6 >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[7] = s7 >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[8] = s8 >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[9] = s9 >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[10] = s10 >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + + s[0] = (s0 >> 0).intValue; + s[1] = (s0 >> 8).intValue; + s[2] = ((s0 >> 16) | (s1 << 5)).intValue; + s[3] = (s1 >> 3).intValue; + s[4] = (s1 >> 11).intValue; + s[5] = ((s1 >> 19) | (s2 << 2)).intValue; + s[6] = (s2 >> 6).intValue; + s[7] = ((s2 >> 14) | (s3 << 7)).intValue; + s[8] = (s3 >> 1).intValue; + s[9] = (s3 >> 9).intValue; + s[10] = ((s3 >> 17) | (s4 << 4)).intValue; + s[11] = (s4 >> 4).intValue; + s[12] = (s4 >> 12).intValue; + s[13] = ((s4 >> 20) | (s5 << 1)).intValue; + s[14] = (s5 >> 7).intValue; + s[15] = ((s5 >> 15) | (s6 << 6)).intValue; + s[16] = (s6 >> 2).intValue; + s[17] = (s6 >> 10).intValue; + s[18] = ((s6 >> 18) | (s7 << 3)).intValue; + s[19] = (s7 >> 5).intValue; + s[20] = (s7 >> 13).intValue; + s[21] = (s8 >> 0).intValue; + s[22] = (s8 >> 8).intValue; + s[23] = ((s8 >> 16) | (s9 << 5)).intValue; + s[24] = (s9 >> 3).intValue; + s[25] = (s9 >> 11).intValue; + s[26] = ((s9 >> 19) | (s10 << 2)).intValue; + s[27] = (s10 >> 6).intValue; + s[28] = ((s10 >> 14) | (s11 << 7)).intValue; + s[29] = (s11 >> 1).intValue; + s[30] = (s11 >> 9).intValue; + s[31] = (s11 >> 17).intValue; +} + +/// Input: +/// s[0]+256*s[1]+...+256^63*s[63] = s +/// +/// Output: +/// s[0]+256*s[1]+...+256^31*s[31] = s mod l +/// where l = 2^252 + 27742317777372353535851937790883648493. +void ScReduce(Uint8List out, Uint8List s) { + var s0 = Numbers.v2097151 & load3(s.sublist(0, s.length)); + var s1 = Numbers.v2097151 & (load4(s.sublist(2, s.length)) >> 5); + var s2 = Numbers.v2097151 & (load3(s.sublist(5, s.length)) >> 2); + var s3 = Numbers.v2097151 & (load4(s.sublist(7, s.length)) >> 7); + var s4 = Numbers.v2097151 & (load4(s.sublist(10, s.length)) >> 4); + var s5 = Numbers.v2097151 & (load3(s.sublist(13, s.length)) >> 1); + var s6 = Numbers.v2097151 & (load4(s.sublist(15, s.length)) >> 6); + var s7 = Numbers.v2097151 & (load3(s.sublist(18, s.length)) >> 3); + var s8 = Numbers.v2097151 & load3(s.sublist(21, s.length)); + var s9 = Numbers.v2097151 & (load4(s.sublist(23, s.length)) >> 5); + var s10 = Numbers.v2097151 & (load3(s.sublist(26, s.length)) >> 2); + var s11 = Numbers.v2097151 & (load4(s.sublist(28, s.length)) >> 7); + var s12 = Numbers.v2097151 & (load4(s.sublist(31, s.length)) >> 4); + var s13 = Numbers.v2097151 & (load3(s.sublist(34, s.length)) >> 1); + var s14 = Numbers.v2097151 & (load4(s.sublist(36, s.length)) >> 6); + var s15 = Numbers.v2097151 & (load3(s.sublist(39, s.length)) >> 3); + var s16 = Numbers.v2097151 & load3(s.sublist(42, s.length)); + var s17 = Numbers.v2097151 & (load4(s.sublist(44, s.length)) >> 5); + var s18 = Numbers.v2097151 & (load3(s.sublist(47, s.length)) >> 2); + var s19 = Numbers.v2097151 & (load4(s.sublist(49, s.length)) >> 7); + var s20 = Numbers.v2097151 & (load4(s.sublist(52, s.length)) >> 4); + var s21 = Numbers.v2097151 & (load3(s.sublist(55, s.length)) >> 1); + var s22 = Numbers.v2097151 & (load4(s.sublist(57, s.length)) >> 6); + var s23 = (load4(s.sublist(60, s.length)) >> 3); + + s11 += s23 * Numbers.v666643; + s12 += s23 * Numbers.v470296; + s13 += s23 * Numbers.v654183; + s14 -= s23 * Numbers.v997805; + s15 += s23 * Numbers.v136657; + s16 -= s23 * Numbers.v683901; + s23 = Number.zero; + + s10 += s22 * Numbers.v666643; + s11 += s22 * Numbers.v470296; + s12 += s22 * Numbers.v654183; + s13 -= s22 * Numbers.v997805; + s14 += s22 * Numbers.v136657; + s15 -= s22 * Numbers.v683901; + s22 = Number.zero; + + s9 += s21 * Numbers.v666643; + s10 += s21 * Numbers.v470296; + s11 += s21 * Numbers.v654183; + s12 -= s21 * Numbers.v997805; + s13 += s21 * Numbers.v136657; + s14 -= s21 * Numbers.v683901; + s21 = Number.zero; + + s8 += s20 * Numbers.v666643; + s9 += s20 * Numbers.v470296; + s10 += s20 * Numbers.v654183; + s11 -= s20 * Numbers.v997805; + s12 += s20 * Numbers.v136657; + s13 -= s20 * Numbers.v683901; + s20 = Number.zero; + + s7 += s19 * Numbers.v666643; + s8 += s19 * Numbers.v470296; + s9 += s19 * Numbers.v654183; + s10 -= s19 * Numbers.v997805; + s11 += s19 * Numbers.v136657; + s12 -= s19 * Numbers.v683901; + s19 = Number.zero; + + s6 += s18 * Numbers.v666643; + s7 += s18 * Numbers.v470296; + s8 += s18 * Numbers.v654183; + s9 -= s18 * Numbers.v997805; + s10 += s18 * Numbers.v136657; + s11 -= s18 * Numbers.v683901; + s18 = Number.zero; + + var carry = List.filled(64, Number.zero); + + carry[6] = (s6 + (Number.one << 20)) >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[8] = (s8 + (Number.one << 20)) >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[10] = (s10 + (Number.one << 20)) >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + carry[12] = (s12 + (Number.one << 20)) >> 21; + s13 += carry[12]; + s12 -= carry[12] << 21; + carry[14] = (s14 + (Number.one << 20)) >> 21; + s15 += carry[14]; + s14 -= carry[14] << 21; + carry[16] = (s16 + (Number.one << 20)) >> 21; + s17 += carry[16]; + s16 -= carry[16] << 21; + + carry[7] = (s7 + (Number.one << 20)) >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[9] = (s9 + (Number.one << 20)) >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[11] = (s11 + (Number.one << 20)) >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + carry[13] = (s13 + (Number.one << 20)) >> 21; + s14 += carry[13]; + s13 -= carry[13] << 21; + carry[15] = (s15 + (Number.one << 20)) >> 21; + s16 += carry[15]; + s15 -= carry[15] << 21; + + s5 += s17 * Numbers.v666643; + s6 += s17 * Numbers.v470296; + s7 += s17 * Numbers.v654183; + s8 -= s17 * Numbers.v997805; + s9 += s17 * Numbers.v136657; + s10 -= s17 * Numbers.v683901; + s17 = Number.zero; + + s4 += s16 * Numbers.v666643; + s5 += s16 * Numbers.v470296; + s6 += s16 * Numbers.v654183; + s7 -= s16 * Numbers.v997805; + s8 += s16 * Numbers.v136657; + s9 -= s16 * Numbers.v683901; + s16 = Number.zero; + + s3 += s15 * Numbers.v666643; + s4 += s15 * Numbers.v470296; + s5 += s15 * Numbers.v654183; + s6 -= s15 * Numbers.v997805; + s7 += s15 * Numbers.v136657; + s8 -= s15 * Numbers.v683901; + s15 = Number.zero; + + s2 += s14 * Numbers.v666643; + s3 += s14 * Numbers.v470296; + s4 += s14 * Numbers.v654183; + s5 -= s14 * Numbers.v997805; + s6 += s14 * Numbers.v136657; + s7 -= s14 * Numbers.v683901; + s14 = Number.zero; + + s1 += s13 * Numbers.v666643; + s2 += s13 * Numbers.v470296; + s3 += s13 * Numbers.v654183; + s4 -= s13 * Numbers.v997805; + s5 += s13 * Numbers.v136657; + s6 -= s13 * Numbers.v683901; + s13 = Number.zero; + + s0 += s12 * Numbers.v666643; + s1 += s12 * Numbers.v470296; + s2 += s12 * Numbers.v654183; + s3 -= s12 * Numbers.v997805; + s4 += s12 * Numbers.v136657; + s5 -= s12 * Numbers.v683901; + s12 = Number.zero; + + carry[0] = (s0 + (Number.one << 20)) >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[2] = (s2 + (Number.one << 20)) >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[4] = (s4 + (Number.one << 20)) >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[6] = (s6 + (Number.one << 20)) >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[8] = (s8 + (Number.one << 20)) >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[10] = (s10 + (Number.one << 20)) >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + + carry[1] = (s1 + (Number.one << 20)) >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[3] = (s3 + (Number.one << 20)) >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[5] = (s5 + (Number.one << 20)) >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[7] = (s7 + (Number.one << 20)) >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[9] = (s9 + (Number.one << 20)) >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[11] = (s11 + (Number.one << 20)) >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + + s0 += s12 * Numbers.v666643; + s1 += s12 * Numbers.v470296; + s2 += s12 * Numbers.v654183; + s3 -= s12 * Numbers.v997805; + s4 += s12 * Numbers.v136657; + s5 -= s12 * Numbers.v683901; + s12 = Number.zero; + + carry[0] = s0 >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[1] = s1 >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[2] = s2 >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[3] = s3 >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[4] = s4 >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[5] = s5 >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[6] = s6 >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[7] = s7 >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[8] = s8 >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[9] = s9 >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[10] = s10 >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + carry[11] = s11 >> 21; + s12 += carry[11]; + s11 -= carry[11] << 21; + + s0 += s12 * Numbers.v666643; + s1 += s12 * Numbers.v470296; + s2 += s12 * Numbers.v654183; + s3 -= s12 * Numbers.v997805; + s4 += s12 * Numbers.v136657; + s5 -= s12 * Numbers.v683901; + s12 = Number.zero; + + carry[0] = s0 >> 21; + s1 += carry[0]; + s0 -= carry[0] << 21; + carry[1] = s1 >> 21; + s2 += carry[1]; + s1 -= carry[1] << 21; + carry[2] = s2 >> 21; + s3 += carry[2]; + s2 -= carry[2] << 21; + carry[3] = s3 >> 21; + s4 += carry[3]; + s3 -= carry[3] << 21; + carry[4] = s4 >> 21; + s5 += carry[4]; + s4 -= carry[4] << 21; + carry[5] = s5 >> 21; + s6 += carry[5]; + s5 -= carry[5] << 21; + carry[6] = s6 >> 21; + s7 += carry[6]; + s6 -= carry[6] << 21; + carry[7] = s7 >> 21; + s8 += carry[7]; + s7 -= carry[7] << 21; + carry[8] = s8 >> 21; + s9 += carry[8]; + s8 -= carry[8] << 21; + carry[9] = s9 >> 21; + s10 += carry[9]; + s9 -= carry[9] << 21; + carry[10] = s10 >> 21; + s11 += carry[10]; + s10 -= carry[10] << 21; + + out[0] = (s0 >> 0).intValue; + out[1] = (s0 >> 8).intValue; + out[2] = ((s0 >> 16) | (s1 << 5)).intValue; + out[3] = (s1 >> 3).intValue; + out[4] = (s1 >> 11).intValue; + out[5] = ((s1 >> 19) | (s2 << 2)).intValue; + out[6] = (s2 >> 6).intValue; + out[7] = ((s2 >> 14) | (s3 << 7)).intValue; + out[8] = (s3 >> 1).intValue; + out[9] = (s3 >> 9).intValue; + out[10] = ((s3 >> 17) | (s4 << 4)).intValue; + out[11] = (s4 >> 4).intValue; + out[12] = (s4 >> 12).intValue; + out[13] = ((s4 >> 20) | (s5 << 1)).intValue; + out[14] = (s5 >> 7).intValue; + out[15] = ((s5 >> 15) | (s6 << 6)).intValue; + out[16] = (s6 >> 2).intValue; + out[17] = (s6 >> 10).intValue; + out[18] = ((s6 >> 18) | (s7 << 3)).intValue; + out[19] = (s7 >> 5).intValue; + out[20] = (s7 >> 13).intValue; + out[21] = (s8 >> 0).intValue; + out[22] = (s8 >> 8).intValue; + out[23] = ((s8 >> 16) | (s9 << 5)).intValue; + out[24] = (s9 >> 3).intValue; + out[25] = (s9 >> 11).intValue; + out[26] = ((s9 >> 19) | (s10 << 2)).intValue; + out[27] = (s10 >> 6).intValue; + out[28] = ((s10 >> 14) | (s11 << 7)).intValue; + out[29] = (s11 >> 1).intValue; + out[30] = (s11 >> 9).intValue; + out[31] = (s11 >> 17).intValue; +} + +/// order is the order of Curve25519 in little-endian form. +var order = List.from( + [ + BigInt.parse('0x5812631a5cf5d3ed'), + BigInt.parse('0x14def9dea2f79cd6'), + BigInt.zero, + BigInt.parse('0x1000000000000000') + ], +); + +/// ScMinimal returns true if the given scalar is less than the order of the +/// curve. +bool ScMinimal(Uint8List scalar) { + for (var i = 3;; i--) { + // var v = binary.LittleEndian.Uint64(scalar[i*8:]); + var v = Uint64(scalar.sublist(i * 8, scalar.length)); + if (v > order[i].toInt()) { + return false; + } else if (v < order[i].toInt()) { + break; + } else if (i == 0) { + return false; + } + } + + return true; +} + +int Uint64(Uint8List b) { + return b[0] | + b[1] << 8 | + b[2] << 16 | + b[3] << 24 | + b[4] << 32 | + b[5] << 40 | + b[6] << 48 | + b[7] << 56; +} diff --git a/ed25519_edwards/lib/src/numbers.dart b/ed25519_edwards/lib/src/numbers.dart new file mode 100644 index 0000000..ba603f9 --- /dev/null +++ b/ed25519_edwards/lib/src/numbers.dart @@ -0,0 +1,18 @@ +import 'package:adaptive_number/adaptive_number.dart'; + +abstract class Numbers { + static Number v8 = Number(8); + static Number v15 = Number(15); + static Number v19 = Number(19); + static Number v24 = Number(24); + static Number v25 = Number(25); + static Number v26 = Number(26); + static Number v38 = Number(38); + static Number v136657 = Number(136657); + static Number v2097151 = Number(2097151); + static Number v470296 = Number(470296); + static Number v683901 = Number(683901); + static Number v654183 = Number(654183); + static Number v666643 = Number(666643); + static Number v997805 = Number(997805); +} diff --git a/ed25519_edwards/lib/src/util.dart b/ed25519_edwards/lib/src/util.dart new file mode 100644 index 0000000..301b952 --- /dev/null +++ b/ed25519_edwards/lib/src/util.dart @@ -0,0 +1,16 @@ +import 'dart:math'; + +import 'dart:typed_data'; + +void arrayCopy(List src, int srcPos, List dest, int destPos, int length) { + dest.setRange(destPos, length + destPos, src, srcPos); +} + +final _defaultSecureRandom = Random.secure(); + +void fillBytesWithSecureRandomNumbers(Uint8List bytes, {Random? random}) { + random ??= _defaultSecureRandom; + for (var i = 0; i < bytes.length; i++) { + bytes[i] = random.nextInt(256); + } +} diff --git a/ed25519_edwards/pubspec.yaml b/ed25519_edwards/pubspec.yaml new file mode 100644 index 0000000..90d2cea --- /dev/null +++ b/ed25519_edwards/pubspec.yaml @@ -0,0 +1,18 @@ +name: ed25519_edwards +description: Dart port of ed25519 from Go Cryptography ed25519 +version: 0.3.1 +homepage: https://github.com/Tougee/ed25519 + +environment: + sdk: '>=2.12.0 <3.0.0' + +dependencies: + collection: ^1.15.0 + crypto: ^3.0.0 + convert: ^3.0.0 + adaptive_number: ^1.0.0 +dev_dependencies: + pedantic: ^1.10.0 + test: ^1.16.4 + hex: ^0.2.0 + benchmark_harness: ^2.0.0 diff --git a/ed25519_edwards/test/benchmark/ed25519_benchmark.dart b/ed25519_edwards/test/benchmark/ed25519_benchmark.dart new file mode 100644 index 0000000..d1740af --- /dev/null +++ b/ed25519_edwards/test/benchmark/ed25519_benchmark.dart @@ -0,0 +1,38 @@ +import 'dart:typed_data'; + +import 'package:ed25519_edwards/ed25519_edwards.dart'; + +import 'rate_benchmark.dart'; + +class Ed25519Benchmark extends RateBenchmark { + Ed25519Benchmark(bool forSigning, [int dataLength = 1024 * 1024]) + : _forSigning = forSigning, + _data = Uint8List(dataLength), + super('Ed25519 - ${forSigning ? 'sign' : 'verify'}'); + + final Uint8List _data; + final bool _forSigning; + late final KeyPair _keyPair; + Uint8List? _signature; + + @override + void setup() { + _keyPair = generateKey(); + _signature = sign(_keyPair.privateKey, _data); + } + + @override + void run() { + if (_forSigning) { + sign(_keyPair.privateKey, _data); + } else if (_signature != null) { + verify(_keyPair.publicKey, _data, _signature!); + } + addSample(_data.length); + } +} + +void main() { + Ed25519Benchmark(true).report(); + Ed25519Benchmark(false).report(); +} diff --git a/ed25519_edwards/test/benchmark/rate_benchmark.dart b/ed25519_edwards/test/benchmark/rate_benchmark.dart new file mode 100644 index 0000000..aa63e50 --- /dev/null +++ b/ed25519_edwards/test/benchmark/rate_benchmark.dart @@ -0,0 +1,64 @@ +import 'package:benchmark_harness/benchmark_harness.dart'; + +abstract class RateBenchmark extends BenchmarkBase { + RateBenchmark(String name, {this.runLength = 5000}) + : super(name, emitter: RateEmitter()) { + (emitter as RateEmitter).benchmark = this; + } + + final int runLength; + int _totalData = 0; + int _iterations = 0; + + @override + ScoreEmitter get emitter => super.emitter; + + void addSample(int processedData) { + _totalData += processedData; + } + + @override + void exercise() { + _totalData = 0; + _iterations = 0; + + var watch = Stopwatch()..start(); + while (watch.elapsedMilliseconds < runLength) { + run(); + _iterations++; + } + } +} + +class RateEmitter implements ScoreEmitter { + late RateBenchmark benchmark; + + int get totalData => benchmark._totalData; + int get iterations => benchmark._iterations; + + @override + void emit(String testName, double value) { + final ms = value / 1000; + final s = ms / 1000; + final date = DateTime.now().toString().split('.')[0]; + + print('| $date | ' + '$testName | ' + '${_formatDataLength(totalData / s)}/s | ' + '$iterations iterations | ' + '${ms.toInt()} ms | ' + '${_formatDataLength(totalData)} |'); + } + + String _formatDataLength(num dataLen) { + if (dataLen < 1024) { + return '${dataLen.toStringAsFixed(2)} B'; + } else if (dataLen < (1024 * 1024)) { + return '${(dataLen / 1024).toStringAsFixed(2)} KB'; + } else if (dataLen < (1024 * 1024 * 1024)) { + return '${(dataLen / (1024 * 1024)).toStringAsFixed(2)} MB'; + } else { + return '${(dataLen / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB'; + } + } +} diff --git a/ed25519_edwards/test/ed25519_test.dart b/ed25519_edwards/test/ed25519_test.dart new file mode 100644 index 0000000..42bda1d --- /dev/null +++ b/ed25519_edwards/test/ed25519_test.dart @@ -0,0 +1,67 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:collection/collection.dart'; +import 'package:ed25519_edwards/ed25519_edwards.dart' as ed; +import 'package:hex/hex.dart'; +import 'package:test/test.dart'; + +void main() { + void testVector( + String plain, String seedStr, String publicStr, String sigStr) { + var seed = HEX.decode(seedStr); + var public = HEX.decode(publicStr); + var privateKey = ed.PrivateKey([...seed, ...public]); + var publicKey = ed.public(privateKey); + var message = HEX.decode(plain); + var sig = ed.sign(privateKey, message as Uint8List); + + var targetSig = HEX.decode(sigStr); + assert(ListEquality().equals(targetSig, sig)); + + var result = ed.verify(publicKey, message, sig); + assert(result == true); + } + + test('test rfc8032 cases', () { + testVector( + '', + '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', + 'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a', + 'e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b'); + testVector( + '72', + '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb', + '3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c', + '92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00'); + testVector( + 'af82', + 'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7', + 'fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025', + '6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a'); + testVector( + '08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0', + 'f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5', + '278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e', + '0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03'); + testVector( + 'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f', + '833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42', + 'ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf', + 'dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704'); + }); + + test('testSignVerify', () { + var keyPair = ed.generateKey(); + var privateKey = keyPair.privateKey; + var publicKey = keyPair.publicKey; + var message = utf8.encode('test message'); + var sig = ed.sign(privateKey, message as Uint8List); + var result = ed.verify(publicKey, message, sig); + assert(result == true); + + var wrongMessage = utf8.encode('wrong message'); + var wrongResult = ed.verify(publicKey, wrongMessage as Uint8List, sig); + assert(wrongResult == false); + }); +} diff --git a/hashlib/LICENSE b/hashlib/LICENSE new file mode 100644 index 0000000..f8437f8 --- /dev/null +++ b/hashlib/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2023, Sudipto Chandra +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/hashlib/lib/codecs.dart b/hashlib/lib/codecs.dart new file mode 100644 index 0000000..ea87732 --- /dev/null +++ b/hashlib/lib/codecs.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +/// Implementations of fast and error resilient codecs +library; + +export 'package:hashlib_codecs/hashlib_codecs.dart'; diff --git a/hashlib/lib/hashlib.dart b/hashlib/lib/hashlib.dart new file mode 100644 index 0000000..8b4c11a --- /dev/null +++ b/hashlib/lib/hashlib.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +/// Collection of hashing algorithms, checksum generators, message +/// authentication code (MAC) utilities and key derivation functions. +/// +/// This library serves as a convenience export so that all supported +/// algorithms can be used with a single import. +library; + +export 'src/hashlib.dart'; diff --git a/hashlib/lib/random.dart b/hashlib/lib/random.dart new file mode 100644 index 0000000..bf471ac --- /dev/null +++ b/hashlib/lib/random.dart @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +/// Implementation of secure random generators based on hashlib +library; + +export 'package:hashlib/src/random.dart'; +export 'package:hashlib/src/uuid.dart'; diff --git a/hashlib/lib/src/adler32.dart b/hashlib/lib/src/adler32.dart new file mode 100644 index 0000000..6eafe05 --- /dev/null +++ b/hashlib/lib/src/adler32.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/adler32.dart'; +import 'package:hashlib/src/core/hash_base.dart'; + +/// [Adler-32][wiki] is composed of two sums accumulated per byte. +/// +/// +/// According to [RFC-1950][rfc], the algorithm is described as follows: +/// - `a` is the sum of all bytes, `b` is the sum of all `a` values. +/// Both sums are done modulo `65521`. +/// - `a` is initialized to 1, `b` to 0. +/// - Final output is `b * 65536 + a` +/// +/// [rfc]: https://www.ietf.org/rfc/rfc1950.html +/// [wiki]: https://en.wikipedia.org/wiki/Adler-32 +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const HashBase adler32 = _Adler32(); + +class _Adler32 extends HashBase { + const _Adler32(); + + @override + final String name = 'ALDER-32'; + + @override + Adler32Hash createSink() => Adler32Hash(); +} + +/// Gets the Adler-32 value of a String +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +int adler32code(String input, [Encoding? encoding]) { + return adler32.string(input, encoding).number(); +} diff --git a/hashlib/lib/src/algorithms/adler32.dart b/hashlib/lib/src/algorithms/adler32.dart new file mode 100644 index 0000000..3c2f3ff --- /dev/null +++ b/hashlib/lib/src/algorithms/adler32.dart @@ -0,0 +1,46 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/hash_base.dart'; + +const int _adler32Mod = 65521; + +/// This implementation is derived from the [ ZLIB Compressed Data Format +/// Specification version 3.3 ][rfc] +/// +/// [rfc]: https://www.ietf.org/rfc/rfc1950.html +class Adler32Hash extends HashDigestSink { + int a = 1, b = 0; + + Adler32Hash(); + + @override + final int hashLength = 4; + + @override + void reset() { + a = 1; + b = 0; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++) { + a = (a + chunk[start]) % _adler32Mod; + b = (b + a) % _adler32Mod; + } + } + + @override + Uint8List $finalize() { + return Uint8List.fromList([ + b >>> 8, + b, + a >>> 8, + a, + ]); + } +} diff --git a/hashlib/lib/src/algorithms/argon2/argon2.dart b/hashlib/lib/src/algorithms/argon2/argon2.dart new file mode 100644 index 0000000..b95ef92 --- /dev/null +++ b/hashlib/lib/src/algorithms/argon2/argon2.dart @@ -0,0 +1,149 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/core/kdf_base.dart'; + +import 'argon2_64bit.dart' if (dart.library.js) 'argon2_32bit.dart'; +import 'common.dart'; +import 'security.dart'; + +export 'common.dart'; +export 'security.dart'; + +/// Creates a context for [Argon2][wiki] password hashing. +/// +/// Argon2 is a key derivation algorithm that was selected as the winner of the +/// 2015 [Password Hashing Contest][phc], and the best password hashing / key +/// derivation algorithm known to date. +/// +/// Example of password hashing using Argon2: +/// +/// ```dart +/// final salt = utf.encode("some salt") +/// final password = utf8.encode('password'); +/// final argon2 = Argon2( +/// version: Argon2Version.v13, +/// type: Argon2Type.argon2id, +/// hashLength: 32, +/// iterations: 2, +/// parallelism: 8, +/// memorySizeKB: 1 << 18, +/// salt: salt, +/// ); +/// final digest = argon2.encode(password); +/// ``` +/// +/// [phc]: https://www.password-hashing.net/ +/// [wiki]: https://en.wikipedia.org/wiki/Argon2 +class Argon2 extends KeyDerivatorBase { + final Argon2Context _ctx; + + @override + String get name => _ctx.type.name; + + /// Argon2 Hash Type + Argon2Type get type => _ctx.type; + + /// The current version is 0x13 (decimal: 19) + Argon2Version get version => _ctx.version; + + /// Degree of parallelism (i.e. number of threads) + int get parallelism => _ctx.lanes; + + /// Desired number of returned bytes + int get hashLength => _ctx.hashLength; + + /// Amount of memory (in kibibytes) to use + int get memorySizeKB => _ctx.memorySizeKB; + + /// Number of iterations to perform + int get iterations => _ctx.passes; + + /// Salt (16 bytes recommended for password hashing) + List get salt => _ctx.salt; + + /// Optional key + List? get key => _ctx.key; + + /// Optional arbitrary additional data + List? get personalization => _ctx.personalization; + + @override + int get derivedKeyLength => hashLength; + + /// Generate a derived key from a [password] using Argon2 algorithm + @override + Argon2HashDigest convert(List password) { + final result = Argon2Internal(_ctx).convert(password); + return Argon2HashDigest(_ctx, result); + } + + /// Generate an Argon2 encoded string from a [password] + String encode(List password) => convert(password).encoded(); + + const Argon2._(this._ctx); + + factory Argon2({ + Argon2Type type = Argon2Type.argon2id, + Argon2Version version = Argon2Version.v13, + required int parallelism, + required int memorySizeKB, + required int iterations, + int? hashLength, + List? salt, + List? key, + List? personalization, + }) { + var ctx = Argon2Context( + salt: salt, + version: version, + type: type, + hashLength: hashLength, + iterations: iterations, + parallelism: parallelism, + memorySizeKB: memorySizeKB, + key: key, + personalization: personalization, + ); + return Argon2._(ctx); + } + + /// Creates an [Argon2] instance from [Argon2Security] parameter. + factory Argon2.fromSecurity( + Argon2Security security, { + List? salt, + List? key, + int? hashLength, + List? personalization, + }) { + return Argon2( + salt: salt, + version: security.version, + type: security.type, + hashLength: hashLength, + iterations: security.t, + parallelism: security.p, + memorySizeKB: security.m, + key: key, + personalization: personalization, + ); + } + + /// Creates an [Argon2] instance from an encoded PHC-compliant string. + /// + /// The encoded string may look like this: + /// `$argon2i$v=19$m=16,t=2,p=1$c29tZSBzYWx0$u1eU6mZFG4/OOoTdAtM5SQ` + factory Argon2.fromEncoded( + CryptData data, { + List? key, + List? personalization, + }) { + var ctx = Argon2Context.fromEncoded( + data, + key: key, + personalization: personalization, + ); + return Argon2._(ctx); + } +} diff --git a/hashlib/lib/src/algorithms/argon2/argon2_32bit.dart b/hashlib/lib/src/algorithms/argon2/argon2_32bit.dart new file mode 100644 index 0000000..4a197b9 --- /dev/null +++ b/hashlib/lib/src/algorithms/argon2/argon2_32bit.dart @@ -0,0 +1,516 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'common.dart'; +import '../blake2/blake2b_32bit.dart'; + +const int _mask16 = 0xFFFF; +const int _mask32 = 0xFFFFFFFF; + +const int _zero = 0; +const int _input = _zero + 256; +const int _address = _input + 256; + +// slice 0 slice 1 slice 2 slice 3 +// ____/\____ ____/\____ ____/\____ ____/\____ +// / \ / \ / \ / \ +// +------------+------------+------------+------------+ +// | segment 0 | segment 1 | segment 2 | segment 3 | -> lane 0 +// +------------+------------+------------+-----------+ +// | segment 4 | segment 5 | segment 6 | segment 7 | -> lane 1 +// +------------+------------+------------+------------+ +// | segment 8 | segment 9 | segment 10 | segment 11 | -> lane 2 +// +------------+------------+------------+------------+ +// | ... ... ... | ... +// +------------+------------+------------+------------+ +// | | | | | -> lane p - 1 +// +------------+------------+------------+------------+ + +class Argon2Internal { + final Argon2Context ctx; + final _blockR = Uint32List(256); + final _blockT = Uint32List(256); + final _temp = Uint32List(_address + 256); + + Argon2Internal(this.ctx); + + Uint8List convert(List password) { + int i, j, k, p; + int pass, slice, lane; + var hash0 = Uint8List(64 + 8); + var hash0as32 = Uint32List.view(hash0.buffer); + var buffer32 = Uint32List(ctx.blocks << 8); + var buffer = Uint8List.view(buffer32.buffer); + var result = Uint8List(ctx.hashLength); + + // H_0 Generation (64 + 8 = 72 bytes) + _initialHash(hash0, password); + + // Initial block generation + // Lane Starting Blocks + k = 0; + hash0as32[16] = 0; + for (i = 0; i < ctx.lanes; i++, k += ctx.columns) { + // B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) + hash0as32[17] = i; + _expandHash(1024, hash0, buffer, k << 10); + } + + // Second Lane Blocks + k = 1; + hash0as32[16] = 1; + for (i = 0; i < ctx.lanes; i++, k += ctx.columns) { + // B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) + hash0as32[17] = i; + _expandHash(1024, hash0, buffer, k << 10); + } + + // Further block generation + for (pass = 0; pass < ctx.passes; ++pass) { + for (slice = 0; slice < ctx.slices; ++slice) { + for (lane = 0; lane < ctx.lanes; ++lane) { + _fillSegment(buffer32, pass, slice, lane); + } + } + } + + // Finalization + /* XOR the blocks */ + j = ctx.columns - 1; + var block = Uint8List.view(buffer.buffer, j << 10, 1024); + for (k = 1; k < ctx.lanes; ++k) { + j += ctx.columns; + p = j << 10; + for (i = 0; i < 1024; ++i, ++p) { + block[i] ^= buffer[p]; + } + } + + /* Hash the result */ + _expandHash(ctx.hashLength, block, result, 0); + return result; + } + + void _initialHash(Uint8List hash0, List password) { + // H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) || + // LE32(v) || LE32(y) || LE32(length(P)) || P || + // LE32(length(S)) || S || LE32(length(K)) || K || + // LE32(length(X)) || X) + var blake2b = Blake2bHash(64); + blake2b.addUint32(ctx.lanes); + blake2b.addUint32(ctx.hashLength); + blake2b.addUint32(ctx.memorySizeKB); + blake2b.addUint32(ctx.passes); + blake2b.addUint32(ctx.version.value); + blake2b.addUint32(ctx.type.index); + blake2b.addUint32(password.length); + blake2b.add(password); + blake2b.addUint32(ctx.salt.length); + blake2b.add(ctx.salt); + blake2b.addUint32(ctx.key?.length ?? 0); + if (ctx.key != null) { + blake2b.add(ctx.key!); + } + blake2b.addUint32(ctx.personalization?.length ?? 0); + if (ctx.personalization != null) { + blake2b.add(ctx.personalization!); + } + + var hash = blake2b.digest().bytes; + for (int i = 0; i < 64; ++i) { + hash0[i] = hash[i]; + } + } + + static void _expandHash( + int digestSize, + Uint8List message, + Uint8List output, + int offset, + ) { + int i, j; + + // Take smaller hash unchanged + if (digestSize <= 64) { + var blake2b = Blake2bHash(digestSize); + blake2b.addUint32(digestSize); + blake2b.add(message); + var hash = blake2b.digest().bytes; + for (i = 0; i < digestSize; ++i, offset++) { + output[offset] = hash[i]; + } + return; + } + + // Otherwise, expand to digestSize by repeatedly hashing + // and taking the first 32-bytes from the each hash + + var blake2b = Blake2bHash(64); + blake2b.addUint32(digestSize); + blake2b.add(message); + var hash = blake2b.digest().bytes; + + // first block + for (i = 0; i < 32; ++i, ++offset) { + output[offset] = hash[i]; + } + + // subsequent blocks + for (j = digestSize - 32; j > 64; j -= 32) { + blake2b.reset(); + blake2b.add(hash); + hash = blake2b.digest().bytes; + for (i = 0; i < 32; ++i, ++offset) { + output[offset] = hash[i]; + } + } + + // final block + blake2b.reset(); + blake2b.add(hash); + hash = blake2b.digest().bytes; + for (i = 0; i < j; ++i, ++offset) { + output[offset] = hash[i]; + } + } + + void _fillSegment(Uint32List buffer, int pass, int slice, int lane) { + int refLane, refIndex; // l, z + int previous, current; + int i, j, startIndex, rand0, rand1; + + bool dataIndependentAddressing = (ctx.type == Argon2Type.argon2i); + if (ctx.type == Argon2Type.argon2id) { + dataIndependentAddressing = (pass == 0) && (slice < ctx.midSlice); + } + + if (dataIndependentAddressing) { + _temp[_input + 0] = pass; + _temp[_input + 1] = 0; + _temp[_input + 2] = lane; + _temp[_input + 3] = 0; + _temp[_input + 4] = slice; + _temp[_input + 5] = 0; + _temp[_input + 6] = ctx.blocks; + _temp[_input + 7] = ctx.blocks >>> 32; + _temp[_input + 8] = ctx.passes; + _temp[_input + 9] = 0; + _temp[_input + 10] = ctx.type.index; + _temp[_input + 11] = 0; + _temp[_input + 12] = 0; + _temp[_input + 13] = 0; + } + + startIndex = 0; + if (pass == 0 && slice == 0) { + startIndex = 2; + if (dataIndependentAddressing) { + _increment(_temp, _input + 12); + _fillBlock(_temp, prev: _zero, ref: _input, next: _address); + _fillBlock(_temp, prev: _zero, ref: _address, next: _address); + } + } + + /* Offset of the current block */ + current = lane * ctx.columns + slice * ctx.segments + startIndex; + + if (current % ctx.columns == 0) { + /* Last block in this lane */ + previous = current + ctx.columns - 1; + } else { + /* Previous block */ + previous = current - 1; + } + + for (i = startIndex; i < ctx.segments; ++i, ++current, ++previous) { + /* 1.1 Rotating prev_offset if needed */ + if (current % ctx.columns == 1) { + previous = current - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (dataIndependentAddressing) { + j = i & 0x7F; + if (j == 0) { + _increment(_temp, _input + 12); + _fillBlock(_temp, prev: _zero, ref: _input, next: _address); + _fillBlock(_temp, prev: _zero, ref: _address, next: _address); + } + rand0 = _temp[_address + (j << 1)]; + rand1 = _temp[_address + (j << 1) + 1]; + } else { + rand0 = buffer[previous << 8]; + rand1 = buffer[(previous << 8) + 1]; + } + + /* 1.2.2 Computing the lane of the reference block */ + refLane = rand1 % ctx.lanes; + + if (pass == 0 && slice == 0) { + /* Can not reference other lanes yet */ + refLane = lane; + } + + /* 1.2.3 Computing the number of possible reference block within the lane */ + refIndex = _alphaIndex( + pass: pass, + slice: slice, + lane: lane, + index: i, + random: rand0, + sameLane: refLane == lane, + ); + + /* 2 Creating a new block */ + _fillBlock( + buffer, + next: current << 8, + prev: previous << 8, + ref: (refLane * ctx.columns + refIndex) << 8, + /* 1.2.1 v10 and earlier: overwrite, not XOR */ + xor: ctx.version != Argon2Version.v10 && pass > 0, + ); + } + } + + // B[next] ^= G(B[prev], B[ref]) + /// Fills a new memory block and optionally XORs the old block over the new one. + void _fillBlock( + Uint32List buffer, { + required int prev, + required int ref, + required int next, + bool xor = false, + }) { + int i, j; + + // T = R = ref ^ prev + for (i = 0; i < 256; ++i) { + _blockT[i] = _blockR[i] = buffer[ref + i] ^ buffer[prev + i]; + } + + if (xor) { + // T = ref ^ prev ^ next + for (i = 0; i < 256; ++i) { + _blockT[i] ^= buffer[next + i]; + } + } + + // Apply Blake2 on columns of 64-bit words: (0,1,...,15), + // then (16,17,..31)... finally (112,113,...127) + for (i = j = 0; i < 8; i++, j += 16) { + _blake2bMixer( + _blockR, + (j) << 1, + (j + 1) << 1, + (j + 2) << 1, + (j + 3) << 1, + (j + 4) << 1, + (j + 5) << 1, + (j + 6) << 1, + (j + 7) << 1, + (j + 8) << 1, + (j + 9) << 1, + (j + 10) << 1, + (j + 11) << 1, + (j + 12) << 1, + (j + 13) << 1, + (j + 14) << 1, + (j + 15) << 1, + ); + } + + // Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), + // then (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) + for (i = j = 0; i < 8; i++, j += 2) { + _blake2bMixer( + _blockR, + (j) << 1, + (j + 1) << 1, + (j + 16) << 1, + (j + 17) << 1, + (j + 32) << 1, + (j + 33) << 1, + (j + 48) << 1, + (j + 49) << 1, + (j + 64) << 1, + (j + 65) << 1, + (j + 80) << 1, + (j + 81) << 1, + (j + 96) << 1, + (j + 97) << 1, + (j + 112) << 1, + (j + 113) << 1, + ); + } + + // next = T ^ R + for (i = 0; i < 256; ++i) { + buffer[next + i] = _blockT[i] ^ _blockR[i]; + } + } + + int _alphaIndex({ + required int pass, + required int slice, + required int lane, + required int index, + required int random, + required bool sameLane, + }) { + int area, pos, start; + + if (pass == 0) { + // First pass + if (slice == 0) { + // First slice + area = index - 1; // all but the previous + } else if (sameLane) { + // The same lane => add current segment + area = slice * ctx.segments + index - 1; + } else { + area = slice * ctx.segments + (index == 0 ? -1 : 0); + } + } else { + // Other passes + if (sameLane) { + area = ctx.columns - ctx.segments + index - 1; + } else { + area = ctx.columns - ctx.segments + (index == 0 ? -1 : 0); + } + } + + // 1.2.4. Mapping pseudo_rand to 0.. + // and produce relative position + pos = _multiplyAndGetMSB(random, random); + pos = area - 1 - _multiplyAndGetMSB(area, pos); + + /* 1.2.5 Computing starting position */ + start = 0; + if (pass != 0 && slice != ctx.slices - 1) { + start = (slice + 1) * ctx.segments; + } + + /* 1.2.6. Computing absolute position */ + return (start + pos) % ctx.columns; + } + + /// `v[i]++` + static void _increment(Uint32List v, int i) { + if (v[i] == _mask32) { + v[i] = 0; + v[i + 1]++; + } else { + v[i]++; + } + } + + /// `((x * y) mod 2^64) >> 32` + static int _multiplyAndGetMSB(int x, int y) { + int lx, hx, ly, hy; + + hx = (x >>> 16) & _mask16; + lx = x & _mask16; + hy = (y >>> 16) & _mask16; + ly = y & _mask16; + + return ((hy * hx) + ((lx * hy + hx * ly) >>> 16)) & _mask32; + } + + /// `v[x] += v[y] + 2 * ((v[x] & _mask32) * (v[y] & _mask32))` + static void _fBlaMka(Uint32List v, int x, int y) { + var t = (BigInt.from(v[x]) * BigInt.from(v[y])) << 1; + t += (BigInt.from(v[x + 1]) << 32) + BigInt.from(v[x]); + t += (BigInt.from(v[y + 1]) << 32) + BigInt.from(v[y]); + + v[x] = t.toUnsigned(32).toInt(); + v[x + 1] = (t >> 32).toUnsigned(32).toInt(); + } + + // v[k] = (v[i] << (64 - n)) | (v[i] >>> n) + static void _rotr(int n, List v, int i, int k) { + var a = v[i + 1]; + var b = v[i]; + if (n == 32) { + v[k + 1] = b; + v[k] = a; + } else if (n < 32) { + v[k + 1] = (b << (32 - n)) | (a >>> n); + v[k] = (a << (32 - n)) | (b >>> n); + } else { + v[k + 1] = (a << (64 - n)) | (b >>> (n - 32)); + v[k] = (b << (64 - n)) | (a >>> (n - 32)); + } + } + + /// `v[k] = v[i] ^ v[j]` + static void _xor(List v, int i, int j, int k) { + v[k] = v[i] ^ v[j]; + v[k + 1] = v[i + 1] ^ v[j + 1]; + } + + static void _mix(Uint32List v, int a, int b, int c, int d) { + _fBlaMka(v, a, b); + // v[d] = _rotr(v[d] ^ v[a], 32); + _xor(v, d, a, d); + _rotr(32, v, d, d); + + _fBlaMka(v, c, d); + // v[b] = _rotr(v[b] ^ v[c], 24); + _xor(v, b, c, b); + _rotr(24, v, b, b); + + _fBlaMka(v, a, b); + // v[d] = _rotr(v[d] ^ v[a], 16); + _xor(v, d, a, d); + _rotr(16, v, d, d); + + _fBlaMka(v, c, d); + // v[b] = _rotr(v[b] ^ v[c], 63); + _xor(v, b, c, b); + _rotr(63, v, b, b); + } + + static void _blake2bMixer( + Uint32List v, + int v0, + int v1, + int v2, + int v3, + int v4, + int v5, + int v6, + int v7, + int v8, + int v9, + int v10, + int v11, + int v12, + int v13, + int v14, + int v15, + ) { + _mix(v, v0, v4, v8, v12); + _mix(v, v1, v5, v9, v13); + _mix(v, v2, v6, v10, v14); + _mix(v, v3, v7, v11, v15); + _mix(v, v0, v5, v10, v15); + _mix(v, v1, v6, v11, v12); + _mix(v, v2, v7, v8, v13); + _mix(v, v3, v4, v9, v14); + } +} + +extension on Blake2bHash { + void addUint32(int value) { + add([ + value, + value >>> 8, + value >>> 16, + value >>> 24, + ]); + } +} diff --git a/hashlib/lib/src/algorithms/argon2/argon2_64bit.dart b/hashlib/lib/src/algorithms/argon2/argon2_64bit.dart new file mode 100644 index 0000000..697f43f --- /dev/null +++ b/hashlib/lib/src/algorithms/argon2/argon2_64bit.dart @@ -0,0 +1,591 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'common.dart'; +import '../blake2/blake2b_64bit.dart'; + +const int _mask32 = 0xFFFFFFFF; + +// slice 0 slice 1 slice 2 slice 3 +// ____/\____ ____/\____ ____/\____ ____/\____ +// / \ / \ / \ / \ +// +------------+------------+------------+------------+ +// | segment 0 | segment 1 | segment 2 | segment 3 | -> lane 0 +// +------------+------------+------------+-----------+ +// | segment 4 | segment 5 | segment 6 | segment 7 | -> lane 1 +// +------------+------------+------------+------------+ +// | segment 8 | segment 9 | segment 10 | segment 11 | -> lane 2 +// +------------+------------+------------+------------+ +// | ... ... ... | ... +// +------------+------------+------------+------------+ +// | | | | | -> lane p - 1 +// +------------+------------+------------+------------+ + +class Argon2Internal { + final Argon2Context ctx; + final _hash0 = Uint8List(64 + 8); + final _blockR = Uint64List(128); + final _blockT = Uint64List(128); + final _input = Uint64List(128); + final _address = Uint64List(128); + + late final _digest = Uint8List(ctx.hashLength); + late final _memory = Uint64List(ctx.blocks << 7); + + Argon2Internal(this.ctx); + + Uint8List convert(List password) { + int i, j, k, cols; + int pass, slice, lane; + var hash0_32 = Uint32List.view(_hash0.buffer); + var memoryBytes = Uint8List.view(_memory.buffer); + + // H_0 Generation (64 + 8 = 72 bytes) + _initialHash(_hash0, password); + + // Initial block generation: First Lane Blocks + k = 0; + hash0_32[16] = 0; + cols = ctx.columns << 10; + for (i = 0; i < ctx.lanes; i++, k += cols) { + // B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) + hash0_32[17] = i; + _expandHash(1024, _hash0, memoryBytes, k); + } + + // Initial block generation: Second Lane Blocks + k = 1024; + hash0_32[16] = 1; + for (i = 0; i < ctx.lanes; i++, k += cols) { + // B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) + hash0_32[17] = i; + _expandHash(1024, _hash0, memoryBytes, k); + } + + // Further block generation + for (pass = 0; pass < ctx.passes; ++pass) { + for (slice = 0; slice < ctx.slices; ++slice) { + for (lane = 0; lane < ctx.lanes; ++lane) { + _fillSegment(pass, slice, lane); + } + } + } + + // Finalization : XOR the last column blocks + j = cols - 1024; + var block = Uint8List.view(memoryBytes.buffer, j, 1024); + for (k = 1; k < ctx.lanes; ++k) { + j += cols; + for (i = 0; i < 1024; ++i) { + block[i] ^= memoryBytes[j + i]; + } + } + + // Extend the block to make final result + _expandHash(ctx.hashLength, block, _digest, 0); + return _digest; + } + + void _initialHash(Uint8List hash0, List password) { + // H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) || + // LE32(v) || LE32(y) || LE32(length(P)) || P || + // LE32(length(S)) || S || LE32(length(K)) || K || + // LE32(length(X)) || X) + var blake2b = Blake2bHash(64); + blake2b.addUint32(ctx.lanes); + blake2b.addUint32(ctx.hashLength); + blake2b.addUint32(ctx.memorySizeKB); + blake2b.addUint32(ctx.passes); + blake2b.addUint32(ctx.version.value); + blake2b.addUint32(ctx.type.index); + blake2b.addUint32(password.length); + blake2b.add(password); + blake2b.addUint32(ctx.salt.length); + blake2b.add(ctx.salt); + blake2b.addUint32(ctx.key?.length ?? 0); + if (ctx.key != null) { + blake2b.add(ctx.key!); + } + blake2b.addUint32(ctx.personalization?.length ?? 0); + if (ctx.personalization != null) { + blake2b.add(ctx.personalization!); + } + + var hash = blake2b.digest().bytes; + for (int i = 0; i < 64; ++i) { + hash0[i] = hash[i]; + } + } + + static void _expandHash( + int digestSize, + Uint8List message, + Uint8List output, + int offset, + ) { + int i, j; + + // Take smaller hash unchanged + if (digestSize <= 64) { + var blake2b = Blake2bHash(digestSize); + blake2b.addUint32(digestSize); + blake2b.add(message); + var hash = blake2b.digest().bytes; + for (i = 0; i < digestSize; ++i, offset++) { + output[offset] = hash[i]; + } + return; + } + + // Otherwise, expand to digestSize by repeatedly hashing + // and taking the first 32-bytes from the each hash + + var blake2b = Blake2bHash(64); + blake2b.addUint32(digestSize); + blake2b.add(message); + var hash = blake2b.digest().bytes; + + // first block + for (i = 0; i < 32; ++i, ++offset) { + output[offset] = hash[i]; + } + + // subsequent blocks + for (j = digestSize - 32; j > 64; j -= 32) { + blake2b.reset(); + blake2b.add(hash); + hash = blake2b.digest().bytes; + for (i = 0; i < 32; ++i, ++offset) { + output[offset] = hash[i]; + } + } + + // final block + blake2b.reset(); + blake2b.add(hash); + hash = blake2b.digest().bytes; + for (i = 0; i < j; ++i, ++offset) { + output[offset] = hash[i]; + } + } + + void _fillSegment(int pass, int slice, int lane) { + int refLane, refIndex; // l, z + int previous, current; + int i, startIndex, random; + + bool xor = ctx.version != Argon2Version.v10 && pass > 0; + bool useAddress = (ctx.type == Argon2Type.argon2i); + if (ctx.type == Argon2Type.argon2id) { + useAddress = (pass == 0) && (slice < ctx.midSlice); + } + + if (useAddress) { + _input[0] = pass; + _input[1] = lane; + _input[2] = slice; + _input[3] = ctx.blocks; + _input[4] = ctx.passes; + _input[5] = ctx.type.index; + _input[6] = 0; + } + + startIndex = 0; + if (pass == 0 && slice == 0) { + startIndex = 2; + if (useAddress) { + _input[6]++; + _nextAddress(_input, _address); + } + } + + /* Offset of the current block */ + current = lane * ctx.columns + slice * ctx.segments + startIndex; + + for (i = startIndex; i < ctx.segments; ++i, ++current) { + if (current % ctx.columns == 0) { + /* Last block in this lane */ + previous = current + ctx.columns - 1; + } else { + /* Previous block */ + previous = current - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (useAddress) { + if (i & 0x7F == 0) { + _input[6]++; + _nextAddress(_input, _address); + } + random = _address[i & 0x7F]; + } else { + random = _memory[previous << 7]; + } + + /* 1.2.2 Computing the lane of the reference block */ + refLane = (random >>> 32) % ctx.lanes; + + if (pass == 0 && slice == 0) { + /* Can not reference other lanes yet */ + refLane = lane; + } + + /* 1.2.3 Computing the number of possible reference block within the lane */ + refIndex = _alphaIndex( + random: random & _mask32, + index: i, + slice: slice, + lane: lane, + pass: pass, + sameLane: refLane == lane, + ); + + /* 2 Creating a new block */ + _fillBlock( + _memory, + xor: xor, + next: current << 7, + prev: previous << 7, + ref: (refLane * ctx.columns + refIndex) << 7, + ); + } + } + + int _alphaIndex({ + required int pass, + required int slice, + required int lane, + required int index, + required int random, + required bool sameLane, + }) { + int area, pos, start; + + if (pass == 0) { + // First pass + if (slice == 0) { + // First slice + area = index - 1; // all but the previous + } else if (sameLane) { + // The same lane => add current segment + area = slice * ctx.segments + index - 1; + } else if (index == 0) { + area = slice * ctx.segments - 1; + } else { + area = slice * ctx.segments; + } + } else { + // Other passes + if (sameLane) { + area = ctx.columns - ctx.segments + index - 1; + } else if (index == 0) { + area = ctx.columns - ctx.segments - 1; + } else { + area = ctx.columns - ctx.segments; + } + } + + // 1.2.4. Mapping pseudo_rand to 0.. + // and produce relative position + pos = (random * random) >>> 32; + pos = area - 1 - ((area * pos) >>> 32); + + /* 1.2.5 Computing starting position */ + start = 0; + if (pass != 0 && slice != ctx.slices - 1) { + start = (slice + 1) * ctx.segments; + } + + /* 1.2.6. Computing absolute position */ + return (start + pos) % ctx.columns; + } + + /// Fills a memory block and optionally XORs the old block over it. + void _nextAddress(Uint64List input, Uint64List address) { + for (int i = 0; i < 128; ++i) { + _blockR[i] = address[i] = input[i]; + } + + for (int k = 0; k < 2; ++k) { + // Apply Blake2 on columns of 64-bit words: (0,1,...,15), + // then (16,17,..31)... finally (112,113,...127) + for (int j = 0; j < 128; j += 16) { + _blake2bMixer( + _blockR, + j, + j + 1, + j + 2, + j + 3, + j + 4, + j + 5, + j + 6, + j + 7, + j + 8, + j + 9, + j + 10, + j + 11, + j + 12, + j + 13, + j + 14, + j + 15, + ); + } + + // Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), + // then (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) + for (int j = 0; j < 16; j += 2) { + _blake2bMixer( + _blockR, + j, + j + 1, + j + 16, + j + 17, + j + 32, + j + 33, + j + 48, + j + 49, + j + 64, + j + 65, + j + 80, + j + 81, + j + 96, + j + 97, + j + 112, + j + 113, + ); + } + + for (int i = 0; i < 128; ++i) { + address[i] = _blockR[i] ^= address[i]; + } + } + } + + /// Fills a memory block and optionally XORs the old block over it. + void _fillBlock( + Uint64List memory, { + required int prev, + required int ref, + required int next, + bool xor = false, + }) { + // R = ref ^ prev + for (int i = 0; i < 128; ++i) { + _blockT[i] = _blockR[i] = memory[ref + i] ^ memory[prev + i]; + } + + if (xor) { + // T ^= next + for (int i = 0; i < 128; ++i) { + _blockT[i] ^= memory[next + i]; + } + } + + // Apply Blake2 on columns of 64-bit words: (0,1,...,15), + // then (16,17,..31)... finally (112,113,...127) + for (int j = 0; j < 128; j += 16) { + _blake2bMixer( + _blockR, + j, + j + 1, + j + 2, + j + 3, + j + 4, + j + 5, + j + 6, + j + 7, + j + 8, + j + 9, + j + 10, + j + 11, + j + 12, + j + 13, + j + 14, + j + 15, + ); + } + + // Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), + // then (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) + for (int j = 0; j < 16; j += 2) { + _blake2bMixer( + _blockR, + j, + j + 1, + j + 16, + j + 17, + j + 32, + j + 33, + j + 48, + j + 49, + j + 64, + j + 65, + j + 80, + j + 81, + j + 96, + j + 97, + j + 112, + j + 113, + ); + } + + // next = T ^ R + for (int i = 0; i < 128; ++i) { + memory[next + i] = _blockR[i] ^ _blockT[i]; + } + } + + @pragma('vm:prefer-inline') + static int _mul32(int a, int b) => (a & _mask32) * (b & _mask32); + + @pragma('vm:prefer-inline') + static int _rotr(int x, int n) => (x >>> n) ^ (x << (64 - n)); + + static void _blake2bMixer( + Uint64List v, + int i0, + int i1, + int i2, + int i3, + int i4, + int i5, + int i6, + int i7, + int i8, + int i9, + int i10, + int i11, + int i12, + int i13, + int i14, + int i15, + ) { + int v0 = v[i0]; + int v1 = v[i1]; + int v2 = v[i2]; + int v3 = v[i3]; + int v4 = v[i4]; + int v5 = v[i5]; + int v6 = v[i6]; + int v7 = v[i7]; + int v8 = v[i8]; + int v9 = v[i9]; + int v10 = v[i10]; + int v11 = v[i11]; + int v12 = v[i12]; + int v13 = v[i13]; + int v14 = v[i14]; + int v15 = v[i15]; + + // _mix(v, v0, v4, v8, v12); + v0 += v4 + (_mul32(v0, v4) << 1); + v12 = _rotr(v12 ^ v0, 32); + v8 += v12 + (_mul32(v8, v12) << 1); + v4 = _rotr(v4 ^ v8, 24); + v0 += v4 + (_mul32(v0, v4) << 1); + v12 = _rotr(v12 ^ v0, 16); + v8 += v12 + (_mul32(v8, v12) << 1); + v4 = _rotr(v4 ^ v8, 63); + + // _mix(v, v1, v5, v9, v13); + v1 += v5 + (_mul32(v1, v5) << 1); + v13 = _rotr(v13 ^ v1, 32); + v9 += v13 + (_mul32(v9, v13) << 1); + v5 = _rotr(v5 ^ v9, 24); + v1 += v5 + (_mul32(v1, v5) << 1); + v13 = _rotr(v13 ^ v1, 16); + v9 += v13 + (_mul32(v9, v13) << 1); + v5 = _rotr(v5 ^ v9, 63); + + // _mix(v, v2, v6, v10, v14); + v2 += v6 + (_mul32(v2, v6) << 1); + v14 = _rotr(v14 ^ v2, 32); + v10 += v14 + (_mul32(v10, v14) << 1); + v6 = _rotr(v6 ^ v10, 24); + v2 += v6 + (_mul32(v2, v6) << 1); + v14 = _rotr(v14 ^ v2, 16); + v10 += v14 + (_mul32(v10, v14) << 1); + v6 = _rotr(v6 ^ v10, 63); + + // _mix(v, v3, v7, v11, v15); + v3 += v7 + (_mul32(v3, v7) << 1); + v15 = _rotr(v15 ^ v3, 32); + v11 += v15 + (_mul32(v11, v15) << 1); + v7 = _rotr(v7 ^ v11, 24); + v3 += v7 + (_mul32(v3, v7) << 1); + v15 = _rotr(v15 ^ v3, 16); + v11 += v15 + (_mul32(v11, v15) << 1); + v7 = _rotr(v7 ^ v11, 63); + + // _mix(v, v0, v5, v10, v15); + v0 += v5 + (_mul32(v0, v5) << 1); + v15 = _rotr(v15 ^ v0, 32); + v10 += v15 + (_mul32(v10, v15) << 1); + v5 = _rotr(v5 ^ v10, 24); + v0 += v5 + (_mul32(v0, v5) << 1); + v15 = _rotr(v15 ^ v0, 16); + v10 += v15 + (_mul32(v10, v15) << 1); + v5 = _rotr(v5 ^ v10, 63); + + // _mix(v, v1, v6, v11, v12); + v1 += v6 + (_mul32(v1, v6) << 1); + v12 = _rotr(v12 ^ v1, 32); + v11 += v12 + (_mul32(v11, v12) << 1); + v6 = _rotr(v6 ^ v11, 24); + v1 += v6 + (_mul32(v1, v6) << 1); + v12 = _rotr(v12 ^ v1, 16); + v11 += v12 + (_mul32(v11, v12) << 1); + v6 = _rotr(v6 ^ v11, 63); + + // _mix(v, v2, v7, v8, v13); + v2 += v7 + (_mul32(v2, v7) << 1); + v13 = _rotr(v13 ^ v2, 32); + v8 += v13 + (_mul32(v8, v13) << 1); + v7 = _rotr(v7 ^ v8, 24); + v2 += v7 + (_mul32(v2, v7) << 1); + v13 = _rotr(v13 ^ v2, 16); + v8 += v13 + (_mul32(v8, v13) << 1); + v7 = _rotr(v7 ^ v8, 63); + + // _mix(v, v3, v4, v9, v14); + v3 += v4 + (_mul32(v3, v4) << 1); + v14 = _rotr(v14 ^ v3, 32); + v9 += v14 + (_mul32(v9, v14) << 1); + v4 = _rotr(v4 ^ v9, 24); + v3 += v4 + (_mul32(v3, v4) << 1); + v14 = _rotr(v14 ^ v3, 16); + v9 += v14 + (_mul32(v9, v14) << 1); + v4 = _rotr(v4 ^ v9, 63); + + v[i0] = v0; + v[i1] = v1; + v[i2] = v2; + v[i3] = v3; + v[i4] = v4; + v[i5] = v5; + v[i6] = v6; + v[i7] = v7; + v[i8] = v8; + v[i9] = v9; + v[i10] = v10; + v[i11] = v11; + v[i12] = v12; + v[i13] = v13; + v[i14] = v14; + v[i15] = v15; + } +} + +extension on Blake2bHash { + void addUint32(int value) { + add([ + value, + value >>> 8, + value >>> 16, + value >>> 24, + ]); + } +} diff --git a/hashlib/lib/src/algorithms/argon2/common.dart b/hashlib/lib/src/algorithms/argon2/common.dart new file mode 100644 index 0000000..8b60c06 --- /dev/null +++ b/hashlib/lib/src/algorithms/argon2/common.dart @@ -0,0 +1,298 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/core/hash_digest.dart'; +import 'package:hashlib/src/random.dart'; + +const int _slices = 4; +const int _minParallelism = 1; +const int _maxParallelism = 0x7FFF; +const int _minDigestSize = 4; +const int _maxDigestSize = 0x3FFFFFF; +const int _minIterations = 1; +const int _maxIterations = 0x3FFFFFF; +const int _maxMemory = 0x3FFFFFF; +const int _minSaltSize = 8; +const int _maxSaltSize = 0x3FFFFFF; +const int _minKeySize = 1; +const int _maxKeySize = 0x3FFFFFF; +const int _minAD = 1; +const int _maxAD = 0x3FFFFFF; +const int _defaultHashLength = 32; + +/// The Argon2 types +enum Argon2Type { + argon2d._('argon2d'), + argon2i._('argon2i'), + argon2id._('argon2id'); + + /// Name of this type + final String name; + + const Argon2Type._(this.name); + + /// Gets the type from string name + static Argon2Type fromName(String name) { + switch (name) { + case 'argon2d': + return Argon2Type.argon2d; + case 'argon2i': + return Argon2Type.argon2i; + case 'argon2id': + return Argon2Type.argon2id; + default: + throw ArgumentError('Unknown type'); + } + } +} + +/// The Argon2 versions +enum Argon2Version { + v10._(0x10), + v13._(0x13); + + /// The version value + final int value; + + const Argon2Version._(this.value); + + /// Gets the version from integer value + static Argon2Version fromValue(int value) { + switch (value) { + case 0x10: + return Argon2Version.v10; + case 0x13: + return Argon2Version.v13; + default: + throw ArgumentError('Unknown version'); + } + } +} + +/// The HashDigest for Argon2 with [Argon2Context] +class Argon2HashDigest extends HashDigest { + final Argon2Context ctx; + + const Argon2HashDigest(this.ctx, super.bytes); + + @override + String toString() => encoded(); + + /// Gets the PHC-compliant string for this [Argon2HashDigest] + String encoded() => ctx.toEncoded(bytes); +} + +/// The configuration used by the **Argon2** algorithm +class Argon2Context { + /// Argon2 Hash Type + final Argon2Type type; + + /// The current version is 0x13 (decimal: 19) + final Argon2Version version; + + /// Degree of parallelism (i.e. number of threads) + final int lanes; + + /// Desired number of returned bytes + final int hashLength; + + /// Amount of memory (in kibibytes) to use + final int memorySizeKB; + + /// Number of iterations to perform + final int passes; + + /// Salt (16 bytes recommended for password hashing) + final List salt; + + /// Optional key + final List? key; + + /// Optional arbitrary additional data + final List? personalization; + + /// Number of slices per column + final int slices; + + /// The start index of the second half of the slices + final int midSlice; + + /// Number of segments per lane + final int segments; + + /// Total number of columns per lane + final int columns; + + /// Total number of memory blocks (1024 bytes each) + final int blocks; + + const Argon2Context._({ + required this.salt, + required this.version, + required this.type, + required this.hashLength, + required this.passes, + required this.lanes, + required this.memorySizeKB, + required this.slices, + required this.segments, + required this.columns, + required this.blocks, + required this.key, + required this.personalization, + }) : midSlice = slices ~/ 2; + + /// Creates a context for Argon2 password hashing + /// + /// Required Parameters: + /// - [iterations] Number of iterations to perform. + /// - [parallelism] Degree of parallelism (i.e. number of threads). + /// - [memorySizeKB] Amount of memory (in kibibytes) to use. + /// + /// Optional Parameters: + /// - [salt] Salt (16 bytes recommended for password hashing). If absent, a + /// 64 bytes random salt is generated. + /// - [hashLength] Desired number of returned bytes. Default: 32. + /// - [key] Additional key. + /// - [personalization] Arbitrary additional data. + /// - [version] Algorithm version; Default: `Argon2Version.v13`, + /// - [type] Argon2 type; Default: `Argon2Type.argon2id`. + factory Argon2Context({ + required int iterations, + required int parallelism, + required int memorySizeKB, + List? key, + List? salt, + List? personalization, + int? hashLength, + Argon2Version version = Argon2Version.v13, + Argon2Type type = Argon2Type.argon2id, + }) { + hashLength ??= _defaultHashLength; + if (hashLength < _minDigestSize) { + throw ArgumentError('The tag length must be at least $_minDigestSize'); + } + if (hashLength > _maxDigestSize) { + throw ArgumentError('The tag length must be at most $_maxDigestSize'); + } + if (parallelism < _minParallelism) { + throw ArgumentError('The parallelism must be at least $_minParallelism'); + } + if (parallelism > _maxParallelism) { + throw ArgumentError('The parallelism must be at most $_maxParallelism'); + } + if (iterations < _minIterations) { + throw ArgumentError('The iterations must be at least $_minIterations'); + } + if (iterations > _maxIterations) { + throw ArgumentError('The iterations must be at most $_maxIterations'); + } + if (memorySizeKB < (parallelism << 3)) { + throw ArgumentError('The memory size must be at least 8 * parallelism'); + } + if (memorySizeKB > _maxMemory) { + throw ArgumentError('The memorySizeKB must be at most $_maxMemory'); + } + salt ??= randomBytes(64); + if (salt.length < _minSaltSize) { + throw ArgumentError('The salt must be at least $_minSaltSize bytes long'); + } + if (salt.length > _maxSaltSize) { + throw ArgumentError('The salt must be at most $_maxSaltSize bytes long'); + } + if (key != null) { + if (key.length < _minKeySize) { + throw ArgumentError('The key must be at least $_minKeySize bytes long'); + } + if (key.length > _maxKeySize) { + throw ArgumentError('The key must be at most $_maxKeySize bytes long'); + } + } + if (personalization != null) { + if (personalization.length < _minAD) { + throw ArgumentError('The extra data must be at least $_minAD bytes'); + } + if (personalization.length > _maxAD) { + throw ArgumentError('The extra data must be at most $_maxAD'); + } + } + + int segments = memorySizeKB ~/ (_slices * parallelism); + int columns = _slices * segments; + int blocks = parallelism * _slices * segments; + + return Argon2Context._( + salt: salt, + version: version, + type: type, + hashLength: hashLength, + passes: iterations, + slices: _slices, + lanes: parallelism, + memorySizeKB: memorySizeKB, + columns: columns, + segments: segments, + blocks: blocks, + key: key, + personalization: personalization, + ); + } + + /// Creates an [Argon2Context] instance from an encoded PHC-compliant string. + /// + /// The encoded string may look like this: + /// `$argon2i$v=19$m=16,t=2,p=1$c29tZSBzYWx0$u1eU6mZFG4/OOoTdAtM5SQ` + factory Argon2Context.fromEncoded( + CryptData data, { + List? key, + List? personalization, + }) { + var type = Argon2Type.fromName(data.id); + var version = Argon2Version.fromValue( + int.tryParse(data.version ?? '0') ?? 0, + ); + if (data.params == null) { + throw ArgumentError('No paramters'); + } + var m = data.params!['m']; + if (m == null) { + throw ArgumentError('Missing parameter: m'); + } + var t = data.params!['t']; + if (t == null) { + throw ArgumentError('Missing parameter: t'); + } + var p = data.params!['p']; + if (p == null) { + throw ArgumentError('Missing parameter: p'); + } + return Argon2Context( + type: type, + version: version, + iterations: int.parse(t), + parallelism: int.parse(p), + memorySizeKB: int.parse(m), + salt: data.saltBytes(), + hashLength: data.hashBytes()?.lengthInBytes, + key: key, + personalization: personalization, + ); + } + + /// Gets the PHC-compliant string for this [Argon2HashDigest] + String toEncoded(Uint8List hashBytes) { + return toCrypt( + CryptDataBuilder(type.name) + .version('${version.value}') + .param('m', memorySizeKB) + .param('t', passes) + .param('p', lanes) + .saltBytes(salt) + .hashBytes(hashBytes) + .build(), + ); + } +} diff --git a/hashlib/lib/src/algorithms/argon2/security.dart b/hashlib/lib/src/algorithms/argon2/security.dart new file mode 100644 index 0000000..7361892 --- /dev/null +++ b/hashlib/lib/src/algorithms/argon2/security.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'argon2.dart'; + +/// This contains some recommended values of memory, iteration and parallelism +/// values for [Argon2] algorithm. +/// +/// It is best to try out different combinations of these values to achieve the +/// desired runtime on a target machine. +class Argon2Security { + final String name; + + /// The amount of memory to use in KB. The more the better, but slower. + final int m; + + /// Number of threads or lanes to use. The more the better, but slower. + final int p; + + /// Number of iterations. The more the better, but slower. + final int t; + + /// The type of the algorithm + final Argon2Type type; + + /// The version of the algorithm + final Argon2Version version; + + const Argon2Security( + this.name, { + required this.m, + required this.p, + required this.t, + this.type = Argon2Type.argon2id, + this.version = Argon2Version.v13, + }); + + /// Provides a very low security. Use it for test purposes. + /// + /// It uses 32KB of memory, 2 lanes, and 2 iterations. + /// + /// **WARNING: Not recommended for general use.** + static const test = Argon2Security('test', m: 1 << 5, p: 4, t: 3); + + /// Provides low security but faster. Suitable for low-end devices. + /// + /// It uses 1MB of memory, 8 lanes, and 2 iterations. + static const little = Argon2Security('little', m: 1 << 10, p: 8, t: 2); + + /// Provides moderate security. Suitable for modern mobile devices. + /// + /// It uses 8MB of memory, 4 lanes, and 3 iterations. + /// This is 10x slower than the [little] one. + static const moderate = Argon2Security('moderate', m: 1 << 13, p: 4, t: 2); + + /// Provides good security. Second recommended option by [RFC-9106][rfc]. + /// + /// It uses 64MB of memory, 4 lanes, and 3 iterations. + /// This is 10x slower than the [moderate] one. + /// + /// [rfc]: https://www.ietf.org/rfc/rfc9106.html + static const good = Argon2Security('good', m: 1 << 16, p: 4, t: 3); + + /// Provides strong security. First recommended option by [RFC-9106][rfc]. + /// + /// It uses 2GB of memory, 4 lanes, and 1 iteration. + /// This is 10x slower than the [good] one. + /// + /// [rfc]: https://www.ietf.org/rfc/rfc9106.html + static const strong = Argon2Security('strong', m: 1 << 21, p: 4, t: 1); + + /// Provides strong security recommended by [OWASP][link]. + /// + /// It uses 46MB of memory, 1 lane, and 1 iteration. + /// + /// **Do not use with Argon2i.** + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp = Argon2Security('owasp1', m: 47104, t: 1, p: 1); + + /// Second recommendation from [OWASP][link]. + /// + /// It uses 19MB of memory, 1 lane, and 2 iterations. + /// + /// **Do not use with Argon2i.** + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp2 = Argon2Security('owasp2', m: 19456, t: 2, p: 1); + + /// Third recommendation from [OWASP][link]. + /// + /// It uses 12MB of memory, 1 lane, and 3 iterations. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp3 = Argon2Security('owasp3', m: 12288, t: 3, p: 1); + + /// Fourth recommendation from [OWASP][link]. + /// + /// It uses 9MB of memory, 1 lane, and 4 iterations. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp4 = Argon2Security('owasp4', m: 9216, t: 4, p: 1); + + /// Second recommendation from [OWASP][link]. + /// + /// It uses 7MB of memory, 1 lane, and 5 iterations. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp5 = Argon2Security('owasp5', m: 7168, t: 5, p: 1); +} diff --git a/hashlib/lib/src/algorithms/bcrypt/bcrypt.dart b/hashlib/lib/src/algorithms/bcrypt/bcrypt.dart new file mode 100644 index 0000000..6029137 --- /dev/null +++ b/hashlib/lib/src/algorithms/bcrypt/bcrypt.dart @@ -0,0 +1,488 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/algorithms/bcrypt/common.dart'; +import 'package:hashlib/src/algorithms/bcrypt/security.dart'; +import 'package:hashlib/src/core/kdf_base.dart'; + +/// Implementation for the bcrypt key generator +class Bcrypt extends KeyDerivatorBase { + final BcryptContext _ctx; + + @override + String get name => 'Bcrypt/${_ctx.version.name}'; + + @override + final int derivedKeyLength = 23; + + const Bcrypt._(this._ctx); + + /// Creates an [Bcrypt] instance with a sink for MAC generation. + factory Bcrypt({ + required int cost, + List? salt, + BcryptVersion version = BcryptVersion.$2b, + }) { + var ctx = BcryptContext( + cost: cost, + salt: salt, + version: version, + ); + return Bcrypt._(ctx); + } + + /// Creates an [Bcrypt] instance from [BcryptSecurity] parameter. + factory Bcrypt.fromSecurity( + BcryptSecurity security, { + List? salt, + BcryptVersion version = BcryptVersion.$2b, + }) { + var ctx = BcryptContext( + cost: security.nb, + salt: salt, + version: version, + ); + return Bcrypt._(ctx); + } + + /// Creates an [Bcrypt] instance from encoded string. + factory Bcrypt.fromEncoded(CryptData data) { + var ctx = BcryptContext.fromEncoded(data); + return Bcrypt._(ctx); + } + + /// Generate a derived key using the Bcrypt algorithm. + @override + BcryptHashDigest convert(List password) { + int i, j, l, h, t; + int s0, s1, s2, s3; + int nb = 1 << _ctx.cost; + var pass32 = _ctx.makePassword(password); + var salt32 = _makeSaltKey(_ctx.salt); + + // Initialize state: P (Subkeys) + S (Substitution boxes) + var state = Uint32List.fromList(_sv); + var p = Uint32List.view(state.buffer, 0, 18); + var s = Uint32List.view(state.buffer, 18 << 2, 1024); + + // Blowfish encrypt routine + l = 0; + h = 0; + void encrypt() { + l ^= p[0]; + h ^= _fsub(s, l) ^ p[1]; + l ^= _fsub(s, h) ^ p[2]; + h ^= _fsub(s, l) ^ p[3]; + l ^= _fsub(s, h) ^ p[4]; + h ^= _fsub(s, l) ^ p[5]; + l ^= _fsub(s, h) ^ p[6]; + h ^= _fsub(s, l) ^ p[7]; + l ^= _fsub(s, h) ^ p[8]; + h ^= _fsub(s, l) ^ p[9]; + l ^= _fsub(s, h) ^ p[10]; + h ^= _fsub(s, l) ^ p[11]; + l ^= _fsub(s, h) ^ p[12]; + h ^= _fsub(s, l) ^ p[13]; + l ^= _fsub(s, h) ^ p[14]; + h ^= _fsub(s, l) ^ p[15]; + l ^= _fsub(s, h) ^ p[16]; + h ^= p[17]; + // swap + t = l; + l = h; + h = t; + } + + // Key Expansion + l = 0; + h = 0; + s0 = salt32[0]; + s1 = salt32[1]; + s2 = salt32[2]; + s3 = salt32[3]; + for (i = 0; i < 18; ++i) { + p[i] ^= pass32[i]; + } + for (i = 0; i < state.length; i += 2) { + // block ^= salt + l ^= s0; + h ^= s1; + // blowfish encrypt + encrypt(); + // set state + state[i] = l; + state[i + 1] = h; + // s0 <-> s2 + t = s0; + s0 = s2; + s2 = t; + // s1 <-> s3 + t = s1; + s1 = s3; + s3 = t; + } + + // Bcrypt Rounds + for (j = 0; j < nb; ++j) { + // mix with password + l = 0; + h = 0; + for (i = 0; i < 18; ++i) { + p[i] ^= pass32[i]; + } + for (i = 0; i < state.length;) { + encrypt(); + state[i++] = l; + state[i++] = h; + } + // mix with salt + l = 0; + h = 0; + for (i = 0; i < 18; ++i) { + p[i] ^= salt32[i]; + } + for (i = 0; i < state.length;) { + encrypt(); + state[i++] = l; + state[i++] = h; + } + } + + // Encrypt IV + var result = Uint32List.fromList(_iv); + for (i = 0; i < 64; i++) { + l = result[0]; + h = result[1]; + encrypt(); + result[0] = l; + result[1] = h; + + l = result[2]; + h = result[3]; + encrypt(); + result[2] = l; + result[3] = h; + + l = result[4]; + h = result[5]; + encrypt(); + result[4] = l; + result[5] = h; + } + + // Transform to bytes + for (i = 0; i < result.length; ++i) { + result[i] = _swap32(result[i]); + } + var output = Uint8List.view(result.buffer, 0, derivedKeyLength); + return BcryptHashDigest(_ctx, output); + } + + static Uint32List _makeSaltKey(Uint8List salt) { + var salt32 = Uint32List.view(salt.buffer); + var dest = Uint32List(18); + dest[0] = _swap32(salt32[0]); + dest[1] = _swap32(salt32[1]); + dest[2] = _swap32(salt32[2]); + dest[3] = _swap32(salt32[3]); + for (int i = 4, j = 0; i < 18; i++, j++) { + dest[i] = dest[j]; + } + return dest; + } + + @pragma('vm:prefer-inline') + static int _swap32(int x) => + ((x << 24) & 0xff000000) | + ((x << 8) & 0x00ff0000) | + ((x >>> 8) & 0x0000ff00) | + ((x >>> 24) & 0x000000ff); + + /// Feistel substitution + @pragma('vm:prefer-inline') + static int _fsub(Uint32List s, int l) => + ((s[(l >>> 24) & 0xff] + // + s[0x100 | ((l >>> 16) & 0xff)]) ^ + s[0x200 | ((l >>> 8) & 0xff)]) + + s[0x300 | (l & 0xff)]; +} + +/// Hex form of text: 'OrpheanBeholderScryDoubt' +const List _iv = [ + 0x4f727068, + 0x65616e42, + 0x65686f6c, + 0x64657253, + 0x63727944, + 0x6f756274, +]; + +/// Fractional part of PI +const List _sv = [ + // first 18 bytes + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, + // next 1024 bytes + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, +]; diff --git a/hashlib/lib/src/algorithms/bcrypt/common.dart b/hashlib/lib/src/algorithms/bcrypt/common.dart new file mode 100644 index 0000000..d3af198 --- /dev/null +++ b/hashlib/lib/src/algorithms/bcrypt/common.dart @@ -0,0 +1,177 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/algorithms/bcrypt/bcrypt.dart'; +import 'package:hashlib/src/core/hash_digest.dart'; +import 'package:hashlib/src/random.dart'; + +/// The [Bcrypt] algorithm version +enum BcryptVersion { + /// This is a revised version of original v2 with UTF-8 character support + /// and inclusion of the null terminator with the password. + $2a._('2a'), + + /// This is the bug-fixed version of OpenBSD implementation of bcrypt, which + /// fixes the support for password longer than 255 characters. + $2b._('2b'), + + /// This was introduced by PHP `crypt_blowfish` implementation to mark hashes + /// generated with a bug in their implementation. + $2x._('2x'), + + /// This was introduced by PHP `crypt_blowfish` implementation to mark hashes + /// generated after fixing the bug in their implementation. + $2y._('2y'); + + /// The name of this version + final String name; + + const BcryptVersion._(this.name); + + /// Gets the version from string name + static BcryptVersion fromName(String name) { + switch (name) { + case '2a': + return BcryptVersion.$2a; + case '2b': + return BcryptVersion.$2b; + case '2x': + return BcryptVersion.$2x; + case '2y': + return BcryptVersion.$2y; + default: + throw FormatException('Invalid version'); + } + } +} + +/// The HashDigest for Bcrypt with [BcryptContext] +class BcryptHashDigest extends HashDigest { + final BcryptContext ctx; + + const BcryptHashDigest(this.ctx, super.bytes); + + @override + String toString() => encoded(); + + /// Gets a PHC-compliant encoded string + String encoded() => ctx.toEncoded(bytes); +} + +/// The configuration used by the [Bcrypt] algorithm +class BcryptContext { + /// The BCrypt version + final BcryptVersion version; + + /// Number of rounds in terms of power of 2 + final int cost; + + /// 16-byte salt + final Uint8List salt; + + const BcryptContext._({ + required this.salt, + required this.version, + required this.cost, + }); + + /// Creates an [BcryptContext] instance from encoded string. + /// + /// Parameters: + /// - [version] : The BcryptVersion to use. Default `BcryptVersion.$2b`. + /// - [salt] : An uniquely and randomly generated string. + /// - [cost] : Number of rounds in terms of power of 2. 0 < [cost] < 31. + factory BcryptContext({ + required int cost, + List? salt, + BcryptVersion version = BcryptVersion.$2b, + }) { + // validate parameters + if (cost < 0) { + throw ArgumentError('The cost must be at least 0'); + } + if (cost > 31) { + throw ArgumentError('The cost must be at most 31'); + } + salt ??= randomBytes(16); + if (salt.length != 16) { + throw ArgumentError('The salt must be exactly 16-bytes'); + } + return BcryptContext._( + cost: cost, + version: version, + salt: salt is Uint8List ? salt : Uint8List.fromList(salt), + ); + } + + /// Creates an [BcryptContext] instance from encoded string. + /// + /// The encoded string may look like this: + /// `$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC` + factory BcryptContext.fromEncoded(CryptData data) { + var version = BcryptVersion.fromName(data.id); + var cost = int.tryParse(data.salt ?? '0'); + if (cost == null) { + throw FormatException('Invalid cost'); + } + Uint8List? salt; + var hash = data.hash; + if (hash != null) { + if (hash.length != 22 && hash.length != 53) { + throw FormatException('Invalid hash'); + } + salt = fromBase64( + hash.substring(0, 22), + codec: Base64Codec.bcrypt, + ); + } + return BcryptContext( + salt: salt, + cost: cost, + version: version, + ); + } + + /// Gets a PHC-compliant encoded string + String toEncoded([Uint8List? hashBytes]) { + var hash = toBase64(salt, codec: Base64Codec.bcrypt); + if (hashBytes != null) { + hash += toBase64(hashBytes, codec: Base64Codec.bcrypt); + } + return toCrypt( + CryptDataBuilder(version.name) + .salt('$cost'.padLeft(2, '0')) + .hash(hash) + .build(), + ); + } + + /// Make the 72-byte long password using version-specific strategy. + Uint32List makePassword(List password) { + int i, j; + var long32 = Uint32List(18); + var long = Uint8List.view(long32.buffer); + var pass8 = Uint8List.fromList(password); + for (i = 0; i < 72 && i < pass8.length; i++) { + long[i] = pass8[i]; + } + if (i < 72) { + long[i++] = 0; + } + for (j = 0; i < 72; i++, j++) { + long[i] = long[j]; + } + for (i = 0; i < 18; ++i) { + j = long32[i]; + j = ((j << 24) & 0xff000000) | + ((j << 8) & 0x00ff0000) | + ((j >>> 8) & 0x0000ff00) | + ((j >>> 24) & 0x000000ff); + long32[i] = j; + } + return long32; + } +} diff --git a/hashlib/lib/src/algorithms/bcrypt/security.dart b/hashlib/lib/src/algorithms/bcrypt/security.dart new file mode 100644 index 0000000..f89c121 --- /dev/null +++ b/hashlib/lib/src/algorithms/bcrypt/security.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'bcrypt.dart'; + +/// This contains some recommended parameters for [Bcrypt] algorithm. +class BcryptSecurity { + final String name; + + /// The number of rounds in terms of power of 2. + final int nb; + + const BcryptSecurity( + this.name, { + required this.nb, + }); + + /// Provides a very low security. Use it for test purposes. + /// + /// It uses 2^1 = 2 round for encryption. + /// + /// **WARNING: Not recommended for general use.** + static const test = BcryptSecurity('test', nb: 1); + + /// Provides low security but faster. Suitable for low-end devices. + /// + /// It uses 2^5 = 32 rounds for encryption. + static const little = BcryptSecurity('little', nb: 5); + + /// Provides moderate security. Suitable for modern mobile devices. + /// + /// It uses 2^8 = 256 rounds for encryption. + static const moderate = BcryptSecurity('moderate', nb: 8); + + /// Provides good security. + /// + /// It uses 2^12 = 4096 rounds for encryption. + static const good = BcryptSecurity('good', nb: 12); + + /// Provides strong security. + /// + /// It uses 2^15 = 32768 rounds for encryption. + static const strong = BcryptSecurity('strong', nb: 15); + + /// Provides strong security recommended by [OWASP][link]. + /// + /// It uses 2^10 = 1024 rounds for encryption. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp = BcryptSecurity('owasp', nb: 10); +} diff --git a/hashlib/lib/src/algorithms/blake2/blake2b.dart b/hashlib/lib/src/algorithms/blake2/blake2b.dart new file mode 100644 index 0000000..e4209e9 --- /dev/null +++ b/hashlib/lib/src/algorithms/blake2/blake2b.dart @@ -0,0 +1,4 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'blake2b_64bit.dart' if (dart.library.js) 'blake2b_32bit.dart'; diff --git a/hashlib/lib/src/algorithms/blake2/blake2b_32bit.dart b/hashlib/lib/src/algorithms/blake2/blake2b_32bit.dart new file mode 100644 index 0000000..415d4bf --- /dev/null +++ b/hashlib/lib/src/algorithms/blake2/blake2b_32bit.dart @@ -0,0 +1,354 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +/* + | BLAKE2b | +--------------+------------------+ + Bits in word | w = 64 | + Rounds in F | r = 12 | + Block bytes | bb = 128 | + Hash bytes | 1 <= nn <= 64 | + Key bytes | 0 <= kk <= 64 | + Input bytes | 0 <= ll < 2**128 | +--------------+------------------+ + G Rotation | (R1, R2, R3, R4) | + constants = | (32, 24, 16, 63) | +--------------+------------------+ +*/ + +const int _mask32 = 0xFFFFFFFF; + +const int _r1 = 32; +const int _r2 = 24; +const int _r3 = 16; +const int _r4 = 63; + +const _seed = [ + 0xF3BCC908, 0x6A09E667, // + 0x84CAA73B, 0xBB67AE85, + 0xFE94F82B, 0x3C6EF372, + 0x5F1D36F1, 0xA54FF53A, + 0xADE682D1, 0x510E527F, + 0x2B3E6C1F, 0x9B05688C, + 0xFB41BD6B, 0x1F83D9AB, + 0x137E2179, 0x5BE0CD19, +]; + +// This is used to contruct sigma2 map. Kept for future reference. +// const _sigma = [ +// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // round 0 +// [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], // round 1 +// [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], // round 2 +// [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], // round 3 +// [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], // round 4 +// [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], // round 5 +// [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], // round 6 +// [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], // round 7 +// [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], // round 8 +// [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], // round 9 +// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // round 10 +// [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], // round 11 +// ]; + +// _sigma.map((e) => e.map((e) => e << 1).toList()).toList(); +const _sigma2 = [ + [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30], // round 0 + [28, 20, 8, 16, 18, 30, 26, 12, 2, 24, 0, 4, 22, 14, 10, 6], // round 1 + [22, 16, 24, 0, 10, 4, 30, 26, 20, 28, 6, 12, 14, 2, 18, 8], // round 2 + [14, 18, 6, 2, 26, 24, 22, 28, 4, 12, 10, 20, 8, 0, 30, 16], // round 3 + [18, 0, 10, 14, 4, 8, 20, 30, 28, 2, 22, 24, 12, 16, 6, 26], // round 4 + [4, 24, 12, 20, 0, 22, 16, 6, 8, 26, 14, 10, 30, 28, 2, 18], // round 5 + [24, 10, 2, 30, 28, 26, 8, 20, 0, 14, 12, 6, 18, 4, 16, 22], // round 6 + [26, 22, 14, 28, 24, 2, 6, 18, 10, 0, 30, 8, 16, 12, 4, 20], // round 7 + [12, 30, 28, 18, 22, 6, 0, 16, 24, 4, 26, 14, 2, 8, 20, 10], // round 8 + [20, 4, 16, 8, 14, 12, 2, 10, 30, 22, 18, 28, 6, 24, 26, 0], // round 9 + [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30], // round 10 + [28, 20, 8, 16, 18, 30, 26, 12, 2, 24, 0, 4, 22, 14, 10, 6], // round 11 +]; + +const int _w0 = 0; +const int _w1 = _w0 + 2; +const int _w2 = _w1 + 2; +const int _w3 = _w2 + 2; +const int _w4 = _w3 + 2; +const int _w5 = _w4 + 2; +const int _w6 = _w5 + 2; +const int _w7 = _w6 + 2; +const int _w8 = _w7 + 2; +const int _w9 = _w8 + 2; +const int _w10 = _w9 + 2; +const int _w11 = _w10 + 2; +const int _w12 = _w11 + 2; +const int _w13 = _w12 + 2; +const int _w14 = _w13 + 2; +const int _w15 = _w14 + 2; + +/// Implementation is derived from [RFC-7693][rfc] document for +/// "The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)". +/// +/// For reference, the official [blake2][blake2] implementation was followed. +/// +/// Note that blake2b uses 64-bit operations. +/// +/// [rfc]: https://www.ietf.org/rfc/rfc7693.html +/// [blake2]: https://github.com/BLAKE2/BLAKE2/blob/master/ref/blake2b-ref.c +class Blake2bHash extends BlockHashSink implements MACSinkBase { + final List? key; + late int _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7; + late int _s8, _s9, _s10, _s11, _s12, _s13, _s14, _s15; + final Uint32List _var = Uint32List(_w15 + 2); + final Uint32List state = Uint32List(_seed.length); + + @override + final int hashLength; + + @override + final int derivedKeyLength; + + /// For internal use only. + Blake2bHash( + int digestSize, { + this.key, + List? salt, + List? aad, + }) : hashLength = digestSize, + derivedKeyLength = digestSize, + super(1024 >>> 3) { + if (digestSize < 1 || digestSize > 64) { + throw ArgumentError('The digest size must be between 1 and 64'); + } + + // Parameter block from the seed + _s0 = _seed[0] ^ 0x01010000 ^ hashLength; + _s1 = _seed[1]; + _s2 = _seed[2]; + _s3 = _seed[3]; + _s4 = _seed[4]; + _s5 = _seed[5]; + _s6 = _seed[6]; + _s7 = _seed[7]; + _s8 = _seed[8]; + _s9 = _seed[9]; + _s10 = _seed[10]; + _s11 = _seed[11]; + _s12 = _seed[12]; + _s13 = _seed[13]; + _s14 = _seed[14]; + _s15 = _seed[15]; + + if (key != null && key!.isNotEmpty) { + if (key!.length > 64) { + throw ArgumentError('The key should not be greater than 64 bytes'); + } + // Add key length to parameter + _s0 ^= key!.length << 8; + } + + if (salt != null && salt.isNotEmpty) { + if (salt.length != 16) { + throw ArgumentError('The valid length of salt is 16 bytes'); + } + for (int i = 0, p = 0; i < 4; i++, p += 8) { + _s8 ^= (salt[i] & 0xFF) << p; + } + for (int i = 4, p = 0; i < 8; i++, p += 8) { + _s9 ^= (salt[i] & 0xFF) << p; + } + for (int i = 8, p = 0; i < 12; i++, p += 8) { + _s10 ^= (salt[i] & 0xFF) << p; + } + for (int i = 12, p = 0; i < 16; i++, p += 8) { + _s11 ^= (salt[i] & 0xFF) << p; + } + } + + if (aad != null && aad.isNotEmpty) { + if (aad.length != 16) { + throw ArgumentError('The valid length of personalization is 16 bytes'); + } + for (int i = 0, p = 0; i < 4; i++, p += 8) { + _s12 ^= (aad[i] & 0xFF) << p; + } + for (int i = 4, p = 0; i < 8; i++, p += 8) { + _s13 ^= (aad[i] & 0xFF) << p; + } + for (int i = 8, p = 0; i < 12; i++, p += 8) { + _s14 ^= (aad[i] & 0xFF) << p; + } + for (int i = 12, p = 0; i < 16; i++, p += 8) { + _s15 ^= (aad[i] & 0xFF) << p; + } + } + + reset(); + } + + @override + void reset() { + super.reset(); + state[0] = _s0; + state[1] = _s1; + state[2] = _s2; + state[3] = _s3; + state[4] = _s4; + state[5] = _s5; + state[6] = _s6; + state[7] = _s7; + state[8] = _s8; + state[9] = _s9; + state[10] = _s10; + state[11] = _s11; + state[12] = _s12; + state[13] = _s13; + state[14] = _s14; + state[15] = _s15; + // If the key is present, the first block is the key padded with zeroes + if (key != null) { + int i; + for (i = 0; i < key!.length; ++i) { + buffer[i] = key![i]; + } + for (; i < blockLength; ++i) { + buffer[i] = 0; + } + messageLength = pos = blockLength; + } + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++, messageLength++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + } + + /// `v[k] = (v[i] << (64 - n)) | (v[i] >>> n)` + static void _rotr(int n, List v, int i, int k) { + var a = v[i + 1]; + var b = v[i]; + if (n == 32) { + v[k + 1] = b; + v[k] = a; + } else if (n < 32) { + v[k + 1] = (b << (32 - n)) | (a >>> n); + v[k] = (a << (32 - n)) | (b >>> n); + } else { + v[k + 1] = (a << (64 - n)) | (b >>> (n - 32)); + v[k] = (b << (64 - n)) | (a >>> (n - 32)); + } + } + + /// `v[k] = v[i] ^ v[j]` + static void _xor(List v, int i, int j, int k) { + v[k] = v[i] ^ v[j]; + v[k + 1] = v[i + 1] ^ v[j + 1]; + } + + /// `v[k] = v[i] + v[j]` + static void _add2(List v, int i, int j, int k) { + var t = v[i] + v[j]; + v[k] = t; + v[k + 1] = (v[i + 1] + v[j + 1]) + (v[k] < t ? 1 : 0); + } + + /// `v[k] = v[i] + v[j] + n[x]` + static void _add3(List v, int i, int j, List n, int x, int k) { + var t = v[i] + v[j]; + v[k] = t; + v[k + 1] = v[i + 1] + v[j + 1] + (v[k] < t ? 1 : 0); + t = v[k] + n[x]; + v[k] += n[x]; + v[k + 1] += n[x + 1] + (v[k] < t ? 1 : 0); + } + + // The G function for mixing + static void _mix( + List v, + int a, + int b, + int c, + int d, + List m, + int x, + int y, + ) { + // v[a] = (v[a] + v[b] + x); + _add3(v, a, b, m, x, a); + // v[d] = _rotr(v[d] ^ v[a], _r1); + _xor(v, d, a, d); + _rotr(_r1, v, d, d); + // v[c] = (v[c] + v[d]); + _add2(v, c, d, c); + // v[b] = _rotr(v[b] ^ v[c], _r2); + _xor(v, b, c, b); + _rotr(_r2, v, b, b); + // v[a] = (v[a] + v[b] + y); + _add3(v, a, b, m, y, a); + // v[d] = _rotr(v[d] ^ v[a], _r3); + _xor(v, d, a, d); + _rotr(_r3, v, d, d); + // v[c] = (v[c] + v[d]); + _add2(v, c, d, c); + // v[b] = _rotr(v[b] ^ v[c], _r4); + _xor(v, b, c, b); + _rotr(_r4, v, b, b); + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + // Copy state and seed + for (int i = 0; i < 16; ++i) { + _var[i] = state[i]; + _var[_w8 + i] = _seed[i]; + } + + _var[_w12] ^= messageLength & _mask32; + _var[_w12 + 1] ^= (messageLength >>> 32) & _mask32; + + if (last) { + _var[_w14] ^= _mask32; + _var[_w14 + 1] ^= _mask32; + } + + // Cryptographic mixing + for (int i = 0; i < 12; i++) { + var s = _sigma2[i]; + _mix(_var, _w0, _w4, _w8, _w12, sbuffer, s[0], s[1]); + _mix(_var, _w1, _w5, _w9, _w13, sbuffer, s[2], s[3]); + _mix(_var, _w2, _w6, _w10, _w14, sbuffer, s[4], s[5]); + _mix(_var, _w3, _w7, _w11, _w15, sbuffer, s[6], s[7]); + _mix(_var, _w0, _w5, _w10, _w15, sbuffer, s[8], s[9]); + _mix(_var, _w1, _w6, _w11, _w12, sbuffer, s[10], s[11]); + _mix(_var, _w2, _w7, _w8, _w13, sbuffer, s[12], s[13]); + _mix(_var, _w3, _w4, _w9, _w14, sbuffer, s[14], s[15]); + } + + // Build new state + for (int i = 0; i < 16; ++i) { + state[i] ^= _var[i] ^ _var[_w8 + i]; + } + } + + @override + Uint8List $finalize() { + // Fill remaining buffer to put the message length at the end + for (; pos < blockLength; pos++) { + buffer[pos] = 0; + } + + // Update with the final block + $update(buffer, 0, true); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/blake2/blake2b_64bit.dart b/hashlib/lib/src/algorithms/blake2/blake2b_64bit.dart new file mode 100644 index 0000000..d1d81fb --- /dev/null +++ b/hashlib/lib/src/algorithms/blake2/blake2b_64bit.dart @@ -0,0 +1,323 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +/* + | BLAKE2b | +--------------+------------------+ + Bits in word | w = 64 | + Rounds in F | r = 12 | + Block bytes | bb = 128 | + Hash bytes | 1 <= nn <= 64 | + Key bytes | 0 <= kk <= 64 | + Input bytes | 0 <= ll < 2**128 | +--------------+------------------+ + G Rotation | (R1, R2, R3, R4) | + constants = | (32, 24, 16, 63) | +--------------+------------------+ +*/ + +const int _r1 = 32; +const int _r2 = 24; +const int _r3 = 16; +const int _r4 = 63; + +const _seed = [ + 0x6A09E667F3BCC908, + 0xBB67AE8584CAA73B, + 0x3C6EF372FE94F82B, + 0xA54FF53A5F1D36F1, + 0x510E527FADE682D1, + 0x9B05688C2B3E6C1F, + 0x1F83D9ABFB41BD6B, + 0x5BE0CD19137E2179, +]; + +const _sigma = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // round 0 + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], // round 1 + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], // round 2 + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], // round 3 + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], // round 4 + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], // round 5 + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], // round 6 + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], // round 7 + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], // round 8 + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], // round 9 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // round 10 + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], // round 11 +]; + +/// Implementation is derived from [RFC-7693][rfc] document for +/// "The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)". +/// +/// For reference, the official [blake2][blake2] implementation was followed. +/// +/// Note that blake2b uses 64-bit operations. +/// +/// [rfc]: https://www.ietf.org/rfc/rfc7693.html +/// [blake2]: https://github.com/BLAKE2/BLAKE2/blob/master/ref/blake2b-ref.c +class Blake2bHash extends BlockHashSink implements MACSinkBase { + final List? key; + late int _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7; + final Uint64List state = Uint64List(_seed.length); + late final Uint64List qbuffer = Uint64List.view(buffer.buffer); + + @override + final int hashLength; + + @override + final int derivedKeyLength; + + /// For internal use only. + Blake2bHash( + int digestSize, { + this.key, + List? salt, + List? aad, + }) : hashLength = digestSize, + derivedKeyLength = digestSize, + super(1024 >>> 3) { + if (digestSize < 1 || digestSize > 64) { + throw ArgumentError('The digest size must be between 1 and 64'); + } + + // Parameter block from the seed + _s0 = _seed[0] ^ 0x01010000 ^ hashLength; + _s1 = _seed[1]; + _s2 = _seed[2]; + _s3 = _seed[3]; + _s4 = _seed[4]; + _s5 = _seed[5]; + _s6 = _seed[6]; + _s7 = _seed[7]; + + if (key != null && key!.isNotEmpty) { + if (key!.length > 64) { + throw ArgumentError('The key should not be greater than 64 bytes'); + } + // Add key length to parameter + _s0 ^= key!.length << 8; + } + + if (salt != null && salt.isNotEmpty) { + if (salt.length != 16) { + throw ArgumentError('The valid length of salt is 16 bytes'); + } + for (int i = 0, p = 0; i < 8; i++, p += 8) { + _s4 ^= (salt[i] & 0xFF) << p; + } + for (int i = 8, p = 0; i < 16; i++, p += 8) { + _s5 ^= (salt[i] & 0xFF) << p; + } + } + + if (aad != null && aad.isNotEmpty) { + if (aad.length != 16) { + throw ArgumentError('The valid length of personalization is 16 bytes'); + } + for (int i = 0, p = 0; i < 8; i++, p += 8) { + _s6 ^= (aad[i] & 0xFF) << p; + } + for (int i = 8, p = 0; i < 16; i++, p += 8) { + _s7 ^= (aad[i] & 0xFF) << p; + } + } + + reset(); + } + + @override + void reset() { + super.reset(); + state[0] = _s0; + state[1] = _s1; + state[2] = _s2; + state[3] = _s3; + state[4] = _s4; + state[5] = _s5; + state[6] = _s6; + state[7] = _s7; + // If the key is present, the first block is the key padded with zeroes + if (key != null) { + int i; + for (i = 0; i < key!.length; ++i) { + buffer[i] = key![i]; + } + for (; i < blockLength; ++i) { + buffer[i] = 0; + } + messageLength = pos = blockLength; + } + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++, messageLength++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + } + + /// Rotates x right by n bits. + @pragma('vm:prefer-inline') + static int _rotr(int x, int n) => (x >>> n) ^ (x << (64 - n)); + + // static void _G(Uint64List v, int a, int b, int c, int d, int x, int y) { + // v[a] = (v[a] + v[b] + x); + // v[d] = _rotr(v[d] ^ v[a], _r1); + // v[c] = (v[c] + v[d]); + // v[b] = _rotr(v[b] ^ v[c], _r2); + // v[a] = (v[a] + v[b] + y); + // v[d] = _rotr(v[d] ^ v[a], _r3); + // v[c] = (v[c] + v[d]); + // v[b] = _rotr(v[b] ^ v[c], _r4); + // } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + var m = qbuffer; + int w0, w1, w2, w3, w4, w5, w6, w7; + int w8, w9, w10, w11, w12, w13, w14, w15; + + // first half from state + w0 = state[0]; + w1 = state[1]; + w2 = state[2]; + w3 = state[3]; + w4 = state[4]; + w5 = state[5]; + w6 = state[6]; + w7 = state[7]; + + // second half from IV + w8 = _seed[0]; + w9 = _seed[1]; + w10 = _seed[2]; + w11 = _seed[3]; + w12 = _seed[4] ^ messageLength; + w13 = _seed[5]; + w14 = _seed[6]; + w15 = _seed[7]; + + if (last) { + w14 = ~w14; // invert bits + } + + // Cryptographic mixing + for (int i = 0; i < 12; i++) { + var s = _sigma[i]; + + // _G(v, 0, 4, 8, 12, m[s[0]], m[s[1]]); + w0 += w4 + m[s[0]]; + w12 = _rotr(w12 ^ w0, _r1); + w8 += w12; + w4 = _rotr(w4 ^ w8, _r2); + w0 += w4 + m[s[1]]; + w12 = _rotr(w12 ^ w0, _r3); + w8 += w12; + w4 = _rotr(w4 ^ w8, _r4); + + // _G(v, 1, 5, 9, 13, m[s[2]], m[s[3]]); + w1 += w5 + m[s[2]]; + w13 = _rotr(w13 ^ w1, _r1); + w9 += w13; + w5 = _rotr(w5 ^ w9, _r2); + w1 += w5 + m[s[3]]; + w13 = _rotr(w13 ^ w1, _r3); + w9 += w13; + w5 = _rotr(w5 ^ w9, _r4); + + // _G(v, 2, 6, 10, 14, m[s[4]], m[s[5]]); + w2 += w6 + m[s[4]]; + w14 = _rotr(w14 ^ w2, _r1); + w10 += w14; + w6 = _rotr(w6 ^ w10, _r2); + w2 += w6 + m[s[5]]; + w14 = _rotr(w14 ^ w2, _r3); + w10 += w14; + w6 = _rotr(w6 ^ w10, _r4); + + // _G(v, 3, 7, 11, 15, m[s[6]], m[s[7]]); + w3 += w7 + m[s[6]]; + w15 = _rotr(w15 ^ w3, _r1); + w11 += w15; + w7 = _rotr(w7 ^ w11, _r2); + w3 += w7 + m[s[7]]; + w15 = _rotr(w15 ^ w3, _r3); + w11 += w15; + w7 = _rotr(w7 ^ w11, _r4); + + // _G(v, 0, 5, 10, 15, m[s[8]], m[s[9]]); + w0 += w5 + m[s[8]]; + w15 = _rotr(w15 ^ w0, _r1); + w10 += w15; + w5 = _rotr(w5 ^ w10, _r2); + w0 += w5 + m[s[9]]; + w15 = _rotr(w15 ^ w0, _r3); + w10 += w15; + w5 = _rotr(w5 ^ w10, _r4); + + // _G(v, 1, 6, 11, 12, m[s[10]], m[s[11]]); + w1 += w6 + m[s[10]]; + w12 = _rotr(w12 ^ w1, _r1); + w11 += w12; + w6 = _rotr(w6 ^ w11, _r2); + w1 += w6 + m[s[11]]; + w12 = _rotr(w12 ^ w1, _r3); + w11 += w12; + w6 = _rotr(w6 ^ w11, _r4); + + // _G(v, 2, 7, 8, 13, m[s[12]], m[s[13]]); + w2 += w7 + m[s[12]]; + w13 = _rotr(w13 ^ w2, _r1); + w8 += w13; + w7 = _rotr(w7 ^ w8, _r2); + w2 += w7 + m[s[13]]; + w13 = _rotr(w13 ^ w2, _r3); + w8 += w13; + w7 = _rotr(w7 ^ w8, _r4); + + // _G(v, 3, 4, 9, 14, m[s[14]], m[s[15]]); + w3 += w4 + m[s[14]]; + w14 = _rotr(w14 ^ w3, _r1); + w9 += w14; + w4 = _rotr(w4 ^ w9, _r2); + w3 += w4 + m[s[15]]; + w14 = _rotr(w14 ^ w3, _r3); + w9 += w14; + w4 = _rotr(w4 ^ w9, _r4); + } + + // XOR the two halves for new state + state[0] ^= w0 ^ w8; + state[1] ^= w1 ^ w9; + state[2] ^= w2 ^ w10; + state[3] ^= w3 ^ w11; + state[4] ^= w4 ^ w12; + state[5] ^= w5 ^ w13; + state[6] ^= w6 ^ w14; + state[7] ^= w7 ^ w15; + } + + @override + Uint8List $finalize() { + // Fill remaining buffer to put the message length at the end + for (; pos < blockLength; pos++) { + buffer[pos] = 0; + } + + // Update with the final block + $update(buffer, 0, true); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/blake2/blake2s.dart b/hashlib/lib/src/algorithms/blake2/blake2s.dart new file mode 100644 index 0000000..3274410 --- /dev/null +++ b/hashlib/lib/src/algorithms/blake2/blake2s.dart @@ -0,0 +1,323 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +/* + | BLAKE2s | +--------------+------------------+ + Bits in word | w = 32 | + Rounds in F | r = 10 | + Block bytes | bb = 64 | + Hash bytes | 1 <= nn <= 32 | + Key bytes | 0 <= kk <= 32 | + Input bytes | 0 <= ll < 2**64 | +--------------+------------------+ + G Rotation | (R1, R2, R3, R4) | + constants = | (16, 12, 8, 7) | +--------------+------------------+ +*/ + +const int _mask32 = 0xFFFFFFFF; + +const int _r1 = 16; +const int _r2 = 12; +const int _r3 = 8; +const int _r4 = 7; + +// Same as SHA-256 +const _seed = [ + 0x6A09E667, // a + 0xBB67AE85, // b + 0x3C6EF372, // c + 0xA54FF53A, // d + 0x510E527F, // e + 0x9B05688C, // f + 0x1F83D9AB, // g + 0x5BE0CD19, // h +]; + +const _sigma = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // round 0 + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], // round 1 + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], // round 2 + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], // round 3 + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], // round 4 + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], // round 5 + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], // round 6 + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], // round 7 + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], // round 8 + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], // round 9 +]; + +/// Implementation is derived from [RFC-7693][rfc] document for +/// "The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)". +/// +/// For reference, the official [blake2][blake2] implementation was followed. +/// +/// Note that blake2s uses only 32-bit operations. +/// +/// [rfc]: https://www.ietf.org/rfc/rfc7693.html +/// [blake2]: https://github.com/BLAKE2/BLAKE2/blob/master/ref/blake2b-ref.c +class Blake2sHash extends BlockHashSink implements MACSinkBase { + final List? key; + late int _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7; + final Uint32List state = Uint32List(_seed.length); + + @override + final int hashLength; + + @override + final int derivedKeyLength; + + /// For internal use only. + Blake2sHash( + int digestSize, { + this.key, + List? salt, + List? aad, + }) : hashLength = digestSize, + derivedKeyLength = digestSize, + super(64) { + if (digestSize < 1 || digestSize > 32) { + throw ArgumentError('The digest size must be between 1 and 32'); + } + + // Parameter block from the seed + _s0 = _seed[0] ^ 0x01010000 ^ hashLength; + _s1 = _seed[1]; + _s2 = _seed[2]; + _s3 = _seed[3]; + _s4 = _seed[4]; + _s5 = _seed[5]; + _s6 = _seed[6]; + _s7 = _seed[7]; + + // Add key length to parameter + if (key != null && key!.isNotEmpty) { + if (key!.length > 32) { + throw ArgumentError('The key should not be greater than 32 bytes'); + } + _s0 ^= key!.length << 8; + } + + if (salt != null && salt.isNotEmpty) { + if (salt.length != 8) { + throw ArgumentError('The valid length of salt is 8 bytes'); + } + for (int i = 0, p = 0; i < 4; i++, p += 8) { + _s4 ^= (salt[i] & 0xFF) << p; + } + for (int i = 4, p = 0; i < 8; i++, p += 8) { + _s5 ^= (salt[i] & 0xFF) << p; + } + } + + if (aad != null && aad.isNotEmpty) { + if (aad.length != 8) { + throw ArgumentError('The valid length of personalization is 8 bytes'); + } + for (int i = 0, p = 0; i < 4; i++, p += 8) { + _s6 ^= (aad[i] & 0xFF) << p; + } + for (int i = 4, p = 0; i < 8; i++, p += 8) { + _s7 ^= (aad[i] & 0xFF) << p; + } + } + + reset(); + } + + @override + void reset() { + super.reset(); + state[0] = _s0; + state[1] = _s1; + state[2] = _s2; + state[3] = _s3; + state[4] = _s4; + state[5] = _s5; + state[6] = _s6; + state[7] = _s7; + // If the key is present, the first block is the key padded with zeroes + if (key != null) { + int i; + for (i = 0; i < key!.length; ++i) { + buffer[i] = key![i]; + } + for (; i < blockLength; ++i) { + buffer[i] = 0; + } + messageLength = pos = blockLength; + } + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++, messageLength++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + } + + /// Rotates x right by n bits. + @pragma('vm:prefer-inline') + static int _rotr(int x, int n) => ((x & _mask32) >>> n) | ((x << (32 - n))); + + // static void _G(Uint32List v, int a, int b, int c, int d, int x, int y) { + // v[a] = (v[a] + v[b] + x); + // v[d] = _rotr(v[d] ^ v[a], _r1); + // v[c] = (v[c] + v[d]); + // v[b] = _rotr(v[b] ^ v[c], _r2); + // v[a] = (v[a] + v[b] + y); + // v[d] = _rotr(v[d] ^ v[a], _r3); + // v[c] = (v[c] + v[d]); + // v[b] = _rotr(v[b] ^ v[c], _r4); + // } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + var m = sbuffer; + int w0, w1, w2, w3, w4, w5, w6, w7; + int w8, w9, w10, w11, w12, w13, w14, w15; + + // first half from state + w0 = state[0]; + w1 = state[1]; + w2 = state[2]; + w3 = state[3]; + w4 = state[4]; + w5 = state[5]; + w6 = state[6]; + w7 = state[7]; + + // second half from IV + w8 = _seed[0]; + w9 = _seed[1]; + w10 = _seed[2]; + w11 = _seed[3]; + w12 = _seed[4] ^ (messageLength & _mask32); + w13 = _seed[5] ^ (messageLength >>> 32); + w14 = _seed[6]; + w15 = _seed[7]; + + if (last) { + w14 ^= _mask32; // invert bits + } + + // Cryptographic mixing + for (int i = 0; i < 10; i++) { + var s = _sigma[i]; + + // _G(v, 0, 4, 8, 12, m[s[0]], m[s[1]]); + w0 += w4 + m[s[0]]; + w12 = _rotr(w12 ^ w0, _r1); + w8 += w12; + w4 = _rotr(w4 ^ w8, _r2); + w0 += w4 + m[s[1]]; + w12 = _rotr(w12 ^ w0, _r3); + w8 += w12; + w4 = _rotr(w4 ^ w8, _r4); + + // _G(v, 1, 5, 9, 13, m[s[2]], m[s[3]]); + w1 += w5 + m[s[2]]; + w13 = _rotr(w13 ^ w1, _r1); + w9 += w13; + w5 = _rotr(w5 ^ w9, _r2); + w1 += w5 + m[s[3]]; + w13 = _rotr(w13 ^ w1, _r3); + w9 += w13; + w5 = _rotr(w5 ^ w9, _r4); + + // _G(v, 2, 6, 10, 14, m[s[4]], m[s[5]]); + w2 += w6 + m[s[4]]; + w14 = _rotr(w14 ^ w2, _r1); + w10 += w14; + w6 = _rotr(w6 ^ w10, _r2); + w2 += w6 + m[s[5]]; + w14 = _rotr(w14 ^ w2, _r3); + w10 += w14; + w6 = _rotr(w6 ^ w10, _r4); + + // _G(v, 3, 7, 11, 15, m[s[6]], m[s[7]]); + w3 += w7 + m[s[6]]; + w15 = _rotr(w15 ^ w3, _r1); + w11 += w15; + w7 = _rotr(w7 ^ w11, _r2); + w3 += w7 + m[s[7]]; + w15 = _rotr(w15 ^ w3, _r3); + w11 += w15; + w7 = _rotr(w7 ^ w11, _r4); + + // _G(v, 0, 5, 10, 15, m[s[8]], m[s[9]]); + w0 += w5 + m[s[8]]; + w15 = _rotr(w15 ^ w0, _r1); + w10 += w15; + w5 = _rotr(w5 ^ w10, _r2); + w0 += w5 + m[s[9]]; + w15 = _rotr(w15 ^ w0, _r3); + w10 += w15; + w5 = _rotr(w5 ^ w10, _r4); + + // _G(v, 1, 6, 11, 12, m[s[10]], m[s[11]]); + w1 += w6 + m[s[10]]; + w12 = _rotr(w12 ^ w1, _r1); + w11 += w12; + w6 = _rotr(w6 ^ w11, _r2); + w1 += w6 + m[s[11]]; + w12 = _rotr(w12 ^ w1, _r3); + w11 += w12; + w6 = _rotr(w6 ^ w11, _r4); + + // _G(v, 2, 7, 8, 13, m[s[12]], m[s[13]]); + w2 += w7 + m[s[12]]; + w13 = _rotr(w13 ^ w2, _r1); + w8 += w13; + w7 = _rotr(w7 ^ w8, _r2); + w2 += w7 + m[s[13]]; + w13 = _rotr(w13 ^ w2, _r3); + w8 += w13; + w7 = _rotr(w7 ^ w8, _r4); + + // _G(v, 3, 4, 9, 14, m[s[14]], m[s[15]]); + w3 += w4 + m[s[14]]; + w14 = _rotr(w14 ^ w3, _r1); + w9 += w14; + w4 = _rotr(w4 ^ w9, _r2); + w3 += w4 + m[s[15]]; + w14 = _rotr(w14 ^ w3, _r3); + w9 += w14; + w4 = _rotr(w4 ^ w9, _r4); + } + + // XOR the two halves for new state + state[0] ^= w0 ^ w8; + state[1] ^= w1 ^ w9; + state[2] ^= w2 ^ w10; + state[3] ^= w3 ^ w11; + state[4] ^= w4 ^ w12; + state[5] ^= w5 ^ w13; + state[6] ^= w6 ^ w14; + state[7] ^= w7 ^ w15; + } + + @override + Uint8List $finalize() { + // Fill remaining buffer to put the message length at the end + for (; pos < blockLength; pos++) { + buffer[pos] = 0; + } + + // Update with the final block + $update(buffer, 0, true); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/crc/crc16.dart b/hashlib/lib/src/algorithms/crc/crc16.dart new file mode 100644 index 0000000..e9752d2 --- /dev/null +++ b/hashlib/lib/src/algorithms/crc/crc16.dart @@ -0,0 +1,246 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/hash_base.dart'; + +const int _mask16 = 0xFFFF; + +/// Predefined polynomials for CRC-16. +/// +/// The predefined polynomials comes from various sources: +/// - https://crccalc.com/ +/// - https://docs.rs/crate/crc16 +/// - https://crcmod.sourceforge.net/crcmod.predefined.html +/// - https://en.wikipedia.org/wiki/Cyclic_redundancy_check +class CRC16Params { + // 0x8005 group + static const arc = + CRC16Params._('ARC', 0x8005, 0x0000, true, 0x0000); // 0xBB3D + static const cms = + CRC16Params._('CMS', 0x8005, 0xFFFF, false, 0x0000); // 0xAEE7 + static const dds110 = + CRC16Params._('DDS-110', 0x8005, 0x800D, false, 0x0000); // 0x9ECF + static const maximDow = + CRC16Params._('MAXIM-DOW', 0x8005, 0x0000, true, 0xFFFF); // 0x44C2 + static const modbus = + CRC16Params._('MODBUS', 0x8005, 0xFFFF, true, 0x0000); // 0x4B37 + static const umts = + CRC16Params._('UMTS', 0x8005, 0x0000, false, 0x0000); // 0xFEE8 + static const usb = + CRC16Params._('USB', 0x8005, 0xFFFF, true, 0xFFFF); // 0xB4C8 + + // 0x1021 group + static const genibus = + CRC16Params._('GENIBUS', 0x1021, 0xFFFF, false, 0xFFFF); // 0xD64E + static const gsm = + CRC16Params._('GSM', 0x1021, 0x0000, false, 0xFFFF); // 0xCE3C + static const ibm3740 = + CRC16Params._('IBM-3740', 0x1021, 0xFFFF, false, 0x0000); // 0x29B1 + static const ccittFalse = + CRC16Params._('CCITT-FALSE', 0x1021, 0xFFFF, false, 0x0000); // 0x29B1 + static const ibmSdlc = + CRC16Params._('IBM-SDLC', 0x1021, 0xFFFF, true, 0xFFFF); // 0x906E + static const x25 = + CRC16Params._('X-25', 0x1021, 0xFFFF, true, 0xFFFF); // 0x906E + static const iso = + CRC16Params._('ISO-IEC-14443-3-A', 0x1021, 0x6363, true); // 0xBF05 + static const kermit = + CRC16Params._('KERMIT', 0x1021, 0x0000, true, 0x0000); // 0x2189 + static const mcrf4xx = + CRC16Params._('MCRF4XX', 0x1021, 0xFFFF, true, 0x0000); // 0x6F91 + static const riello = + CRC16Params._('RIELLO', 0x1021, 0x554D, true, 0x0000); // 0x63D0 + static const augCcitt = + CRC16Params._('AUG-CCITT', 0x1021, 0x1D0F, false, 0x0000); // 0xE5CC + static const spiFujitsu = + CRC16Params._('SPI-FUJITSU', 0x1021, 0x1D0F, false, 0x0000); // 0xE5CC + static const tms37157 = + CRC16Params._('TMS37157', 0x1021, 0x3791, true, 0x0000); // 0x26B1 + static const xmodem = + CRC16Params._('XMODEM', 0x1021, 0x0000, false, 0x0000); // 0x31C3 + + // Others + static const cdma2000 = + CRC16Params._('CDMA2000', 0xC867, 0xFFFF, false, 0x0000); // 0x4C06 + static const dectR = + CRC16Params._('DECT-R', 0x0589, 0x0000, false, 0x0001); // 0x007E + static const dectX = + CRC16Params._('DECT-X', 0x0589, 0x0000, false, 0x0000); // 0x007F + static const dnp = + CRC16Params._('DNP', 0x3D65, 0x0000, true, 0xFFFF); // 0xEA82 + static const en13757 = + CRC16Params._('EN-13757', 0x3D65, 0x0000, false, 0xFFFF); // 0xC2B7 + static const lj1200 = + CRC16Params._('LJ1200', 0x6F63, 0x0000, false, 0x0000); // 0xBDF4 + static const nrsc5 = + CRC16Params._('NRSC-5', 0x080B, 0xFFFF, true, 0x0000); // 0xA066 + static const m17 = + CRC16Params._('M17', 0x5935, 0xFFFF, false, 0x0000); // 0x772B + static const opensafetyA = + CRC16Params._('OPENSAFETY-A', 0x5935, 0x0000, false, 0x0000); // 0x5D38 + static const opensafetyB = + CRC16Params._('OPENSAFETY-B', 0x755B, 0x0000, false, 0x0000); // 0x20FE + static const profibus = + CRC16Params._('PROFIBUS', 0x1DCF, 0xFFFF, false, 0xFFFF); // 0xA819 + static const t10Dif = + CRC16Params._('T10-DIF', 0x8BB7, 0x0000, false, 0x0000); // 0xD0DB + static const teledisk = + CRC16Params._('TELEDISK', 0xA097, 0x0000, false, 0x0000); // 0x0FB3 + + // From Wikipedia + static const arinc = + CRC16Params._("ARINC", 0xA02B, 0x0000, false, 0x0000); // 0xEBA4 + + // aliases + static const ibm = arc; + static const ansi = arc; + static const lha = arc; + static const arinc453 = arc; + static const ccitt = kermit; + static const bluetooth = kermit; + static const buypass = umts; + static const autosar = genibus; + + //-------------------------------------------------------------------------- + // Implementation + //-------------------------------------------------------------------------- + + /// Polynomial name + final String name; + + /// Polynomial value + final int poly; + + /// Initial CRC + final int seed; + + /// Output XOR value + final int xorOut; + + /// To use the reverse of the polynomial + final bool reversed; + + const CRC16Params._( + this.name, + this.poly, + this.seed, + this.reversed, [ + this.xorOut = 0, + ]); + + /// Create a custom polynomial for CRC-16 + /// + /// Parameters: + /// - [seed]: initial counter to start from + /// - [xorOut]: the value to xor with the final output + /// - [reversed]: to use reversed or reflected polynomial and input + CRC16Params( + this.poly, { + this.seed = 0, + this.xorOut = 0, + this.reversed = false, + }) : name = poly.toRadixString(16); +} + +/// A CRC-16 code generator with a polynomial. +abstract class CRC16Hash extends HashDigestSink { + final int seed; + final int xorOut; + final int polynomial; + final table = Uint16List(256); + + int _crc; + + /// Creates a sink for generating CRC-16 Hash + CRC16Hash(CRC16Params params) + : seed = params.seed, + xorOut = params.xorOut, + polynomial = params.poly, + _crc = params.seed { + $generate(); + } + + @override + final int hashLength = 2; + + @override + void reset() { + _crc = seed; + super.reset(); + } + + /// Generates the lookup table for CRC-16 + void $generate(); + + @override + Uint8List $finalize() { + _crc ^= xorOut; + return Uint8List.fromList([ + _crc >>> 8, + _crc, + ]); + } +} + +/// A CRC-16 code generator with a polynomial. +class CRC16NormalHash extends CRC16Hash { + /// Creates a sink for generating CRC-16 Hash + CRC16NormalHash(super.params); + + @override + void $generate() { + int i, j, r, p; + p = polynomial & _mask16; + for (i = 0; i < 256; ++i) { + r = i << 8; + for (j = 0; j < 8; ++j) { + r = (((r >>> 15) & 1) * p) ^ (r << 1); + } + table[i] = r; + } + } + + @override + void $process(List chunk, int start, int end) { + for (int index; start < end; start++) { + index = ((_crc >>> 8) ^ chunk[start]) & 0xFF; + _crc = table[index] ^ (_crc << 8); + } + } +} + +/// A CRC-16 code generator with a reversed or reflected polynomial. +class CRC16ReverseHash extends CRC16Hash { + /// Creates a sink for generating CRC-16 Hash + CRC16ReverseHash(super.params); + + @override + void $generate() { + int i, j, r, p; + + // reverse polynomial + p = 0; + for (i = 0; i < 16; ++i) { + p ^= ((polynomial >>> i) & 1) << (15 - i); + } + + // generate table + for (i = 0; i < 256; ++i) { + r = i; + for (j = 0; j < 8; ++j) { + r = ((r & 1) * p) ^ (r >>> 1); + } + table[i] = r; + } + } + + @override + void $process(List chunk, int start, int end) { + for (int index; start < end; start++) { + index = (_crc ^ chunk[start]) & 0xFF; + _crc = table[index] ^ (_crc >>> 8); + } + } +} diff --git a/hashlib/lib/src/algorithms/crc/crc32.dart b/hashlib/lib/src/algorithms/crc/crc32.dart new file mode 100644 index 0000000..c772ec9 --- /dev/null +++ b/hashlib/lib/src/algorithms/crc/crc32.dart @@ -0,0 +1,215 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/hash_base.dart'; + +const int _mask32 = 0xFFFFFFFF; + +/// Predefined polynomials for CRC-32. +/// +/// The predefined polynomials comes from various sources: +/// - https://crccalc.com/ +/// - https://pkg.go.dev/hash/crc32 +/// - https://crcmod.sourceforge.net/crcmod.predefined.html +/// - https://en.wikipedia.org/wiki/Cyclic_redundancy_check +class CRC32Params { + /// IEEE is by far and away the most common CRC-32 polynomial. + /// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, etc. + static const ieee = CRC32Params._( + 'IEEE', 0x04C11DB7, 0xFFFFFFFF, true, 0xFFFFFFFF); // 0xCBF43926 + + /// Castagnoli's polynomial, used in iSCSI. + /// Has better error detection characteristics than IEEE. + /// https://dx.doi.org/10.1109/26.231911 + static const castagnoli = CRC32Params._( + 'Castagnoli', 0x1EDC6F41, 0xFFFFFFFF, true, 0xFFFFFFFF); // 0xE3069283 + + /// Koopman's polynomial. + /// Also has better error detection characteristics than IEEE. + /// https://dx.doi.org/10.1109/DSN.2002.1028931 + static const koopman = CRC32Params._( + 'Koopman', 0x741B8CD7, 0xFFFFFFFF, true, 0x00000000); // 0xD2C22F51 + + // 0x04C11DB7 group + static const bzip2 = CRC32Params._( + 'BZIP2', 0x04C11DB7, 0xFFFFFFFF, false, 0xFFFFFFFF); // 0xFC891918 + static const cksum = CRC32Params._( + 'CKSUM', 0x04C11DB7, 0x00000000, false, 0xFFFFFFFF); // 0x765E7680 + static const jamcrc = CRC32Params._( + 'JAMCRC', 0x04C11DB7, 0xFFFFFFFF, true, 0x00000000); // 0x340BC6D9 + static const mpeg2 = CRC32Params._( + 'MPEG-2', 0x04C11DB7, 0xFFFFFFFF, false, 0x00000000); // 0x0376E6E7 + + // Others + static const aixm = CRC32Params._( + 'AIXM', 0x814141AB, 0x00000000, false, 0x00000000); // 0x3010BF7F + static const autosar = CRC32Params._( + 'AUTOSAR', 0xF4ACFB13, 0xFFFFFFFF, true, 0xFFFFFFFF); // 0x1697D06A + static const base91D = CRC32Params._( + 'BASE91-D', 0xA833982B, 0xFFFFFFFF, true, 0xFFFFFFFF); // 0x87315576 + static const cdRomEdc = CRC32Params._( + 'CD-ROM-EDC', 0x8001801B, 0x00000000, true, 0x00000000); // 0x6EC2EDC4 + static const xfer = CRC32Params._( + 'XFER', 0x000000AF, 0x00000000, false, 0x00000000); // 0xBD0BE338 + + // aliases + static const iso = ieee; + static const isoHdlc = ieee; + static const adccp = ieee; + static const v42 = ieee; + static const xz = ieee; + static const pkzip = ieee; + static const iscsi = castagnoli; + static const interlaken = castagnoli; + static const nvme = castagnoli; + static const base91C = castagnoli; + static const mef = koopman; + static const aal5 = bzip2; + static const dectB = bzip2; + static const posix = cksum; + + //-------------------------------------------------------------------------- + // Implementation + //-------------------------------------------------------------------------- + + /// Polynomial name + final String name; + + /// Polynomial value + final int poly; + + /// Initial CRC + final int seed; + + /// Output XOR value + final int xorOut; + + /// To use the reverse of the polynomial + final bool reversed; + + const CRC32Params._( + this.name, + this.poly, + this.seed, + this.reversed, [ + this.xorOut = 0, + ]); + + /// Create a custom polynomial for CRC-32 + /// + /// Parameters: + /// - [seed]: initial counter to start from + /// - [xorOut]: the value to xor with the final output + /// - [reversed]: to use reversed or reflected polynomial and input + CRC32Params( + this.poly, { + this.seed = 0, + this.xorOut = 0, + this.reversed = false, + }) : name = poly.toRadixString(16); +} + +/// A CRC-32 code generator with a polynomial. +abstract class CRC32Hash extends HashDigestSink { + final int seed; + final int xorOut; + final int polynomial; + final table = Uint32List(256); + + int _crc; + + /// Creates a sink for generating CRC-32 Hash + CRC32Hash(CRC32Params params) + : seed = params.seed, + xorOut = params.xorOut, + polynomial = params.poly, + _crc = params.seed { + $generate(); + } + + @override + final int hashLength = 4; + + @override + void reset() { + _crc = seed; + super.reset(); + } + + /// Generates the lookup table for CRC-32 + void $generate(); + + @override + Uint8List $finalize() { + _crc ^= xorOut; + return Uint8List.fromList([ + _crc >>> 24, + _crc >>> 16, + _crc >>> 8, + _crc, + ]); + } +} + +/// A CRC-32 code generator with a polynomial. +class CRC32NormalHash extends CRC32Hash { + /// Creates a sink for generating CRC-32 Hash + CRC32NormalHash(super.params); + + @override + void $generate() { + int i, j, r, p; + p = polynomial & _mask32; + for (i = 0; i < 256; ++i) { + r = i << 24; + for (j = 0; j < 8; ++j) { + r = (((r >>> 31) & 1) * p) ^ (r << 1); + } + table[i] = r; + } + } + + @override + void $process(List chunk, int start, int end) { + for (int index; start < end; start++) { + index = ((_crc >>> 24) ^ chunk[start]) & 0xFF; + _crc = table[index] ^ (_crc << 8); + } + } +} + +/// A CRC-32 code generator with a reversed or reflected polynomial. +class CRC32ReverseHash extends CRC32Hash { + /// Creates a sink for generating CRC-32 Hash + CRC32ReverseHash(super.params); + + @override + void $generate() { + int i, j, r, p; + + // reverse polynomial + p = 0; + for (i = 0; i < 32; ++i) { + p ^= ((polynomial >>> i) & 1) << (31 - i); + } + + // generate table + for (i = 0; i < 256; ++i) { + r = i; + for (j = 0; j < 8; ++j) { + r = ((r & 1) * p) ^ (r >>> 1); + } + table[i] = r; + } + } + + @override + void $process(List chunk, int start, int end) { + for (int index; start < end; start++) { + index = (_crc ^ chunk[start]) & 0xFF; + _crc = table[index] ^ (_crc >>> 8); + } + } +} diff --git a/hashlib/lib/src/algorithms/crc/crc64.dart b/hashlib/lib/src/algorithms/crc/crc64.dart new file mode 100644 index 0000000..81f25b6 --- /dev/null +++ b/hashlib/lib/src/algorithms/crc/crc64.dart @@ -0,0 +1,265 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/core/hash_base.dart'; + +const int _pow32 = 2 ^ 32; +const int _mask32 = 0xFFFFFFFF; + +/// Predefined polynomials for CRC-64. +/// +/// The predefined polynomials comes from various sources: +/// - https://pkg.go.dev/hash/crc64 +/// - https://crcmod.sourceforge.net/crcmod.predefined.html +/// - https://en.wikipedia.org/wiki/Cyclic_redundancy_check +/// - https://github.com/emn178/js-crc/blob/master/src/models.js +class CRC64Params { + /// Defined in ISO 3309 (HDLC), Swiss-Prot/TrEMBL. + static const iso = CRC64Params._("ISO-HDLC", 0x00000000, 0x0000001B, true, + 0x00000000, 0x00000000, 0x00000000, 0x00000000); // 46a5a9388a5beffe + + /// Defined in ECMA-182 p. 51, XZ Utils. + static const ecma = CRC64Params._("ECMA-182", 0x42F0E1EB, 0xA9EA3693, false, + 0x00000000, 0x00000000, 0x00000000, 0x00000000); // b90956c775a41001 + + static const goIso = CRC64Params._("GO-ISO", 0x00000000, 0x0000001B, true, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); // 46a5a9388a5beffe + static const goEcma = CRC64Params._("GO-ECMA", 0x42F0E1EB, 0xA9EA3693, true, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); // 995dc9bbdf1939fa + static const ms = CRC64Params._("MS", 0x259C84CB, 0xA6426349, true, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000); // 75d4b74f024eceea + static const nvme = CRC64Params._("NVME", 0xAD93D235, 0x94C93659, true, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); // ae8b14860a799888 + static const redis = CRC64Params._("Redis", 0xAD93D235, 0x94C935A9, true, + 0x00000000, 0x00000000, 0x00000000, 0x00000000); // e9c6d914c4b8d9ca + static const we = CRC64Params._("WE", 0x42F0E1EB, 0xA9EA3693, false, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); // 62ec59e3f1a4f00a + static const xz = CRC64Params._("XZ", 0x42F0E1EB, 0xA9EA3693, true, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); // 995dc9bbdf1939fa + static const jones = CRC64Params._("Jones", 0xAD93D235, 0x94C935A9, true, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000); // caa717168609f281 + + //-------------------------------------------------------------------------- + // Implementation + //-------------------------------------------------------------------------- + + /// Polynomial name + final String name; + + /// Most significant 32-bytes of polynomial (first 32) + final int high; + + /// Least significant 32-bytes of polynomial (last 32) + final int low; + + /// Initial CRC (most significant 32-bytes) + final int seedHigh; + + /// Initial CRC (least significant 32-bytes) + final int seedLow; + + /// Output XOR value (least significant 32-bytes) + final int xorOutHigh; + + /// Output XOR value (most significant 32-bytes) + final int xorOutLow; + + /// To use the reverse of the polynomial + final bool reversed; + + const CRC64Params._( + this.name, + this.high, + this.low, + this.reversed, + this.seedHigh, + this.seedLow, [ + this.xorOutHigh = 0, + this.xorOutLow = 0, + ]); + + /// Create a custom polynomial for CRC-64 + /// + /// Parameters: + /// - [seed]: initial counter to start from + /// - [xorOut]: the value to xor with the final output + /// - [reversed]: to use reversed or reflected polynomial and input + CRC64Params( + int poly, { + this.reversed = false, + int seed = 0, + int xorOut = 0, + }) : high = poly ~/ _pow32, + low = poly % _pow32, + seedHigh = seed ~/ _pow32, + seedLow = seed % _pow32, + xorOutHigh = xorOut ~/ _pow32, + xorOutLow = xorOut % _pow32, + name = poly.toRadixString(16); + + /// Create a custom polynomial from hexadecimal + /// + /// Parameters: + /// - [poly]: the polynomial in hexadecimal (MSB first) + /// - [seed]: initial counter to start from (MSB first) + /// - [xorOut]: the value to xor with the final output (MSB first) + /// - [reversed]: to use reversed or reflected polynomial and input + factory CRC64Params.hex({ + required String poly, + bool reversed = false, + String seed = "0000000000000000", + String xorOut = "0000000000000000", + }) { + Uint8List p = fromHex(poly); + Uint8List s = fromHex(seed); + Uint8List x = fromHex(xorOut); + int high = (p[0] << 24) ^ (p[1] << 16) ^ (p[2] << 8) ^ (p[3]); + int low = (p[4] << 24) ^ (p[5] << 16) ^ (p[6] << 8) ^ (p[7]); + int seedHigh = (s[0] << 24) ^ (s[1] << 16) ^ (s[2] << 8) ^ (s[3]); + int seedLow = (s[4] << 24) ^ (s[5] << 16) ^ (s[6] << 8) ^ (s[7]); + int xorOutHigh = (x[0] << 24) ^ (x[1] << 16) ^ (x[2] << 8) ^ (x[3]); + int xorOutLow = (x[4] << 24) ^ (x[5] << 16) ^ (x[6] << 8) ^ (x[7]); + return CRC64Params._( + poly, + high, + low, + reversed, + seedHigh, + seedLow, + xorOutHigh, + xorOutLow, + ); + } +} + +/// A CRC-64 code generator with a polynomial. +abstract class CRC64Hash extends HashDigestSink { + final int polyHigh; + final int polyLow; + final int seedHigh; + final int seedLow; + final int xorOutHigh; + final int xorOutLow; + final table = Uint32List(512); + + int _high, _low; + + /// Creates a sink for generating CRC-64 Hash + CRC64Hash(CRC64Params params) + : polyHigh = params.high, + polyLow = params.low, + seedHigh = params.seedHigh, + seedLow = params.seedLow, + xorOutHigh = params.xorOutHigh, + xorOutLow = params.xorOutLow, + _high = params.seedHigh, + _low = params.seedLow { + $generate(); + } + + @override + final int hashLength = 8; + + @override + void reset() { + super.reset(); + _high = seedHigh; + _low = seedLow; + } + + /// Generates the lookup table for CRC-64 + void $generate(); + + @override + Uint8List $finalize() { + _high ^= xorOutHigh; + _low ^= xorOutLow; + return Uint8List.fromList([ + _high >>> 24, + _high >>> 16, + _high >>> 8, + _high, + _low >>> 24, + _low >>> 16, + _low >>> 8, + _low, + ]); + } +} + +/// A CRC-64 code generator with a normal polynomial. +class CRC64NormalHash extends CRC64Hash { + /// Creates a sink for generating CRC-64 Hash + CRC64NormalHash(super.params); + + @override + void $generate() { + int i, j, h, l, f, ph, pl; + ph = polyHigh & _mask32; + pl = polyLow & _mask32; + for (i = 0; i < 512; i += 2) { + h = i << 23; // (i / 2) << 24 + l = 0; + for (j = 0; j < 8; ++j) { + f = (h >>> 31) & 1; + h = (f * ph) ^ (h << 1) ^ ((l >>> 31) & 1); + l = (f * pl) ^ (l << 1); + } + table[i] = h; + table[i + 1] = l; + } + } + + @override + void $process(List chunk, int start, int end) { + for (int i; start < end; start++) { + i = (((_high >>> 24) ^ chunk[start]) & 0xFF) << 1; + _high = table[i] ^ (_high << 8) ^ ((_low >>> 24) & 0xFF); + _low = table[i + 1] ^ (_low << 8); + } + } +} + +/// A CRC-64 code generator with reversed or reflected polynomial. +class CRC64ReverseHash extends CRC64Hash { + /// Creates a sink for generating CRC-64 Hash + CRC64ReverseHash(super.params); + + @override + void $generate() { + int i, j, h, l, f, ph, pl; + + // reverse polynomial + ph = 0; + pl = 0; + for (i = 0; i < 32; ++i) { + pl ^= ((polyHigh >>> i) & 1) << (31 - i); + ph ^= ((polyLow >>> i) & 1) << (31 - i); + } + + // generate table + for (i = 0; i < 512; i += 2) { + h = 0; + l = i >>> 1; + for (j = 0; j < 8; ++j) { + f = l & 1; + l = (f * pl) ^ ((h & 1) << 31) ^ ((l & _mask32) >>> 1); + h = (f * ph) ^ ((h & _mask32) >>> 1); + } + table[i] = h; + table[i + 1] = l; + } + } + + @override + void $process(List chunk, int start, int end) { + for (int i; start < end; start++) { + i = ((_low ^ chunk[start]) & 0xFF) << 1; + _low = table[i + 1] ^ ((_high & 0xFF) << 24) ^ ((_low & _mask32) >>> 8); + _high = table[i] ^ ((_high & _mask32) >>> 8); + } + } +} diff --git a/hashlib/lib/src/algorithms/hmac.dart b/hashlib/lib/src/algorithms/hmac.dart new file mode 100644 index 0000000..02c4f26 --- /dev/null +++ b/hashlib/lib/src/algorithms/hmac.dart @@ -0,0 +1,70 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +/// This implementation is derived from the RFC document +/// [HMAC: Keyed-Hashing for Message Authentication][rfc2104]. +/// +/// [rfc2104]: https://www.ietf.org/rfc/rfc2104.html +class HMACSink extends MACSinkBase { + final BlockHashSink _sink; + + @override + late final int hashLength = _sink.hashLength; + + late final innerKey = Uint8List(_sink.blockLength); + late final outerKey = Uint8List(_sink.blockLength); + + HMACSink( + T algo, + List keyBytes, + ) : _sink = algo.createSink() { + var key = keyBytes is Uint8List ? keyBytes : Uint8List.fromList(keyBytes); + + // Keys longer than blockLength are shortened by hashing them + if (key.length > _sink.blockLength) { + _sink.reset(); + _sink.add(key); + key = _sink.$finalize(); + } + + // Calculated padded keys for inner and outer sinks + int i = 0; + for (; i < key.length; i++) { + innerKey[i] = key[i] ^ 0x36; + outerKey[i] = key[i] ^ 0x5c; + } + for (; i < _sink.blockLength; i++) { + innerKey[i] = 0x36; + outerKey[i] = 0x5c; + } + + _sink.reset(); + _sink.add(innerKey); + } + + @override + void reset() { + _sink.reset(); + _sink.add(innerKey); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + _sink.$process(chunk, start, end); + } + + @override + Uint8List $finalize() { + var hash = _sink.$finalize(); + _sink.reset(); + _sink.add(outerKey); + _sink.add(hash); + return _sink.$finalize(); + } +} diff --git a/hashlib/lib/src/algorithms/keccak/keccak.dart b/hashlib/lib/src/algorithms/keccak/keccak.dart new file mode 100644 index 0000000..01b7736 --- /dev/null +++ b/hashlib/lib/src/algorithms/keccak/keccak.dart @@ -0,0 +1,42 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'keccak_64bit.dart' if (dart.library.js) 'keccak_32bit.dart'; + +export 'keccak_64bit.dart' if (dart.library.js) 'keccak_32bit.dart'; + +/// Implementation of Keccak-224 that generates a 224-bit hash. +class Keccak224Hash extends KeccakHash { + Keccak224Hash() + : super( + stateSize: 224 >>> 3, + paddingByte: 0x01, + ); +} + +/// Implementation of Keccak-256 that generates a 256-bit hash. +class Keccak256Hash extends KeccakHash { + Keccak256Hash() + : super( + stateSize: 256 >>> 3, + paddingByte: 0x01, + ); +} + +/// Implementation of Keccak-384 that generates a 384-bit hash. +class Keccak384Hash extends KeccakHash { + Keccak384Hash() + : super( + stateSize: 384 >>> 3, + paddingByte: 0x01, + ); +} + +/// Implementation of Keccak-512 that generates a 512-bit hash. +class Keccak512Hash extends KeccakHash { + Keccak512Hash() + : super( + stateSize: 512 >>> 3, + paddingByte: 0x01, + ); +} diff --git a/hashlib/lib/src/algorithms/keccak/keccak_32bit.dart b/hashlib/lib/src/algorithms/keccak/keccak_32bit.dart new file mode 100644 index 0000000..9b9b7fb --- /dev/null +++ b/hashlib/lib/src/algorithms/keccak/keccak_32bit.dart @@ -0,0 +1,409 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +// Rotation constants +const int _rot01 = 36; +const int _rot02 = 3; +const int _rot03 = 41; +const int _rot04 = 18; +const int _rot05 = 1; +const int _rot06 = 44; +const int _rot07 = 10; +const int _rot08 = 45; +const int _rot09 = 2; +const int _rot10 = 62; +const int _rot11 = 6; +const int _rot12 = 43; +const int _rot13 = 15; +const int _rot14 = 61; +const int _rot15 = 28; +const int _rot16 = 55; +const int _rot17 = 25; +const int _rot18 = 21; +const int _rot19 = 56; +const int _rot20 = 27; +const int _rot21 = 20; +const int _rot22 = 39; +const int _rot23 = 8; +const int _rot24 = 14; + +// 200-bit round constants iota mapping [little endian] +const _rc = [ + 0x00000001, 0x00000000, // + 0x00008082, 0x00000000, + 0x0000808a, 0x80000000, + 0x80008000, 0x80000000, + 0x0000808b, 0x00000000, + 0x80000001, 0x00000000, + 0x80008081, 0x80000000, + 0x00008009, 0x80000000, + 0x0000008a, 0x00000000, + 0x00000088, 0x00000000, + 0x80008009, 0x00000000, + 0x8000000a, 0x00000000, + 0x8000808b, 0x00000000, + 0x0000008b, 0x80000000, + 0x00008089, 0x80000000, + 0x00008003, 0x80000000, + 0x00008002, 0x80000000, + 0x00000080, 0x80000000, + 0x0000800a, 0x00000000, + 0x8000000a, 0x80000000, + 0x80008081, 0x80000000, + 0x00008080, 0x80000000, + 0x80000001, 0x00000000, + 0x80008008, 0x80000000, +]; + +// State variable indices +const int _a0 = 0; +const int _a1 = _a0 + 2; +const int _a2 = _a1 + 2; +const int _a3 = _a2 + 2; +const int _a4 = _a3 + 2; +const int _a5 = _a4 + 2; +const int _a6 = _a5 + 2; +const int _a7 = _a6 + 2; +const int _a8 = _a7 + 2; +const int _a9 = _a8 + 2; +const int _a10 = _a9 + 2; +const int _a11 = _a10 + 2; +const int _a12 = _a11 + 2; +const int _a13 = _a12 + 2; +const int _a14 = _a13 + 2; +const int _a15 = _a14 + 2; +const int _a16 = _a15 + 2; +const int _a17 = _a16 + 2; +const int _a18 = _a17 + 2; +const int _a19 = _a18 + 2; +const int _a20 = _a19 + 2; +const int _a21 = _a20 + 2; +const int _a22 = _a21 + 2; +const int _a23 = _a22 + 2; +const int _a24 = _a23 + 2; + +// Temp variable indices +const int _b0 = 0; +const int _b1 = _b0 + 2; +const int _b2 = _b1 + 2; +const int _b3 = _b2 + 2; +const int _b4 = _b3 + 2; +const int _b5 = _b4 + 2; +const int _b6 = _b5 + 2; +const int _b7 = _b6 + 2; +const int _b8 = _b7 + 2; +const int _b9 = _b8 + 2; +const int _b10 = _b9 + 2; +const int _b11 = _b10 + 2; +const int _b12 = _b11 + 2; +const int _b13 = _b12 + 2; +const int _b14 = _b13 + 2; +const int _b15 = _b14 + 2; +const int _b16 = _b15 + 2; +const int _b17 = _b16 + 2; +const int _b18 = _b17 + 2; +const int _b19 = _b18 + 2; +const int _b20 = _b19 + 2; +const int _b21 = _b20 + 2; +const int _b22 = _b21 + 2; +const int _b23 = _b22 + 2; +const int _b24 = _b23 + 2; +const int _c0 = _b24 + 2; +const int _c1 = _c0 + 2; +const int _c2 = _c1 + 2; +const int _c3 = _c2 + 2; +const int _c4 = _c3 + 2; +const int _d = _c4 + 2; + +/// This is an implementation of Keccak-f\[1600\] derived from +/// [FIPS-202 SHA-3 Standard][fips202] published by NIST. +/// +/// Followed the optimizations in [PyCryptodome's implementation][keccak]. +/// Special thanks to [tiny_sha3] for readable code and test cases. +/// +/// It uses 32-bit integers to accommodate 64-bit integer operations, designed +/// specially to be supported by Web VM. It is albeit slower than the native +/// implementation. +/// +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +/// [keccak]: https://github.com/Legrandin/pycryptodome/blob/master/src/keccak.c +/// [tiny_sha3]: https://github.com/mjosaarinen/tiny_sha3/blob/master/sha3.c +class KeccakHash extends BlockHashSink { + final int stateSize; + final int paddingByte; + final _var = Uint32List(_d + 2); + late final Uint32List state = sbuffer; + + @override + final int hashLength; + + KeccakHash({ + required this.stateSize, + required this.paddingByte, + int? outputSize, // equals to state size if not provided + }) : assert(stateSize >= 0 && stateSize < 100), + hashLength = outputSize ?? stateSize, + super( + 200 - (stateSize << 1), // rate as blockLength + bufferLength: 200, // 1600-bit state as buffer + ); + + @override + void reset() { + buffer.fillRange(0, buffer.length, 0); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] ^= chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + // (x << n) | (x >>> (64 - n)) + static void _rotl(int n, List x, int i, List z, int k) { + // *numbers are in little-endian order* + var a = x[i]; + var b = x[i + 1]; + if (n == 32) { + z[k] = b; + z[k + 1] = a; + } else if (n < 32) { + z[k] = (a << n) | (b >>> (32 - n)); + z[k + 1] = (b << n) | a >>> (32 - n); + } else { + z[k] = (b << (n - 32)) | (a >>> (64 - n)); + z[k + 1] = (a << (n - 32)) | (b >>> (64 - n)); + } + } + + // z = x ^ y + static void _xor(List x, int i, List y, int j, List z, int k) { + z[k] = x[i] ^ y[j]; + z[k + 1] = x[i + 1] ^ y[j + 1]; + } + + // z = x[i1] ^ x[i2] ^ x[i3] ^ x[i4] ^ x[i5] + static void _xor5( + List x, int i1, int i2, int i3, int i4, int i5, List z, int k) { + z[k] = x[i1] ^ x[i2] ^ x[i3] ^ x[i4] ^ x[i5]; + z[k + 1] = x[i1 + 1] ^ x[i2 + 1] ^ x[i3 + 1] ^ x[i4 + 1] ^ x[i5 + 1]; + } + + // z = x[i1] ^ (~x[i2] & x[i3]); + static void _chi(List x, int i1, int i2, int i3, List z, int k) { + z[k] = x[i1] ^ (~x[i2] & x[i3]); + z[k + 1] = x[i1 + 1] ^ (~x[i2 + 1] & x[i3 + 1]); + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + for (int r = 0; r < _rc.length; r += 2) { + // ---- Theta parity ---- + // c0 = a0 ^ a5 ^ a10 ^ a15 ^ a20; + _xor5(state, _a0, _a5, _a10, _a15, _a20, _var, _c0); + // c1 = a1 ^ a6 ^ a11 ^ a16 ^ a21; + _xor5(state, _a1, _a6, _a11, _a16, _a21, _var, _c1); + // c2 = a2 ^ a7 ^ a12 ^ a17 ^ a22; + _xor5(state, _a2, _a7, _a12, _a17, _a22, _var, _c2); + // c3 = a3 ^ a8 ^ a13 ^ a18 ^ a23; + _xor5(state, _a3, _a8, _a13, _a18, _a23, _var, _c3); + // c4 = a4 ^ a9 ^ a14 ^ a19 ^ a24; + _xor5(state, _a4, _a9, _a14, _a19, _a24, _var, _c4); + + // ---- Theta + Rho + Pi ---- + // d = c4 ^ _rotl(c1, 1); + _rotl(1, _var, _c1, _var, _d); + _xor(_var, _c4, _var, _d, _var, _d); + // b0 = d ^ a0; + _xor(_var, _d, state, _a0, _var, _b0); + // b16 = _rotl(d ^ a5, _rot01); + _xor(_var, _d, state, _a5, _var, _b16); + _rotl(_rot01, _var, _b16, _var, _b16); + // b7 = _rotl(d ^ a10, _rot02); + _xor(_var, _d, state, _a10, _var, _b7); + _rotl(_rot02, _var, _b7, _var, _b7); + // b23 = _rotl(d ^ a15, _rot03); + _xor(_var, _d, state, _a15, _var, _b23); + _rotl(_rot03, _var, _b23, _var, _b23); + // b14 = _rotl(d ^ a20, _rot04); + _xor(_var, _d, state, _a20, _var, _b14); + _rotl(_rot04, _var, _b14, _var, _b14); + + // d = c0 ^ _rotl(c2, 1); + _rotl(1, _var, _c2, _var, _d); + _xor(_var, _c0, _var, _d, _var, _d); + // b10 = _rotl(d ^ a1, _rot05); + _xor(_var, _d, state, _a1, _var, _b10); + _rotl(_rot05, _var, _b10, _var, _b10); + // b1 = _rotl(d ^ a6, _rot06); + _xor(_var, _d, state, _a6, _var, _b1); + _rotl(_rot06, _var, _b1, _var, _b1); + // b17 = _rotl(d ^ a11, _rot07); + _xor(_var, _d, state, _a11, _var, _b17); + _rotl(_rot07, _var, _b17, _var, _b17); + // b8 = _rotl(d ^ a16, _rot08); + _xor(_var, _d, state, _a16, _var, _b8); + _rotl(_rot08, _var, _b8, _var, _b8); + // b24 = _rotl(d ^ a21, _rot09); + _xor(_var, _d, state, _a21, _var, _b24); + _rotl(_rot09, _var, _b24, _var, _b24); + + // d = c1 ^ _rotl(c3, 1); + _rotl(1, _var, _c3, _var, _d); + _xor(_var, _d, _var, _c1, _var, _d); + // b20 = _rotl(d ^ a2, _rot10); + _xor(_var, _d, state, _a2, _var, _b20); + _rotl(_rot10, _var, _b20, _var, _b20); + // b11 = _rotl(d ^ a7, _rot11); + _xor(_var, _d, state, _a7, _var, _b11); + _rotl(_rot11, _var, _b11, _var, _b11); + // b2 = _rotl(d ^ a12, _rot12); + _xor(_var, _d, state, _a12, _var, _b2); + _rotl(_rot12, _var, _b2, _var, _b2); + // b18 = _rotl(d ^ a17, _rot13); + _xor(_var, _d, state, _a17, _var, _b18); + _rotl(_rot13, _var, _b18, _var, _b18); + // b9 = _rotl(d ^ a22, _rot14); + _xor(_var, _d, state, _a22, _var, _b9); + _rotl(_rot14, _var, _b9, _var, _b9); + + // d = c2 ^ _rotl(c4, 1); + _rotl(1, _var, _c4, _var, _d); + _xor(_var, _c2, _var, _d, _var, _d); + // b5 = _rotl(d ^ a3, _rot15); + _xor(_var, _d, state, _a3, _var, _b5); + _rotl(_rot15, _var, _b5, _var, _b5); + // b21 = _rotl(d ^ a8, _rot16); + _xor(_var, _d, state, _a8, _var, _b21); + _rotl(_rot16, _var, _b21, _var, _b21); + // b12 = _rotl(d ^ a13, _rot17); + _xor(_var, _d, state, _a13, _var, _b12); + _rotl(_rot17, _var, _b12, _var, _b12); + // b3 = _rotl(d ^ a18, _rot18); + _xor(_var, _d, state, _a18, _var, _b3); + _rotl(_rot18, _var, _b3, _var, _b3); + // b19 = _rotl(d ^ a23, _rot19); + _xor(_var, _d, state, _a23, _var, _b19); + _rotl(_rot19, _var, _b19, _var, _b19); + + // d = c3 ^ _rotl(c0, 1); + _rotl(1, _var, _c0, _var, _d); + _xor(_var, _c3, _var, _d, _var, _d); + // b15 = _rotl(d ^ a4, _rot20); + _xor(_var, _d, state, _a4, _var, _b15); + _rotl(_rot20, _var, _b15, _var, _b15); + // b6 = _rotl(d ^ a9, _rot21); + _xor(_var, _d, state, _a9, _var, _b6); + _rotl(_rot21, _var, _b6, _var, _b6); + // b22 = _rotl(d ^ a14, _rot22); + _xor(_var, _d, state, _a14, _var, _b22); + _rotl(_rot22, _var, _b22, _var, _b22); + // b13 = _rotl(d ^ a19, _rot23); + _xor(_var, _d, state, _a19, _var, _b13); + _rotl(_rot23, _var, _b13, _var, _b13); + // b4 = _rotl(d ^ a24, _rot24); + _xor(_var, _d, state, _a24, _var, _b4); + _rotl(_rot24, _var, _b4, _var, _b4); + + // ---- Chi + Iota ---- + // a0 = b0 ^ (~b1 & b2) ^ r; + _chi(_var, _b0, _b1, _b2, state, _a0); + _xor(state, _a0, _rc, r, state, _a0); + // a1 = b1 ^ (~b2 & b3); + _chi(_var, _b1, _b2, _b3, state, _a1); + // a2 = b2 ^ (~b3 & b4); + _chi(_var, _b2, _b3, _b4, state, _a2); + // a3 = b3 ^ (~b4 & b0); + _chi(_var, _b3, _b4, _b0, state, _a3); + // a4 = b4 ^ (~b0 & b1); + _chi(_var, _b4, _b0, _b1, state, _a4); + + // a5 = b5 ^ (~b6 & b7); + _chi(_var, _b5, _b6, _b7, state, _a5); + // a6 = b6 ^ (~b7 & b8); + _chi(_var, _b6, _b7, _b8, state, _a6); + // a7 = b7 ^ (~b8 & b9); + _chi(_var, _b7, _b8, _b9, state, _a7); + // a8 = b8 ^ (~b9 & b5); + _chi(_var, _b8, _b9, _b5, state, _a8); + // a9 = b9 ^ (~b5 & b6); + _chi(_var, _b9, _b5, _b6, state, _a9); + + // a10 = b10 ^ (~b11 & b12); + _chi(_var, _b10, _b11, _b12, state, _a10); + // a11 = b11 ^ (~b12 & b13); + _chi(_var, _b11, _b12, _b13, state, _a11); + // a12 = b12 ^ (~b13 & b14); + _chi(_var, _b12, _b13, _b14, state, _a12); + // a13 = b13 ^ (~b14 & b10); + _chi(_var, _b13, _b14, _b10, state, _a13); + // a14 = b14 ^ (~b10 & b11); + _chi(_var, _b14, _b10, _b11, state, _a14); + + // a15 = b15 ^ (~b16 & b17); + _chi(_var, _b15, _b16, _b17, state, _a15); + // a16 = b16 ^ (~b17 & b18); + _chi(_var, _b16, _b17, _b18, state, _a16); + // a17 = b17 ^ (~b18 & b19); + _chi(_var, _b17, _b18, _b19, state, _a17); + // a18 = b18 ^ (~b19 & b15); + _chi(_var, _b18, _b19, _b15, state, _a18); + // a19 = b19 ^ (~b15 & b16); + _chi(_var, _b19, _b15, _b16, state, _a19); + + // a20 = b20 ^ (~b21 & b22); + _chi(_var, _b20, _b21, _b22, state, _a20); + // a21 = b21 ^ (~b22 & b23); + _chi(_var, _b21, _b22, _b23, state, _a21); + // a22 = b22 ^ (~b23 & b24); + _chi(_var, _b22, _b23, _b24, state, _a22); + // a23 = b23 ^ (~b24 & b20); + _chi(_var, _b23, _b24, _b20, state, _a23); + // a24 = b24 ^ (~b20 & b21); + _chi(_var, _b24, _b20, _b21, state, _a24); + } + } + + @override + Uint8List $finalize() { + // Update the final block + if (pos == blockLength) { + $update(); + pos = 0; + } + + // Setting the signature bytes + buffer[pos] ^= paddingByte; + buffer[blockLength - 1] ^= 0x80; + $update(); + + if (hashLength <= stateSize) { + return buffer.sublist(0, hashLength); + } + + // sponge construction + var bytes = Uint8List(hashLength); + for (int i = 0, j = 0; i < hashLength; i++, j++) { + if (j == blockLength) { + $update(); + j = 0; + } + bytes[i] = buffer[j]; + } + return bytes; + } +} diff --git a/hashlib/lib/src/algorithms/keccak/keccak_64bit.dart b/hashlib/lib/src/algorithms/keccak/keccak_64bit.dart new file mode 100644 index 0000000..74c1ad2 --- /dev/null +++ b/hashlib/lib/src/algorithms/keccak/keccak_64bit.dart @@ -0,0 +1,282 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +// Rotation constants +const int _rot01 = 36; +const int _rot02 = 3; +const int _rot03 = 41; +const int _rot04 = 18; +const int _rot05 = 1; +const int _rot06 = 44; +const int _rot07 = 10; +const int _rot08 = 45; +const int _rot09 = 2; +const int _rot10 = 62; +const int _rot11 = 6; +const int _rot12 = 43; +const int _rot13 = 15; +const int _rot14 = 61; +const int _rot15 = 28; +const int _rot16 = 55; +const int _rot17 = 25; +const int _rot18 = 21; +const int _rot19 = 56; +const int _rot20 = 27; +const int _rot21 = 20; +const int _rot22 = 39; +const int _rot23 = 8; +const int _rot24 = 14; + +// 200-bit round constants iota mapping +const List _rc = [ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808a, + 0x8000000080008000, + 0x000000000000808b, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008a, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000a, + 0x000000008000808b, + 0x800000000000008b, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800a, + 0x800000008000000a, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +]; + +/// This is an implementation of Keccak-f\[1600\] derived from +/// [FIPS-202 SHA-3 Standard][fips202] published by NIST. +/// +/// Followed the optimizations in [PyCryptodome's implementation][keccak]. +/// Special thanks to [tiny_sha3] for readable code and test cases. +/// +/// It uses 64-bit integer operations internally which is not supported by +/// Web VM, but a lot faster. +/// +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +/// [keccak]: https://github.com/Legrandin/pycryptodome/blob/master/src/keccak.c +/// [tiny_sha3]: https://github.com/mjosaarinen/tiny_sha3/blob/master/sha3.c +class KeccakHash extends BlockHashSink { + final int stateSize; + final int paddingByte; + late final Uint64List qstate = Uint64List.view(buffer.buffer); + + @override + final int hashLength; + + KeccakHash({ + required this.stateSize, + required this.paddingByte, + int? outputSize, // equals to state size if not provided + }) : assert(stateSize >= 0 && stateSize < 100), + hashLength = outputSize ?? stateSize, + super( + 200 - (stateSize << 1), // rate as blockLength + bufferLength: 200, // 1600-bit state as buffer + ); + + @override + void reset() { + buffer.fillRange(0, buffer.length, 0); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] ^= chunk[start]; + } + if (pos == blockLength) { + $update(); + pos = 0; + } + } + + @override + Uint8List $finalize() { + // Setting the signature bytes + buffer[pos] ^= paddingByte; + buffer[blockLength - 1] ^= 0x80; + $update(); + + if (hashLength <= stateSize) { + return buffer.sublist(0, hashLength); + } + + // sponge construction + var bytes = Uint8List(hashLength); + for (int i = 0, j = 0; i < hashLength; i++, j++) { + if (j == blockLength) { + $update(); + j = 0; + } + bytes[i] = buffer[j]; + } + return bytes; + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + // Use variables to avoid index processing + int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; + int a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24; + + int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12; + int b13, b14, b15, b16, b17, b18, b19, b20, b21, b22, b23, b24; + + int c0, c1, c2, c3, c4, d, r; + + // Prepare the state (little-endian) + a0 = qstate[0]; + a1 = qstate[1]; + a2 = qstate[2]; + a3 = qstate[3]; + a4 = qstate[4]; + a5 = qstate[5]; + a6 = qstate[6]; + a7 = qstate[7]; + a8 = qstate[8]; + a9 = qstate[9]; + a10 = qstate[10]; + a11 = qstate[11]; + a12 = qstate[12]; + a13 = qstate[13]; + a14 = qstate[14]; + a15 = qstate[15]; + a16 = qstate[16]; + a17 = qstate[17]; + a18 = qstate[18]; + a19 = qstate[19]; + a20 = qstate[20]; + a21 = qstate[21]; + a22 = qstate[22]; + a23 = qstate[23]; + a24 = qstate[24]; + + for (r in _rc) { + // ---- Theta parity ---- + c0 = a0 ^ a5 ^ a10 ^ a15 ^ a20; + c1 = a1 ^ a6 ^ a11 ^ a16 ^ a21; + c2 = a2 ^ a7 ^ a12 ^ a17 ^ a22; + c3 = a3 ^ a8 ^ a13 ^ a18 ^ a23; + c4 = a4 ^ a9 ^ a14 ^ a19 ^ a24; + + // ---- Theta + Rho + Pi ---- + d = c4 ^ _rotl(c1, 1); + b0 = d ^ a0; + b16 = _rotl(d ^ a5, _rot01); + b7 = _rotl(d ^ a10, _rot02); + b23 = _rotl(d ^ a15, _rot03); + b14 = _rotl(d ^ a20, _rot04); + + d = c0 ^ _rotl(c2, 1); + b10 = _rotl(d ^ a1, _rot05); + b1 = _rotl(d ^ a6, _rot06); + b17 = _rotl(d ^ a11, _rot07); + b8 = _rotl(d ^ a16, _rot08); + b24 = _rotl(d ^ a21, _rot09); + + d = c1 ^ _rotl(c3, 1); + b20 = _rotl(d ^ a2, _rot10); + b11 = _rotl(d ^ a7, _rot11); + b2 = _rotl(d ^ a12, _rot12); + b18 = _rotl(d ^ a17, _rot13); + b9 = _rotl(d ^ a22, _rot14); + + d = c2 ^ _rotl(c4, 1); + b5 = _rotl(d ^ a3, _rot15); + b21 = _rotl(d ^ a8, _rot16); + b12 = _rotl(d ^ a13, _rot17); + b3 = _rotl(d ^ a18, _rot18); + b19 = _rotl(d ^ a23, _rot19); + + d = c3 ^ _rotl(c0, 1); + b15 = _rotl(d ^ a4, _rot20); + b6 = _rotl(d ^ a9, _rot21); + b22 = _rotl(d ^ a14, _rot22); + b13 = _rotl(d ^ a19, _rot23); + b4 = _rotl(d ^ a24, _rot24); + + // ---- Chi + Iota ---- + a0 = b0 ^ ((~b1) & b2) ^ r; + a1 = b1 ^ ((~b2) & b3); + a2 = b2 ^ ((~b3) & b4); + a3 = b3 ^ ((~b4) & b0); + a4 = b4 ^ ((~b0) & b1); + + a5 = b5 ^ ((~b6) & b7); + a6 = b6 ^ ((~b7) & b8); + a7 = b7 ^ ((~b8) & b9); + a8 = b8 ^ ((~b9) & b5); + a9 = b9 ^ ((~b5) & b6); + + a10 = b10 ^ ((~b11) & b12); + a11 = b11 ^ ((~b12) & b13); + a12 = b12 ^ ((~b13) & b14); + a13 = b13 ^ ((~b14) & b10); + a14 = b14 ^ ((~b10) & b11); + + a15 = b15 ^ ((~b16) & b17); + a16 = b16 ^ ((~b17) & b18); + a17 = b17 ^ ((~b18) & b19); + a18 = b18 ^ ((~b19) & b15); + a19 = b19 ^ ((~b15) & b16); + + a20 = b20 ^ ((~b21) & b22); + a21 = b21 ^ ((~b22) & b23); + a22 = b22 ^ ((~b23) & b24); + a23 = b23 ^ ((~b24) & b20); + a24 = b24 ^ ((~b20) & b21); + } + + // Save the state (little-endian) + qstate[0] = a0; + qstate[1] = a1; + qstate[2] = a2; + qstate[3] = a3; + qstate[4] = a4; + qstate[5] = a5; + qstate[6] = a6; + qstate[7] = a7; + qstate[8] = a8; + qstate[9] = a9; + qstate[10] = a10; + qstate[11] = a11; + qstate[12] = a12; + qstate[13] = a13; + qstate[14] = a14; + qstate[15] = a15; + qstate[16] = a16; + qstate[17] = a17; + qstate[18] = a18; + qstate[19] = a19; + qstate[20] = a20; + qstate[21] = a21; + qstate[22] = a22; + qstate[23] = a23; + qstate[24] = a24; + } + + /// Rotates 64-bit number x by n bits + @pragma('vm:prefer-inline') + static int _rotl(int x, int n) => (x << n) ^ (x >>> (64 - n)); +} diff --git a/hashlib/lib/src/algorithms/md2.dart b/hashlib/lib/src/algorithms/md2.dart new file mode 100644 index 0000000..9c40224 --- /dev/null +++ b/hashlib/lib/src/algorithms/md2.dart @@ -0,0 +1,119 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +/// Permutation of 0..255 constructed from the digits of pi. It gives a +/// "random" nonlinear byte substitution operation. +const _pi = [ + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, // + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +]; + +const _padding = >[ + [], + [01], + [02, 02], + [03, 03, 03], + [04, 04, 04, 04], + [05, 05, 05, 05, 05], + [06, 06, 06, 06, 06, 06], + [07, 07, 07, 07, 07, 07, 07], + [08, 08, 08, 08, 08, 08, 08, 08], + [09, 09, 09, 09, 09, 09, 09, 09, 09], + [10, 10, 10, 10, 10, 10, 10, 10, 10, 10], + [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11], + [12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + [13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13], + [14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14], + [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15], + [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], +]; + +/// This implementation is derived from the RSA Laboratories' +/// [The MD2 Message-Digest Algorithm][rfc1319]. +/// +/// [rfc1319]: https://www.ietf.org/rfc/rfc1319.html +class MD2Hash extends BlockHashSink { + final state = Uint8List(48); + final checksum = Uint8List(16); + + @override + final int hashLength; + + MD2Hash() + : hashLength = 128 >>> 3, + super(16); + + @override + void reset() { + state.fillRange(0, 16, 0); + checksum.fillRange(0, 16, 0); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @override + void $update(List block, [int offset = 0, bool last = false]) { + int i, j, t; + for (i = 0; i < 16; i++) { + state[16 + i] = block[i]; + state[32 + i] = block[i] ^ state[i]; + } + t = 0; + for (i = 0; i < 18; i++) { + for (j = 0; j < 48; ++j) { + t = state[j] ^= _pi[t]; + } + t = (t + i) & 0xFF; + } + t = checksum[15]; + for (i = 0; i < 16; i++) { + t = checksum[i] ^= _pi[block[i] ^ t]; + } + } + + @override + Uint8List $finalize() { + // add padding + $process(_padding[blockLength - pos], 0, blockLength - pos); + + // process checksum + $update(checksum); + + // Convert the state to 8-bit byte array + return state.sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/md4.dart b/hashlib/lib/src/algorithms/md4.dart new file mode 100644 index 0000000..faf2d26 --- /dev/null +++ b/hashlib/lib/src/algorithms/md4.dart @@ -0,0 +1,142 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, // a + 0xEFCDAB89, // b + 0x98BADCFE, // c + 0x10325476, // d +]; + +/// Shift constants +const _rc = [ + 03, 07, 11, 19, 03, 07, 11, 19, 03, 07, 11, 19, 03, 07, 11, 19, // + 03, 05, 09, 13, 03, 05, 09, 13, 03, 05, 09, 13, 03, 05, 09, 13, // + 03, 09, 11, 15, 03, 09, 11, 15, 03, 09, 11, 15, 03, 09, 11, 15, +]; + +/// This implementation is derived from the RSA Data Security, Inc. +/// [MD4 Message-Digest Algorithm][rfc1320]. +/// +/// [rfc1320]: https://www.ietf.org/rfc/rfc1320.html +class MD4Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + MD4Hash() + : state = Uint32List.fromList(_iv), + hashLength = 128 >>> 3, + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, e, f, g, h, t; + var x = sbuffer; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + + for (int i = 0; i < 16; i++) { + e = (b & c) | ((~b & _mask32) & d); + f = i; + t = d; + d = c; + c = b; + g = (a + e + x[f]) & _mask32; + h = _rc[i]; + b = ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + for (int i = 16; i < 32; i++) { + e = (b & c) | (b & d) | (c & d); + f = ((i >>> 2) & 3) + ((i & 3) << 2); + t = d; + d = c; + c = b; + g = (a + e + 0x5a827999 + x[f]) & _mask32; + h = _rc[i]; + b = ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + for (int i = 32; i < 48; i++) { + e = b ^ c ^ d; + f = ((i & 1) << 3) | ((i & 2) << 1) | ((i >>> 1) & 2) | ((i >>> 3) & 1); + t = d; + d = c; + c = b; + g = (a + e + 0x6ed9eba1 + x[f]) & _mask32; + h = _rc[i]; + b = ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits, Endian.little); + bdata.setUint32(60, messageLengthInBits >>> 32, Endian.little); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/md5.dart b/hashlib/lib/src/algorithms/md5.dart new file mode 100644 index 0000000..685b0a6 --- /dev/null +++ b/hashlib/lib/src/algorithms/md5.dart @@ -0,0 +1,175 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, // a + 0xEFCDAB89, // b + 0x98BADCFE, // c + 0x10325476, // d +]; + +/// 64 constants [Formula: floor(2^32 * abs(sin(i + 1)))] +const _k = [ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, // + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 +]; + +/// Shift constants +const _rc = [ + 07, 12, 17, 22, 07, 12, 17, 22, 07, 12, 17, 22, 07, 12, 17, 22, // + 05, 09, 14, 20, 05, 09, 14, 20, 05, 09, 14, 20, 05, 09, 14, 20, // + 04, 11, 16, 23, 04, 11, 16, 23, 04, 11, 16, 23, 04, 11, 16, 23, // + 06, 10, 15, 21, 06, 10, 15, 21, 06, 10, 15, 21, 06, 10, 15, 21, +]; + +/// This implementation is derived from the RSA Data Security, Inc. +/// [MD5 Message-Digest Algorithm][rfc1321]. +/// +/// [rfc1321]: https://www.ietf.org/rfc/rfc1321.html +class MD5Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + MD5Hash() + : state = Uint32List.fromList(_iv), + hashLength = 128 >>> 3, + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, e, f, g, h, t; + var x = sbuffer; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + + for (int i = 0; i < 16; i++) { + e = (b & c) | ((~b & _mask32) & d); + f = i; + t = d; + d = c; + c = b; + g = (a + e + _k[i] + x[f]) & _mask32; + h = _rc[i]; + b += ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + for (int i = 16; i < 32; i++) { + e = (d & b) | ((~d & _mask32) & c); + f = ((i << 2) + i + 1) & 15; + t = d; + d = c; + c = b; + g = (a + e + _k[i] + x[f]) & _mask32; + h = _rc[i]; + b += ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + for (int i = 32; i < 48; i++) { + e = b ^ c ^ d; + f = ((i << 1) + i + 5) & 15; + t = d; + d = c; + c = b; + g = (a + e + _k[i] + x[f]) & _mask32; + h = _rc[i]; + b += ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + for (int i = 48; i < 64; i++) { + e = c ^ (b | (~d & _mask32)); + f = ((i << 3) - i) & 15; + t = d; + d = c; + c = b; + g = (a + e + _k[i] + x[f]) & _mask32; + h = _rc[i]; + b += ((g << h) & _mask32) | (g >>> (32 - h)); + a = t; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits, Endian.little); + bdata.setUint32(60, messageLengthInBits >>> 32, Endian.little); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/pbkdf2/pbkdf2.dart b/hashlib/lib/src/algorithms/pbkdf2/pbkdf2.dart new file mode 100644 index 0000000..3423ffb --- /dev/null +++ b/hashlib/lib/src/algorithms/pbkdf2/pbkdf2.dart @@ -0,0 +1,137 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/hash_digest.dart'; +import 'package:hashlib/src/core/kdf_base.dart'; +import 'package:hashlib/src/core/mac_base.dart'; +import 'package:hashlib/src/random.dart'; + +import 'security.dart'; + +int _defaultKeyLength = 24; +int _defaultSaltLength = 16; + +/// This is an implementation of Password Based Key Derivation Algorithm, +/// PBKDF2 derived from [RFC-8081][rfc], which internally uses a MAC based +/// Pseudo Random Function (PRF) for key derivation. +/// +/// PBKDF2 is part of Public-Key Cryptography Standards (PKCS) series published +/// by the RSA Laboratories, specifically PKCS #5 v2.0. It supersedes PBKDF1, +/// which could only produce derived keys up to 160 bits long. +/// +/// The strength of the generated password using PBKDF2 depends on the number +/// of iterations. The idea is to prevent a brute force attack on the original +/// password by making the key derivation time long. This implementation can be +/// used for both to [convert] a passphrase and [verify] it with a derived key. +/// +/// [rfc]: https://www.rfc-editor.org/rfc/rfc8018.html#section-5.2 +class PBKDF2 extends KeyDerivatorBase { + @override + String get name => '${algo.name}/PBKDF2'; + + /// The underlying algorithm used as Pseudo Random Function (PRF) + final MACHash algo; + + /// The byte array containing salt + final List salt; + + /// The number of iterations + final int iterations; + + @override + final int derivedKeyLength; + + const PBKDF2._({ + required this.algo, + required this.salt, + required this.iterations, + required this.derivedKeyLength, + }); + + /// Create a [PBKDF2] instance with a MAC instance. + factory PBKDF2( + MACHash mac, + int iterations, { + List? salt, + int? keyLength, + }) { + keyLength ??= _defaultKeyLength; + salt ??= randomBytes(_defaultSaltLength); + + // validate parameters + if (iterations < 1) { + throw StateError('The iterations must be at least 1'); + } + if (iterations > 0x7FFFFFFF) { + throw StateError('The iterations must be less than 2^31'); + } + if (keyLength < 1) { + throw StateError('The keyLength must be at least 1'); + } + + // create instance + return PBKDF2._( + algo: mac, + salt: salt, + iterations: iterations, + derivedKeyLength: keyLength, + ); + } + + /// Create a [PBKDF2] instance from [PBKDF2Security]. + factory PBKDF2.fromSecurity( + PBKDF2Security security, { + List? salt, + MACHash? mac, + int? iterations, + int? keyLength, + }) => + PBKDF2( + mac ?? security.mac, + iterations ?? security.c, + keyLength: keyLength ?? security.dklen, + salt: salt, + ); + + @override + HashDigest convert(List password) { + int i, j, k, t; + Uint8List hash, block; + var result = Uint8List(derivedKeyLength); + + // Initialize the MAC with provided password + var sink = algo.by(password).createSink(); + + k = 0; + for (i = 1; k < derivedKeyLength; i++) { + // Generate the first HMAC: U_1 + sink.reset(); + sink.add(salt); + sink.add([i >>> 24, i >>> 16, i >>> 8, i]); + hash = sink.digest().bytes; + + // For storing the combined XORs + block = hash; + + // Subsequence HMAC generation: U_2 .. U_c + for (t = 1; t < iterations; ++t) { + sink.reset(); + sink.add(hash); + hash = sink.digest().bytes; + + for (j = 0; j < hash.length; ++j) { + block[j] ^= hash[j]; + } + } + + // Append the hash to the result + for (j = 0; j < hash.length && k < derivedKeyLength; ++j, ++k) { + result[k] = block[j]; + } + } + + return HashDigest(result); + } +} diff --git a/hashlib/lib/src/algorithms/pbkdf2/security.dart b/hashlib/lib/src/algorithms/pbkdf2/security.dart new file mode 100644 index 0000000..dc77715 --- /dev/null +++ b/hashlib/lib/src/algorithms/pbkdf2/security.dart @@ -0,0 +1,90 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/core/mac_base.dart'; +import 'package:hashlib/src/hmac.dart'; +import 'package:hashlib/src/md5.dart'; +import 'package:hashlib/src/sha1.dart'; +import 'package:hashlib/src/sha256.dart'; +import 'package:hashlib/src/sha3_256.dart'; +import 'package:hashlib/src/sha512.dart'; + +import 'pbkdf2.dart'; + +/// This contains some recommended parameters for [PBKDF2] algorithm. +class PBKDF2Security { + final String name; + + /// The number of iterations + final int c; + + /// The length of the derived key + final int dklen; + + /// The underlying algorithm + final MACHash mac; + + const PBKDF2Security( + this.name, { + required this.c, + required this.mac, + required this.dklen, + }); + + /// Provides a very low security. Use it only for test purposes. + /// + /// It uses MD5/HMAC algorithm with a cost of 10. + /// + /// **WARNING: Not recommended for general use.** + static const test = PBKDF2Security('test', mac: HMAC(md5), c: 10, dklen: 16); + + /// Provides low security. Can be used on low-end devices. + /// + /// It uses SHA3-256/HMAC algorithm with 100 iterations. + /// + /// **WARNING: Not recommended for general use.** + static const little = + PBKDF2Security('little', mac: HMAC(sha3_256), c: 100, dklen: 32); + + /// Provides moderate security. + /// + /// It uses SHA-256/HMAC algorithm with 3,000 iterations. + static const moderate = + PBKDF2Security('moderate', mac: hmac_sha256, c: 3000, dklen: 32); + + /// Provides good security. + /// + /// It uses SHA-256/HMAC algorithm with 50,000 iterations. + static const good = + PBKDF2Security('good', mac: hmac_sha256, c: 50000, dklen: 64); + + /// Provides strong security. It uses similar parameters as [owasp2]. + /// + /// It uses SHA-256/HMAC algorithm with 600,000 iterations. + static const strong = + PBKDF2Security('strong', mac: HMAC(sha256), c: 600000, dklen: 64); + + /// Provides strong security recommended by [OWASP][link]. + /// + /// It uses SHA1/HMAC algorithm with 1,300,000 iterations. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp = + PBKDF2Security('owasp1', mac: HMAC(sha1), c: 1300000, dklen: 32); + + /// Provides strong security recommended by [OWASP][link]. + /// + /// It uses SHA-256/HMAC algorithm with 600,000 iterations. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp2 = + PBKDF2Security('owasp2', mac: HMAC(sha256), c: 600000, dklen: 64); + + /// Provides strong security recommended by [OWASP][link]. + /// + /// It uses SHA-512/HMAC algorithm with 210,000 iterations. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp3 = + PBKDF2Security('owasp3', mac: HMAC(sha512), c: 210000, dklen: 64); +} diff --git a/hashlib/lib/src/algorithms/poly1305/poly1305_32bit.dart b/hashlib/lib/src/algorithms/poly1305/poly1305_32bit.dart new file mode 100644 index 0000000..d193708 --- /dev/null +++ b/hashlib/lib/src/algorithms/poly1305/poly1305_32bit.dart @@ -0,0 +1,105 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +const List _clamp = [ + 0xff, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, // + 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, +]; + +/// This implementation is derived from the [The Poly1305 Algorithms] described +/// in the [ChaCha20 and Poly1305 for IETF Protocols][rfc8439] document. +/// +/// [rfc8439]: https://www.ietf.org/rfc/rfc8439.html +class Poly1305Sink extends BlockHashSink implements MACSinkBase { + BigInt _n = BigInt.zero; + BigInt _r = BigInt.zero; + BigInt _s = BigInt.zero; + BigInt _h = BigInt.zero; + final BigInt _m = BigInt.two.pow(128); + final BigInt _p = BigInt.two.pow(130) - BigInt.from(5); + + @override + final int hashLength = 16; + + @override + final int derivedKeyLength = 16; + + /// Creates a new instance to process 16-bytes blocks with 17-bytes buffer + /// + /// Parameters: + /// - [key] : The key-pair (`r`, `s`) - 16 or 32-bytes. + Poly1305Sink(Uint8List key) : super(16, bufferLength: 17) { + if (key.length != 16 && key.length != 32) { + throw ArgumentError('The key length must be either 16 or 32 bytes'); + } + + int i; + _r = BigInt.zero; + for (i = 15; i >= 0; i--) { + _r <<= 8; + _r += BigInt.from(key[i] & _clamp[i]); + } + + if (key.length == 32) { + _s = BigInt.zero; + for (i = 31; i >= 16; i--) { + _s <<= 8; + _s += BigInt.from(key[i]); + } + } + } + + @override + void reset() { + _n = BigInt.zero; + _h = BigInt.zero; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + for (; start < end; start++, pos++) { + if (pos == blockLength) { + _n += BigInt.one << 128; + $update(); + _n = BigInt.zero; + pos = 0; + } + _n += BigInt.from(chunk[start]) << (pos << 3); + } + if (pos == blockLength) { + _n += BigInt.one << 128; + $update(); + _n = BigInt.zero; + pos = 0; + } + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + _h = ((_h + _n) * _r) % _p; + } + + @override + Uint8List $finalize() { + if (pos > 0) { + _n += BigInt.one << (pos << 3); + $update(); + } + + _h += _s; + + var result = Uint32List.fromList([ + (_h % _m).toUnsigned(32).toInt(), + ((_h >> 32) % _m).toUnsigned(32).toInt(), + ((_h >> 64) % _m).toUnsigned(32).toInt(), + ((_h >> 96) % _m).toUnsigned(32).toInt(), + ]); + return Uint8List.view(result.buffer); + } +} diff --git a/hashlib/lib/src/algorithms/poly1305/poly1305_64bit.dart b/hashlib/lib/src/algorithms/poly1305/poly1305_64bit.dart new file mode 100644 index 0000000..077b0dd --- /dev/null +++ b/hashlib/lib/src/algorithms/poly1305/poly1305_64bit.dart @@ -0,0 +1,220 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +const int _mask32 = 0xFFFFFFFF; +const int _mask26 = 0x03FFFFFF; + +/// This implementation is derived from the [The Poly1305 Algorithms][pdf] +/// described in the [ChaCha20 and Poly1305 for IETF Protocols][rfc] document. +/// +/// The Reference implementation used for optimization: +/// https://github.com/floodyberry/poly1305-opt +/// +/// [rfc]: https://www.ietf.org/rfc/rfc8439.html +/// [pdf]: https://cr.yp.to/mac/poly1305-20050329.pdf +class Poly1305Sink extends BlockHashSink implements MACSinkBase { + // secret key: r + int _r0 = 0; + int _r1 = 0; + int _r2 = 0; + int _r3 = 0; + int _r4 = 0; + // authentication key: s + int _s0 = 0; + int _s1 = 0; + int _s2 = 0; + int _s3 = 0; + // accumulator: a + int _h0 = 0; + int _h1 = 0; + int _h2 = 0; + int _h3 = 0; + int _h4 = 0; + // g = 5 * r + int _g1 = 0; + int _g2 = 0; + int _g3 = 0; + int _g4 = 0; + + @override + final int hashLength = 16; + + @override + final int derivedKeyLength = 16; + + /// Creates a new instance to process 16-bytes blocks with 17-bytes buffer + /// + /// Parameters: + /// - [key] : The key-pair (`r`, `s`) - 16 or 32-bytes. + Poly1305Sink(Uint8List key) : super(16, bufferLength: 17) { + if (key.length != 16 && key.length != 32) { + throw ArgumentError('The key length must be either 16 or 32 bytes'); + } + + // r = key[15..0] + _r0 = key[0] | (key[1] << 8) | (key[2] << 16) | (key[3] << 24); + _r1 = (key[3] >>> 2) | (key[4] << 6) | (key[5] << 14) | (key[6] << 22); + _r2 = (key[6] >>> 4) | (key[7] << 4) | (key[8] << 12) | (key[9] << 20); + _r3 = (key[9] >>> 6) | (key[10] << 2) | (key[11] << 10) | (key[12] << 18); + _r4 = key[13] | (key[14] << 8) | (key[15] << 16); + + // clamp(r): r &= 0x0ffffffc0ffffffc0ffffffc0fffffff + _r0 &= 0x03ffffff; + _r1 &= 0x03ffff03; + _r2 &= 0x03ffc0ff; + _r3 &= 0x03f03fff; + _r4 &= 0x000fffff; + + _g1 = 5 * _r1; + _g2 = 5 * _r2; + _g3 = 5 * _r3; + _g4 = 5 * _r4; + + if (key.length == 32) { + // s = key[31..16] + _s0 = key[16] | (key[17] << 8) | (key[18] << 16) | (key[19] << 24); + _s1 = key[20] | (key[21] << 8) | (key[22] << 16) | (key[23] << 24); + _s2 = key[24] | (key[25] << 8) | (key[26] << 16) | (key[27] << 24); + _s3 = key[28] | (key[29] << 8) | (key[30] << 16) | (key[31] << 24); + } + } + + @override + void reset() { + _h0 = 0; + _h1 = 0; + _h2 = 0; + _h3 = 0; + _h4 = 0; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + buffer[16] = 1; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(); + pos = 0; + } + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int d0, d1, d2, d3, d4; + + // a += n + _h0 += buffer[0] | + (buffer[1] << 8) | + (buffer[2] << 16) | + ((buffer[3] & 0x03) << 24); + _h1 += (buffer[3] >>> 2) | + (buffer[4] << 6) | + (buffer[5] << 14) | + ((buffer[6] & 0xF) << 22); + _h2 += (buffer[6] >>> 4) | + (buffer[7] << 4) | + (buffer[8] << 12) | + ((buffer[9] & 0x3F) << 20); + _h3 += (buffer[9] >>> 6) | + (buffer[10] << 2) | + (buffer[11] << 10) | + (buffer[12] << 18); + _h4 += buffer[13] | + (buffer[14] << 8) | + (buffer[15] << 16) | + ((buffer[16] & 0x03) << 24); + + // a *= r + d0 = _h0 * _r0 + _h1 * _g4 + _h2 * _g3 + _h3 * _g2 + _h4 * _g1; + d1 = _h0 * _r1 + _h1 * _r0 + _h2 * _g4 + _h3 * _g3 + _h4 * _g2; + d2 = _h0 * _r2 + _h1 * _r1 + _h2 * _r0 + _h3 * _g4 + _h4 * _g3; + d3 = _h0 * _r3 + _h1 * _r2 + _h2 * _r1 + _h3 * _r0 + _h4 * _g4; + d4 = _h0 * _r4 + _h1 * _r3 + _h2 * _r2 + _h3 * _r1 + _h4 * _r0; + + // a %= 2^130 - 5; + d1 += d0 >>> 26; + d2 += d1 >>> 26; + d3 += d2 >>> 26; + d4 += d3 >>> 26; + _h0 = d0 & _mask26; + _h1 = d1 & _mask26; + _h2 = d2 & _mask26; + _h3 = d3 & _mask26; + _h4 = d4 & _mask26; + _h0 += 5 * (d4 >>> 26); + _h1 += _h0 >>> 26; + _h0 &= _mask26; + } + + @override + Uint8List $finalize() { + if (pos > 0) { + buffer[pos] = 1; + for (pos++; pos <= 16; pos++) { + buffer[pos] = 0; + } + $update(); + } + + int d0, d1, d2, d3, d4; + + // fully carry + _h1 += _h0 >>> 26; + _h2 += _h1 >>> 26; + _h3 += _h2 >>> 26; + _h4 += _h3 >>> 26; + _h0 &= _mask26; + _h1 &= _mask26; + _h2 &= _mask26; + _h3 &= _mask26; + + // compute d = h - p + d0 = _h0 + 5; + d1 = _h1 + (d0 >>> 26); + d2 = _h2 + (d1 >>> 26); + d3 = _h3 + (d2 >>> 26); + d4 = _h4 + (d3 >>> 26) - (1 << 26); + d4 &= _mask32; + + // if h < p, take h; else, take d + if ((d4 >>> 31) != 1) { + _h0 = d0 & _mask26; + _h1 = d1 & _mask26; + _h2 = d2 & _mask26; + _h3 = d3 & _mask26; + _h4 = d4 & _mask26; + } + + // modulus 2^128 + _h0 = ((_h0) | (_h1 << 26)) & _mask32; + _h1 = ((_h1 >>> 6) | (_h2 << 20)) & _mask32; + _h2 = ((_h2 >>> 12) | (_h3 << 14)) & _mask32; + _h3 = ((_h3 >>> 18) | (_h4 << 8)) & _mask32; + + // h += s + _h0 += _s0; + _h1 += _s1 + (_h0 >>> 32); + _h2 += _s2 + (_h1 >>> 32); + _h3 += _s3 + (_h2 >>> 32); + + var result = Uint32List.fromList([ + _h0, + _h1, + _h2, + _h3, + ]); + return Uint8List.view(result.buffer); + } +} diff --git a/hashlib/lib/src/algorithms/poly1305/poly1305_sink.dart b/hashlib/lib/src/algorithms/poly1305/poly1305_sink.dart new file mode 100644 index 0000000..f4e9b1f --- /dev/null +++ b/hashlib/lib/src/algorithms/poly1305/poly1305_sink.dart @@ -0,0 +1,4 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'poly1305_64bit.dart' if (dart.library.js) 'poly1305_32bit.dart'; diff --git a/hashlib/lib/src/algorithms/ripemd/ripemd128.dart b/hashlib/lib/src/algorithms/ripemd/ripemd128.dart new file mode 100644 index 0000000..782317d --- /dev/null +++ b/hashlib/lib/src/algorithms/ripemd/ripemd128.dart @@ -0,0 +1,328 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, +]; + +/// This implementation is derived from the Bouncy Castle's implementation of +/// [RIPEMD-128][bc]. +/// +/// [bc]: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/RIPEMD128Digest.java +class RIPEMD128Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + RIPEMD128Hash() + : state = Uint32List.fromList(_iv), + hashLength = 128 >>> 3, + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + @pragma('vm:prefer-inline') + static int _f1(int x, int y, int z) => x ^ y ^ z; + + @pragma('vm:prefer-inline') + static int _f2(int x, int y, int z) => (x & y) | (((~x) & _mask32) & z); + + @pragma('vm:prefer-inline') + static int _f3(int x, int y, int z) => (x | ((~y) & _mask32)) ^ z; + + @pragma('vm:prefer-inline') + static int _f4(int x, int y, int z) => (x & z) | (y & ((~z) & _mask32)); + + @pragma('vm:prefer-inline') + static int _lr1(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f1(b, c, d) + x, s); + + @pragma('vm:prefer-inline') + static int _lr2(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f2(b, c, d) + x + 0x5a827999, s); + + @pragma('vm:prefer-inline') + static int _lr3(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f3(b, c, d) + x + 0x6ed9eba1, s); + + @pragma('vm:prefer-inline') + static int _lr4(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f4(b, c, d) + x + 0x8f1bbcdc, s); + + @pragma('vm:prefer-inline') + static int _rr1(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f1(b, c, d) + x, s); + + @pragma('vm:prefer-inline') + static int _rr2(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f2(b, c, d) + x + 0x6d703ef3, s); + + @pragma('vm:prefer-inline') + static int _rr3(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f3(b, c, d) + x + 0x5c4dd124, s); + + @pragma('vm:prefer-inline') + static int _rr4(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f4(b, c, d) + x + 0x50a28be6, s); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, aa, bb, cc, dd; + int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + a = aa = state[0]; + b = bb = state[1]; + c = cc = state[2]; + d = dd = state[3]; + + x0 = sbuffer[0]; + x1 = sbuffer[1]; + x2 = sbuffer[2]; + x3 = sbuffer[3]; + x4 = sbuffer[4]; + x5 = sbuffer[5]; + x6 = sbuffer[6]; + x7 = sbuffer[7]; + x8 = sbuffer[8]; + x9 = sbuffer[9]; + x10 = sbuffer[10]; + x11 = sbuffer[11]; + x12 = sbuffer[12]; + x13 = sbuffer[13]; + x14 = sbuffer[14]; + x15 = sbuffer[15]; + + // + // Round 1 + // + a = _lr1(a, b, c, d, x0, 11); + d = _lr1(d, a, b, c, x1, 14); + c = _lr1(c, d, a, b, x2, 15); + b = _lr1(b, c, d, a, x3, 12); + a = _lr1(a, b, c, d, x4, 5); + d = _lr1(d, a, b, c, x5, 8); + c = _lr1(c, d, a, b, x6, 7); + b = _lr1(b, c, d, a, x7, 9); + a = _lr1(a, b, c, d, x8, 11); + d = _lr1(d, a, b, c, x9, 13); + c = _lr1(c, d, a, b, x10, 14); + b = _lr1(b, c, d, a, x11, 15); + a = _lr1(a, b, c, d, x12, 6); + d = _lr1(d, a, b, c, x13, 7); + c = _lr1(c, d, a, b, x14, 9); + b = _lr1(b, c, d, a, x15, 8); + + // + // Round 2 + // + a = _lr2(a, b, c, d, x7, 7); + d = _lr2(d, a, b, c, x4, 6); + c = _lr2(c, d, a, b, x13, 8); + b = _lr2(b, c, d, a, x1, 13); + a = _lr2(a, b, c, d, x10, 11); + d = _lr2(d, a, b, c, x6, 9); + c = _lr2(c, d, a, b, x15, 7); + b = _lr2(b, c, d, a, x3, 15); + a = _lr2(a, b, c, d, x12, 7); + d = _lr2(d, a, b, c, x0, 12); + c = _lr2(c, d, a, b, x9, 15); + b = _lr2(b, c, d, a, x5, 9); + a = _lr2(a, b, c, d, x2, 11); + d = _lr2(d, a, b, c, x14, 7); + c = _lr2(c, d, a, b, x11, 13); + b = _lr2(b, c, d, a, x8, 12); + + // + // Round 3 + // + a = _lr3(a, b, c, d, x3, 11); + d = _lr3(d, a, b, c, x10, 13); + c = _lr3(c, d, a, b, x14, 6); + b = _lr3(b, c, d, a, x4, 7); + a = _lr3(a, b, c, d, x9, 14); + d = _lr3(d, a, b, c, x15, 9); + c = _lr3(c, d, a, b, x8, 13); + b = _lr3(b, c, d, a, x1, 15); + a = _lr3(a, b, c, d, x2, 14); + d = _lr3(d, a, b, c, x7, 8); + c = _lr3(c, d, a, b, x0, 13); + b = _lr3(b, c, d, a, x6, 6); + a = _lr3(a, b, c, d, x13, 5); + d = _lr3(d, a, b, c, x11, 12); + c = _lr3(c, d, a, b, x5, 7); + b = _lr3(b, c, d, a, x12, 5); + + // + // Round 4 + // + a = _lr4(a, b, c, d, x1, 11); + d = _lr4(d, a, b, c, x9, 12); + c = _lr4(c, d, a, b, x11, 14); + b = _lr4(b, c, d, a, x10, 15); + a = _lr4(a, b, c, d, x0, 14); + d = _lr4(d, a, b, c, x8, 15); + c = _lr4(c, d, a, b, x12, 9); + b = _lr4(b, c, d, a, x4, 8); + a = _lr4(a, b, c, d, x13, 9); + d = _lr4(d, a, b, c, x3, 14); + c = _lr4(c, d, a, b, x7, 5); + b = _lr4(b, c, d, a, x15, 6); + a = _lr4(a, b, c, d, x14, 8); + d = _lr4(d, a, b, c, x5, 6); + c = _lr4(c, d, a, b, x6, 5); + b = _lr4(b, c, d, a, x2, 12); + + // + // Parallel round 1 + // + aa = _rr4(aa, bb, cc, dd, x5, 8); + dd = _rr4(dd, aa, bb, cc, x14, 9); + cc = _rr4(cc, dd, aa, bb, x7, 9); + bb = _rr4(bb, cc, dd, aa, x0, 11); + aa = _rr4(aa, bb, cc, dd, x9, 13); + dd = _rr4(dd, aa, bb, cc, x2, 15); + cc = _rr4(cc, dd, aa, bb, x11, 15); + bb = _rr4(bb, cc, dd, aa, x4, 5); + aa = _rr4(aa, bb, cc, dd, x13, 7); + dd = _rr4(dd, aa, bb, cc, x6, 7); + cc = _rr4(cc, dd, aa, bb, x15, 8); + bb = _rr4(bb, cc, dd, aa, x8, 11); + aa = _rr4(aa, bb, cc, dd, x1, 14); + dd = _rr4(dd, aa, bb, cc, x10, 14); + cc = _rr4(cc, dd, aa, bb, x3, 12); + bb = _rr4(bb, cc, dd, aa, x12, 6); + + // + // Parallel round 2 + // + aa = _rr3(aa, bb, cc, dd, x6, 9); + dd = _rr3(dd, aa, bb, cc, x11, 13); + cc = _rr3(cc, dd, aa, bb, x3, 15); + bb = _rr3(bb, cc, dd, aa, x7, 7); + aa = _rr3(aa, bb, cc, dd, x0, 12); + dd = _rr3(dd, aa, bb, cc, x13, 8); + cc = _rr3(cc, dd, aa, bb, x5, 9); + bb = _rr3(bb, cc, dd, aa, x10, 11); + aa = _rr3(aa, bb, cc, dd, x14, 7); + dd = _rr3(dd, aa, bb, cc, x15, 7); + cc = _rr3(cc, dd, aa, bb, x8, 12); + bb = _rr3(bb, cc, dd, aa, x12, 7); + aa = _rr3(aa, bb, cc, dd, x4, 6); + dd = _rr3(dd, aa, bb, cc, x9, 15); + cc = _rr3(cc, dd, aa, bb, x1, 13); + bb = _rr3(bb, cc, dd, aa, x2, 11); + + // + // Parallel round 3 + // + aa = _rr2(aa, bb, cc, dd, x15, 9); + dd = _rr2(dd, aa, bb, cc, x5, 7); + cc = _rr2(cc, dd, aa, bb, x1, 15); + bb = _rr2(bb, cc, dd, aa, x3, 11); + aa = _rr2(aa, bb, cc, dd, x7, 8); + dd = _rr2(dd, aa, bb, cc, x14, 6); + cc = _rr2(cc, dd, aa, bb, x6, 6); + bb = _rr2(bb, cc, dd, aa, x9, 14); + aa = _rr2(aa, bb, cc, dd, x11, 12); + dd = _rr2(dd, aa, bb, cc, x8, 13); + cc = _rr2(cc, dd, aa, bb, x12, 5); + bb = _rr2(bb, cc, dd, aa, x2, 14); + aa = _rr2(aa, bb, cc, dd, x10, 13); + dd = _rr2(dd, aa, bb, cc, x0, 13); + cc = _rr2(cc, dd, aa, bb, x4, 7); + bb = _rr2(bb, cc, dd, aa, x13, 5); + + // + // Parallel round 4 + // + aa = _rr1(aa, bb, cc, dd, x8, 15); + dd = _rr1(dd, aa, bb, cc, x6, 5); + cc = _rr1(cc, dd, aa, bb, x4, 8); + bb = _rr1(bb, cc, dd, aa, x1, 11); + aa = _rr1(aa, bb, cc, dd, x3, 14); + dd = _rr1(dd, aa, bb, cc, x11, 14); + cc = _rr1(cc, dd, aa, bb, x15, 6); + bb = _rr1(bb, cc, dd, aa, x0, 14); + aa = _rr1(aa, bb, cc, dd, x5, 6); + dd = _rr1(dd, aa, bb, cc, x12, 9); + cc = _rr1(cc, dd, aa, bb, x2, 12); + bb = _rr1(bb, cc, dd, aa, x13, 9); + aa = _rr1(aa, bb, cc, dd, x9, 12); + dd = _rr1(dd, aa, bb, cc, x7, 5); + cc = _rr1(cc, dd, aa, bb, x10, 15); + bb = _rr1(bb, cc, dd, aa, x14, 8); + + // + // combine the results + // + dd += c + state[1]; + state[1] = state[2] + d + aa; + state[2] = state[3] + a + bb; + state[3] = state[0] + b + cc; + state[0] = dd; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits, Endian.little); + bdata.setUint32(60, messageLengthInBits >>> 32, Endian.little); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/ripemd/ripemd160.dart b/hashlib/lib/src/algorithms/ripemd/ripemd160.dart new file mode 100644 index 0000000..d5f9046 --- /dev/null +++ b/hashlib/lib/src/algorithms/ripemd/ripemd160.dart @@ -0,0 +1,494 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, + 0xc3d2e1f0, +]; + +/// This implementation is derived from the Bouncy Castle's implementation of +/// [RIPEMD-160][bc]. +/// +/// [bc]: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/RIPEMD160Digest.java +class RIPEMD160Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + RIPEMD160Hash() + : state = Uint32List.fromList(_iv), + hashLength = 160 >>> 3, + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + @pragma('vm:prefer-inline') + static int _f1(int x, int y, int z) => x ^ y ^ z; + + @pragma('vm:prefer-inline') + static int _f2(int x, int y, int z) => (x & y) | (((~x) & _mask32) & z); + + @pragma('vm:prefer-inline') + static int _f3(int x, int y, int z) => (x | ((~y) & _mask32)) ^ z; + + @pragma('vm:prefer-inline') + static int _f4(int x, int y, int z) => (x & z) | (y & ((~z) & _mask32)); + + @pragma('vm:prefer-inline') + static int _f5(int x, int y, int z) => x ^ (y | ((~z) & _mask32)); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, e, aa, bb, cc, dd, ee; + int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + a = aa = state[0]; + b = bb = state[1]; + c = cc = state[2]; + d = dd = state[3]; + e = ee = state[4]; + + x0 = sbuffer[0]; + x1 = sbuffer[1]; + x2 = sbuffer[2]; + x3 = sbuffer[3]; + x4 = sbuffer[4]; + x5 = sbuffer[5]; + x6 = sbuffer[6]; + x7 = sbuffer[7]; + x8 = sbuffer[8]; + x9 = sbuffer[9]; + x10 = sbuffer[10]; + x11 = sbuffer[11]; + x12 = sbuffer[12]; + x13 = sbuffer[13]; + x14 = sbuffer[14]; + x15 = sbuffer[15]; + + // + // Rounds 1 - 16 + // + // left + a = _rotl32(a + _f1(b, c, d) + x0, 11) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f1(a, b, c) + x1, 14) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f1(e, a, b) + x2, 15) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f1(d, e, a) + x3, 12) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f1(c, d, e) + x4, 5) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f1(b, c, d) + x5, 8) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f1(a, b, c) + x6, 7) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f1(e, a, b) + x7, 9) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f1(d, e, a) + x8, 11) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f1(c, d, e) + x9, 13) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f1(b, c, d) + x10, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f1(a, b, c) + x11, 15) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f1(e, a, b) + x12, 6) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f1(d, e, a) + x13, 7) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f1(c, d, e) + x14, 9) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f1(b, c, d) + x15, 8) + e; + c = _rotl32(c, 10); + + // right + aa = _rotl32(aa + _f5(bb, cc, dd) + x5 + 0x50a28be6, 8) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f5(aa, bb, cc) + x14 + 0x50a28be6, 9) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f5(ee, aa, bb) + x7 + 0x50a28be6, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f5(dd, ee, aa) + x0 + 0x50a28be6, 11) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f5(cc, dd, ee) + x9 + 0x50a28be6, 13) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f5(bb, cc, dd) + x2 + 0x50a28be6, 15) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f5(aa, bb, cc) + x11 + 0x50a28be6, 15) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f5(ee, aa, bb) + x4 + 0x50a28be6, 5) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f5(dd, ee, aa) + x13 + 0x50a28be6, 7) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f5(cc, dd, ee) + x6 + 0x50a28be6, 7) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f5(bb, cc, dd) + x15 + 0x50a28be6, 8) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f5(aa, bb, cc) + x8 + 0x50a28be6, 11) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f5(ee, aa, bb) + x1 + 0x50a28be6, 14) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f5(dd, ee, aa) + x10 + 0x50a28be6, 14) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f5(cc, dd, ee) + x3 + 0x50a28be6, 12) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f5(bb, cc, dd) + x12 + 0x50a28be6, 6) + ee; + cc = _rotl32(cc, 10); + + // + // Rounds 16-31 + // + // left + e = _rotl32(e + _f2(a, b, c) + x7 + 0x5a827999, 7) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f2(e, a, b) + x4 + 0x5a827999, 6) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f2(d, e, a) + x13 + 0x5a827999, 8) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f2(c, d, e) + x1 + 0x5a827999, 13) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f2(b, c, d) + x10 + 0x5a827999, 11) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f2(a, b, c) + x6 + 0x5a827999, 9) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f2(e, a, b) + x15 + 0x5a827999, 7) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f2(d, e, a) + x3 + 0x5a827999, 15) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f2(c, d, e) + x12 + 0x5a827999, 7) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f2(b, c, d) + x0 + 0x5a827999, 12) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f2(a, b, c) + x9 + 0x5a827999, 15) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f2(e, a, b) + x5 + 0x5a827999, 9) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f2(d, e, a) + x2 + 0x5a827999, 11) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f2(c, d, e) + x14 + 0x5a827999, 7) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f2(b, c, d) + x11 + 0x5a827999, 13) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f2(a, b, c) + x8 + 0x5a827999, 12) + d; + b = _rotl32(b, 10); + + // right + ee = _rotl32(ee + _f4(aa, bb, cc) + x6 + 0x5c4dd124, 9) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f4(ee, aa, bb) + x11 + 0x5c4dd124, 13) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f4(dd, ee, aa) + x3 + 0x5c4dd124, 15) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f4(cc, dd, ee) + x7 + 0x5c4dd124, 7) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f4(bb, cc, dd) + x0 + 0x5c4dd124, 12) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f4(aa, bb, cc) + x13 + 0x5c4dd124, 8) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f4(ee, aa, bb) + x5 + 0x5c4dd124, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f4(dd, ee, aa) + x10 + 0x5c4dd124, 11) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f4(cc, dd, ee) + x14 + 0x5c4dd124, 7) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f4(bb, cc, dd) + x15 + 0x5c4dd124, 7) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f4(aa, bb, cc) + x8 + 0x5c4dd124, 12) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f4(ee, aa, bb) + x12 + 0x5c4dd124, 7) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f4(dd, ee, aa) + x4 + 0x5c4dd124, 6) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f4(cc, dd, ee) + x9 + 0x5c4dd124, 15) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f4(bb, cc, dd) + x1 + 0x5c4dd124, 13) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f4(aa, bb, cc) + x2 + 0x5c4dd124, 11) + dd; + bb = _rotl32(bb, 10); + + // + // Rounds 32-47 + // + // left + d = _rotl32(d + _f3(e, a, b) + x3 + 0x6ed9eba1, 11) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f3(d, e, a) + x10 + 0x6ed9eba1, 13) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f3(c, d, e) + x14 + 0x6ed9eba1, 6) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f3(b, c, d) + x4 + 0x6ed9eba1, 7) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f3(a, b, c) + x9 + 0x6ed9eba1, 14) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f3(e, a, b) + x15 + 0x6ed9eba1, 9) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f3(d, e, a) + x8 + 0x6ed9eba1, 13) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f3(c, d, e) + x1 + 0x6ed9eba1, 15) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f3(b, c, d) + x2 + 0x6ed9eba1, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f3(a, b, c) + x7 + 0x6ed9eba1, 8) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f3(e, a, b) + x0 + 0x6ed9eba1, 13) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f3(d, e, a) + x6 + 0x6ed9eba1, 6) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f3(c, d, e) + x13 + 0x6ed9eba1, 5) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f3(b, c, d) + x11 + 0x6ed9eba1, 12) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f3(a, b, c) + x5 + 0x6ed9eba1, 7) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f3(e, a, b) + x12 + 0x6ed9eba1, 5) + c; + a = _rotl32(a, 10); + + // right + dd = _rotl32(dd + _f3(ee, aa, bb) + x15 + 0x6d703ef3, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f3(dd, ee, aa) + x5 + 0x6d703ef3, 7) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f3(cc, dd, ee) + x1 + 0x6d703ef3, 15) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f3(bb, cc, dd) + x3 + 0x6d703ef3, 11) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f3(aa, bb, cc) + x7 + 0x6d703ef3, 8) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f3(ee, aa, bb) + x14 + 0x6d703ef3, 6) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f3(dd, ee, aa) + x6 + 0x6d703ef3, 6) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f3(cc, dd, ee) + x9 + 0x6d703ef3, 14) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f3(bb, cc, dd) + x11 + 0x6d703ef3, 12) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f3(aa, bb, cc) + x8 + 0x6d703ef3, 13) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f3(ee, aa, bb) + x12 + 0x6d703ef3, 5) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f3(dd, ee, aa) + x2 + 0x6d703ef3, 14) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f3(cc, dd, ee) + x10 + 0x6d703ef3, 13) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f3(bb, cc, dd) + x0 + 0x6d703ef3, 13) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f3(aa, bb, cc) + x4 + 0x6d703ef3, 7) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f3(ee, aa, bb) + x13 + 0x6d703ef3, 5) + cc; + aa = _rotl32(aa, 10); + + // + // Rounds 48-63 + // + // left + c = _rotl32(c + _f4(d, e, a) + x1 + 0x8f1bbcdc, 11) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f4(c, d, e) + x9 + 0x8f1bbcdc, 12) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f4(b, c, d) + x11 + 0x8f1bbcdc, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f4(a, b, c) + x10 + 0x8f1bbcdc, 15) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f4(e, a, b) + x0 + 0x8f1bbcdc, 14) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f4(d, e, a) + x8 + 0x8f1bbcdc, 15) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f4(c, d, e) + x12 + 0x8f1bbcdc, 9) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f4(b, c, d) + x4 + 0x8f1bbcdc, 8) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f4(a, b, c) + x13 + 0x8f1bbcdc, 9) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f4(e, a, b) + x3 + 0x8f1bbcdc, 14) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f4(d, e, a) + x7 + 0x8f1bbcdc, 5) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f4(c, d, e) + x15 + 0x8f1bbcdc, 6) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f4(b, c, d) + x14 + 0x8f1bbcdc, 8) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f4(a, b, c) + x5 + 0x8f1bbcdc, 6) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f4(e, a, b) + x6 + 0x8f1bbcdc, 5) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f4(d, e, a) + x2 + 0x8f1bbcdc, 12) + b; + e = _rotl32(e, 10); + + // right + cc = _rotl32(cc + _f2(dd, ee, aa) + x8 + 0x7a6d76e9, 15) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f2(cc, dd, ee) + x6 + 0x7a6d76e9, 5) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f2(bb, cc, dd) + x4 + 0x7a6d76e9, 8) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f2(aa, bb, cc) + x1 + 0x7a6d76e9, 11) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f2(ee, aa, bb) + x3 + 0x7a6d76e9, 14) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f2(dd, ee, aa) + x11 + 0x7a6d76e9, 14) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f2(cc, dd, ee) + x15 + 0x7a6d76e9, 6) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f2(bb, cc, dd) + x0 + 0x7a6d76e9, 14) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f2(aa, bb, cc) + x5 + 0x7a6d76e9, 6) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f2(ee, aa, bb) + x12 + 0x7a6d76e9, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f2(dd, ee, aa) + x2 + 0x7a6d76e9, 12) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f2(cc, dd, ee) + x13 + 0x7a6d76e9, 9) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f2(bb, cc, dd) + x9 + 0x7a6d76e9, 12) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f2(aa, bb, cc) + x7 + 0x7a6d76e9, 5) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f2(ee, aa, bb) + x10 + 0x7a6d76e9, 15) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f2(dd, ee, aa) + x14 + 0x7a6d76e9, 8) + bb; + ee = _rotl32(ee, 10); + + // + // Rounds 64-79 + // + // left + b = _rotl32(b + _f5(c, d, e) + x4 + 0xa953fd4e, 9) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f5(b, c, d) + x0 + 0xa953fd4e, 15) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f5(a, b, c) + x5 + 0xa953fd4e, 5) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f5(e, a, b) + x9 + 0xa953fd4e, 11) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f5(d, e, a) + x7 + 0xa953fd4e, 6) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f5(c, d, e) + x12 + 0xa953fd4e, 8) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f5(b, c, d) + x2 + 0xa953fd4e, 13) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f5(a, b, c) + x10 + 0xa953fd4e, 12) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f5(e, a, b) + x14 + 0xa953fd4e, 5) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f5(d, e, a) + x1 + 0xa953fd4e, 12) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f5(c, d, e) + x3 + 0xa953fd4e, 13) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f5(b, c, d) + x8 + 0xa953fd4e, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f5(a, b, c) + x11 + 0xa953fd4e, 11) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f5(e, a, b) + x6 + 0xa953fd4e, 8) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f5(d, e, a) + x15 + 0xa953fd4e, 5) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f5(c, d, e) + x13 + 0xa953fd4e, 6) + a; + d = _rotl32(d, 10); + + // right + bb = _rotl32(bb + _f1(cc, dd, ee) + x12, 8) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f1(bb, cc, dd) + x15, 5) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f1(aa, bb, cc) + x10, 12) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f1(ee, aa, bb) + x4, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f1(dd, ee, aa) + x1, 12) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f1(cc, dd, ee) + x5, 5) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f1(bb, cc, dd) + x8, 14) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f1(aa, bb, cc) + x7, 6) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f1(ee, aa, bb) + x6, 8) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f1(dd, ee, aa) + x2, 13) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f1(cc, dd, ee) + x13, 6) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f1(bb, cc, dd) + x14, 5) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f1(aa, bb, cc) + x0, 15) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f1(ee, aa, bb) + x3, 13) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f1(dd, ee, aa) + x9, 11) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f1(cc, dd, ee) + x11, 11) + aa; + dd = _rotl32(dd, 10); + + dd += c + state[1]; + state[1] = state[2] + d + ee; + state[2] = state[3] + e + aa; + state[3] = state[4] + a + bb; + state[4] = state[0] + b + cc; + state[0] = dd; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits, Endian.little); + bdata.setUint32(60, messageLengthInBits >>> 32, Endian.little); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/ripemd/ripemd256.dart b/hashlib/lib/src/algorithms/ripemd/ripemd256.dart new file mode 100644 index 0000000..6fcc252 --- /dev/null +++ b/hashlib/lib/src/algorithms/ripemd/ripemd256.dart @@ -0,0 +1,343 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, + 0x76543210, + 0xFEDCBA98, + 0x89ABCDEF, + 0x01234567, +]; + +/// This implementation is derived from the Bouncy Castle's implementation of +/// [RIPEMD-256][bc]. +/// +/// [bc]: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/RIPEMD256Digest.java +class RIPEMD256Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + RIPEMD256Hash() + : state = Uint32List.fromList(_iv), + hashLength = 256 >>> 3, + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + @pragma('vm:prefer-inline') + static int _f1(int x, int y, int z) => x ^ y ^ z; + + @pragma('vm:prefer-inline') + static int _f2(int x, int y, int z) => (x & y) | (((~x) & _mask32) & z); + + @pragma('vm:prefer-inline') + static int _f3(int x, int y, int z) => (x | ((~y) & _mask32)) ^ z; + + @pragma('vm:prefer-inline') + static int _f4(int x, int y, int z) => (x & z) | (y & ((~z) & _mask32)); + + @pragma('vm:prefer-inline') + static int _lr1(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f1(b, c, d) + x, s); + + @pragma('vm:prefer-inline') + static int _lr2(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f2(b, c, d) + x + 0x5a827999, s); + + @pragma('vm:prefer-inline') + static int _lr3(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f3(b, c, d) + x + 0x6ed9eba1, s); + + @pragma('vm:prefer-inline') + static int _lr4(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f4(b, c, d) + x + 0x8f1bbcdc, s); + + @pragma('vm:prefer-inline') + static int _rr1(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f1(b, c, d) + x, s); + + @pragma('vm:prefer-inline') + static int _rr2(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f2(b, c, d) + x + 0x6d703ef3, s); + + @pragma('vm:prefer-inline') + static int _rr3(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f3(b, c, d) + x + 0x5c4dd124, s); + + @pragma('vm:prefer-inline') + static int _rr4(int a, int b, int c, int d, int x, int s) => + _rotl32(a + _f4(b, c, d) + x + 0x50a28be6, s); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, aa, bb, cc, dd, t; + int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + aa = state[4]; + bb = state[5]; + cc = state[6]; + dd = state[7]; + + x0 = sbuffer[0]; + x1 = sbuffer[1]; + x2 = sbuffer[2]; + x3 = sbuffer[3]; + x4 = sbuffer[4]; + x5 = sbuffer[5]; + x6 = sbuffer[6]; + x7 = sbuffer[7]; + x8 = sbuffer[8]; + x9 = sbuffer[9]; + x10 = sbuffer[10]; + x11 = sbuffer[11]; + x12 = sbuffer[12]; + x13 = sbuffer[13]; + x14 = sbuffer[14]; + x15 = sbuffer[15]; + + // + // Round 1 + // + a = _lr1(a, b, c, d, x0, 11); + d = _lr1(d, a, b, c, x1, 14); + c = _lr1(c, d, a, b, x2, 15); + b = _lr1(b, c, d, a, x3, 12); + a = _lr1(a, b, c, d, x4, 5); + d = _lr1(d, a, b, c, x5, 8); + c = _lr1(c, d, a, b, x6, 7); + b = _lr1(b, c, d, a, x7, 9); + a = _lr1(a, b, c, d, x8, 11); + d = _lr1(d, a, b, c, x9, 13); + c = _lr1(c, d, a, b, x10, 14); + b = _lr1(b, c, d, a, x11, 15); + a = _lr1(a, b, c, d, x12, 6); + d = _lr1(d, a, b, c, x13, 7); + c = _lr1(c, d, a, b, x14, 9); + b = _lr1(b, c, d, a, x15, 8); + + aa = _rr4(aa, bb, cc, dd, x5, 8); + dd = _rr4(dd, aa, bb, cc, x14, 9); + cc = _rr4(cc, dd, aa, bb, x7, 9); + bb = _rr4(bb, cc, dd, aa, x0, 11); + aa = _rr4(aa, bb, cc, dd, x9, 13); + dd = _rr4(dd, aa, bb, cc, x2, 15); + cc = _rr4(cc, dd, aa, bb, x11, 15); + bb = _rr4(bb, cc, dd, aa, x4, 5); + aa = _rr4(aa, bb, cc, dd, x13, 7); + dd = _rr4(dd, aa, bb, cc, x6, 7); + cc = _rr4(cc, dd, aa, bb, x15, 8); + bb = _rr4(bb, cc, dd, aa, x8, 11); + aa = _rr4(aa, bb, cc, dd, x1, 14); + dd = _rr4(dd, aa, bb, cc, x10, 14); + cc = _rr4(cc, dd, aa, bb, x3, 12); + bb = _rr4(bb, cc, dd, aa, x12, 6); + + t = a; + a = aa; + aa = t; + + // + // Round 2 + // + a = _lr2(a, b, c, d, x7, 7); + d = _lr2(d, a, b, c, x4, 6); + c = _lr2(c, d, a, b, x13, 8); + b = _lr2(b, c, d, a, x1, 13); + a = _lr2(a, b, c, d, x10, 11); + d = _lr2(d, a, b, c, x6, 9); + c = _lr2(c, d, a, b, x15, 7); + b = _lr2(b, c, d, a, x3, 15); + a = _lr2(a, b, c, d, x12, 7); + d = _lr2(d, a, b, c, x0, 12); + c = _lr2(c, d, a, b, x9, 15); + b = _lr2(b, c, d, a, x5, 9); + a = _lr2(a, b, c, d, x2, 11); + d = _lr2(d, a, b, c, x14, 7); + c = _lr2(c, d, a, b, x11, 13); + b = _lr2(b, c, d, a, x8, 12); + + aa = _rr3(aa, bb, cc, dd, x6, 9); + dd = _rr3(dd, aa, bb, cc, x11, 13); + cc = _rr3(cc, dd, aa, bb, x3, 15); + bb = _rr3(bb, cc, dd, aa, x7, 7); + aa = _rr3(aa, bb, cc, dd, x0, 12); + dd = _rr3(dd, aa, bb, cc, x13, 8); + cc = _rr3(cc, dd, aa, bb, x5, 9); + bb = _rr3(bb, cc, dd, aa, x10, 11); + aa = _rr3(aa, bb, cc, dd, x14, 7); + dd = _rr3(dd, aa, bb, cc, x15, 7); + cc = _rr3(cc, dd, aa, bb, x8, 12); + bb = _rr3(bb, cc, dd, aa, x12, 7); + aa = _rr3(aa, bb, cc, dd, x4, 6); + dd = _rr3(dd, aa, bb, cc, x9, 15); + cc = _rr3(cc, dd, aa, bb, x1, 13); + bb = _rr3(bb, cc, dd, aa, x2, 11); + + t = b; + b = bb; + bb = t; + + // + // Round 3 + // + a = _lr3(a, b, c, d, x3, 11); + d = _lr3(d, a, b, c, x10, 13); + c = _lr3(c, d, a, b, x14, 6); + b = _lr3(b, c, d, a, x4, 7); + a = _lr3(a, b, c, d, x9, 14); + d = _lr3(d, a, b, c, x15, 9); + c = _lr3(c, d, a, b, x8, 13); + b = _lr3(b, c, d, a, x1, 15); + a = _lr3(a, b, c, d, x2, 14); + d = _lr3(d, a, b, c, x7, 8); + c = _lr3(c, d, a, b, x0, 13); + b = _lr3(b, c, d, a, x6, 6); + a = _lr3(a, b, c, d, x13, 5); + d = _lr3(d, a, b, c, x11, 12); + c = _lr3(c, d, a, b, x5, 7); + b = _lr3(b, c, d, a, x12, 5); + + aa = _rr2(aa, bb, cc, dd, x15, 9); + dd = _rr2(dd, aa, bb, cc, x5, 7); + cc = _rr2(cc, dd, aa, bb, x1, 15); + bb = _rr2(bb, cc, dd, aa, x3, 11); + aa = _rr2(aa, bb, cc, dd, x7, 8); + dd = _rr2(dd, aa, bb, cc, x14, 6); + cc = _rr2(cc, dd, aa, bb, x6, 6); + bb = _rr2(bb, cc, dd, aa, x9, 14); + aa = _rr2(aa, bb, cc, dd, x11, 12); + dd = _rr2(dd, aa, bb, cc, x8, 13); + cc = _rr2(cc, dd, aa, bb, x12, 5); + bb = _rr2(bb, cc, dd, aa, x2, 14); + aa = _rr2(aa, bb, cc, dd, x10, 13); + dd = _rr2(dd, aa, bb, cc, x0, 13); + cc = _rr2(cc, dd, aa, bb, x4, 7); + bb = _rr2(bb, cc, dd, aa, x13, 5); + + t = c; + c = cc; + cc = t; + + // + // Round 4 + // + a = _lr4(a, b, c, d, x1, 11); + d = _lr4(d, a, b, c, x9, 12); + c = _lr4(c, d, a, b, x11, 14); + b = _lr4(b, c, d, a, x10, 15); + a = _lr4(a, b, c, d, x0, 14); + d = _lr4(d, a, b, c, x8, 15); + c = _lr4(c, d, a, b, x12, 9); + b = _lr4(b, c, d, a, x4, 8); + a = _lr4(a, b, c, d, x13, 9); + d = _lr4(d, a, b, c, x3, 14); + c = _lr4(c, d, a, b, x7, 5); + b = _lr4(b, c, d, a, x15, 6); + a = _lr4(a, b, c, d, x14, 8); + d = _lr4(d, a, b, c, x5, 6); + c = _lr4(c, d, a, b, x6, 5); + b = _lr4(b, c, d, a, x2, 12); + + aa = _rr1(aa, bb, cc, dd, x8, 15); + dd = _rr1(dd, aa, bb, cc, x6, 5); + cc = _rr1(cc, dd, aa, bb, x4, 8); + bb = _rr1(bb, cc, dd, aa, x1, 11); + aa = _rr1(aa, bb, cc, dd, x3, 14); + dd = _rr1(dd, aa, bb, cc, x11, 14); + cc = _rr1(cc, dd, aa, bb, x15, 6); + bb = _rr1(bb, cc, dd, aa, x0, 14); + aa = _rr1(aa, bb, cc, dd, x5, 6); + dd = _rr1(dd, aa, bb, cc, x12, 9); + cc = _rr1(cc, dd, aa, bb, x2, 12); + bb = _rr1(bb, cc, dd, aa, x13, 9); + aa = _rr1(aa, bb, cc, dd, x9, 12); + dd = _rr1(dd, aa, bb, cc, x7, 5); + cc = _rr1(cc, dd, aa, bb, x10, 15); + bb = _rr1(bb, cc, dd, aa, x14, 8); + + t = d; + d = dd; + dd = t; + + // + // combine the results + // + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += aa; + state[5] += bb; + state[6] += cc; + state[7] += dd; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits, Endian.little); + bdata.setUint32(60, messageLengthInBits >>> 32, Endian.little); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/ripemd/ripemd320.dart b/hashlib/lib/src/algorithms/ripemd/ripemd320.dart new file mode 100644 index 0000000..0790d72 --- /dev/null +++ b/hashlib/lib/src/algorithms/ripemd/ripemd320.dart @@ -0,0 +1,527 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, + 0xc3d2e1f0, + 0x76543210, + 0xFEDCBA98, + 0x89ABCDEF, + 0x01234567, + 0x3C2D1E0F, +]; + +/// This implementation is derived from the Bouncy Castle's implementation of +/// [RIPEMD-320][bc]. +/// +/// [bc]: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/RIPEMD320Digest.java +class RIPEMD320Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + RIPEMD320Hash() + : state = Uint32List.fromList(_iv), + hashLength = 320 >>> 3, + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + @pragma('vm:prefer-inline') + static int _f1(int x, int y, int z) => x ^ y ^ z; + + @pragma('vm:prefer-inline') + static int _f2(int x, int y, int z) => (x & y) | (((~x) & _mask32) & z); + + @pragma('vm:prefer-inline') + static int _f3(int x, int y, int z) => (x | ((~y) & _mask32)) ^ z; + + @pragma('vm:prefer-inline') + static int _f4(int x, int y, int z) => (x & z) | (y & ((~z) & _mask32)); + + @pragma('vm:prefer-inline') + static int _f5(int x, int y, int z) => x ^ (y | ((~z) & _mask32)); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, e, aa, bb, cc, dd, ee, t; + int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + aa = state[5]; + bb = state[6]; + cc = state[7]; + dd = state[8]; + ee = state[9]; + + x0 = sbuffer[0]; + x1 = sbuffer[1]; + x2 = sbuffer[2]; + x3 = sbuffer[3]; + x4 = sbuffer[4]; + x5 = sbuffer[5]; + x6 = sbuffer[6]; + x7 = sbuffer[7]; + x8 = sbuffer[8]; + x9 = sbuffer[9]; + x10 = sbuffer[10]; + x11 = sbuffer[11]; + x12 = sbuffer[12]; + x13 = sbuffer[13]; + x14 = sbuffer[14]; + x15 = sbuffer[15]; + + // + // Rounds 1 - 16 + // + // left + a = _rotl32(a + _f1(b, c, d) + x0, 11) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f1(a, b, c) + x1, 14) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f1(e, a, b) + x2, 15) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f1(d, e, a) + x3, 12) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f1(c, d, e) + x4, 5) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f1(b, c, d) + x5, 8) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f1(a, b, c) + x6, 7) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f1(e, a, b) + x7, 9) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f1(d, e, a) + x8, 11) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f1(c, d, e) + x9, 13) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f1(b, c, d) + x10, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f1(a, b, c) + x11, 15) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f1(e, a, b) + x12, 6) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f1(d, e, a) + x13, 7) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f1(c, d, e) + x14, 9) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f1(b, c, d) + x15, 8) + e; + c = _rotl32(c, 10); + + // right + aa = _rotl32(aa + _f5(bb, cc, dd) + x5 + 0x50a28be6, 8) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f5(aa, bb, cc) + x14 + 0x50a28be6, 9) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f5(ee, aa, bb) + x7 + 0x50a28be6, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f5(dd, ee, aa) + x0 + 0x50a28be6, 11) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f5(cc, dd, ee) + x9 + 0x50a28be6, 13) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f5(bb, cc, dd) + x2 + 0x50a28be6, 15) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f5(aa, bb, cc) + x11 + 0x50a28be6, 15) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f5(ee, aa, bb) + x4 + 0x50a28be6, 5) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f5(dd, ee, aa) + x13 + 0x50a28be6, 7) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f5(cc, dd, ee) + x6 + 0x50a28be6, 7) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f5(bb, cc, dd) + x15 + 0x50a28be6, 8) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f5(aa, bb, cc) + x8 + 0x50a28be6, 11) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f5(ee, aa, bb) + x1 + 0x50a28be6, 14) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f5(dd, ee, aa) + x10 + 0x50a28be6, 14) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f5(cc, dd, ee) + x3 + 0x50a28be6, 12) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f5(bb, cc, dd) + x12 + 0x50a28be6, 6) + ee; + cc = _rotl32(cc, 10); + + t = a; + a = aa; + aa = t; + + // + // Rounds 16-31 + // + // left + e = _rotl32(e + _f2(a, b, c) + x7 + 0x5a827999, 7) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f2(e, a, b) + x4 + 0x5a827999, 6) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f2(d, e, a) + x13 + 0x5a827999, 8) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f2(c, d, e) + x1 + 0x5a827999, 13) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f2(b, c, d) + x10 + 0x5a827999, 11) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f2(a, b, c) + x6 + 0x5a827999, 9) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f2(e, a, b) + x15 + 0x5a827999, 7) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f2(d, e, a) + x3 + 0x5a827999, 15) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f2(c, d, e) + x12 + 0x5a827999, 7) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f2(b, c, d) + x0 + 0x5a827999, 12) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f2(a, b, c) + x9 + 0x5a827999, 15) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f2(e, a, b) + x5 + 0x5a827999, 9) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f2(d, e, a) + x2 + 0x5a827999, 11) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f2(c, d, e) + x14 + 0x5a827999, 7) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f2(b, c, d) + x11 + 0x5a827999, 13) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f2(a, b, c) + x8 + 0x5a827999, 12) + d; + b = _rotl32(b, 10); + + // right + ee = _rotl32(ee + _f4(aa, bb, cc) + x6 + 0x5c4dd124, 9) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f4(ee, aa, bb) + x11 + 0x5c4dd124, 13) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f4(dd, ee, aa) + x3 + 0x5c4dd124, 15) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f4(cc, dd, ee) + x7 + 0x5c4dd124, 7) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f4(bb, cc, dd) + x0 + 0x5c4dd124, 12) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f4(aa, bb, cc) + x13 + 0x5c4dd124, 8) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f4(ee, aa, bb) + x5 + 0x5c4dd124, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f4(dd, ee, aa) + x10 + 0x5c4dd124, 11) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f4(cc, dd, ee) + x14 + 0x5c4dd124, 7) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f4(bb, cc, dd) + x15 + 0x5c4dd124, 7) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f4(aa, bb, cc) + x8 + 0x5c4dd124, 12) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f4(ee, aa, bb) + x12 + 0x5c4dd124, 7) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f4(dd, ee, aa) + x4 + 0x5c4dd124, 6) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f4(cc, dd, ee) + x9 + 0x5c4dd124, 15) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f4(bb, cc, dd) + x1 + 0x5c4dd124, 13) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f4(aa, bb, cc) + x2 + 0x5c4dd124, 11) + dd; + bb = _rotl32(bb, 10); + + t = b; + b = bb; + bb = t; + + // + // Rounds 32-47 + // + // left + d = _rotl32(d + _f3(e, a, b) + x3 + 0x6ed9eba1, 11) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f3(d, e, a) + x10 + 0x6ed9eba1, 13) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f3(c, d, e) + x14 + 0x6ed9eba1, 6) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f3(b, c, d) + x4 + 0x6ed9eba1, 7) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f3(a, b, c) + x9 + 0x6ed9eba1, 14) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f3(e, a, b) + x15 + 0x6ed9eba1, 9) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f3(d, e, a) + x8 + 0x6ed9eba1, 13) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f3(c, d, e) + x1 + 0x6ed9eba1, 15) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f3(b, c, d) + x2 + 0x6ed9eba1, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f3(a, b, c) + x7 + 0x6ed9eba1, 8) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f3(e, a, b) + x0 + 0x6ed9eba1, 13) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f3(d, e, a) + x6 + 0x6ed9eba1, 6) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f3(c, d, e) + x13 + 0x6ed9eba1, 5) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f3(b, c, d) + x11 + 0x6ed9eba1, 12) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f3(a, b, c) + x5 + 0x6ed9eba1, 7) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f3(e, a, b) + x12 + 0x6ed9eba1, 5) + c; + a = _rotl32(a, 10); + + // right + dd = _rotl32(dd + _f3(ee, aa, bb) + x15 + 0x6d703ef3, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f3(dd, ee, aa) + x5 + 0x6d703ef3, 7) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f3(cc, dd, ee) + x1 + 0x6d703ef3, 15) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f3(bb, cc, dd) + x3 + 0x6d703ef3, 11) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f3(aa, bb, cc) + x7 + 0x6d703ef3, 8) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f3(ee, aa, bb) + x14 + 0x6d703ef3, 6) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f3(dd, ee, aa) + x6 + 0x6d703ef3, 6) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f3(cc, dd, ee) + x9 + 0x6d703ef3, 14) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f3(bb, cc, dd) + x11 + 0x6d703ef3, 12) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f3(aa, bb, cc) + x8 + 0x6d703ef3, 13) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f3(ee, aa, bb) + x12 + 0x6d703ef3, 5) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f3(dd, ee, aa) + x2 + 0x6d703ef3, 14) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f3(cc, dd, ee) + x10 + 0x6d703ef3, 13) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f3(bb, cc, dd) + x0 + 0x6d703ef3, 13) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f3(aa, bb, cc) + x4 + 0x6d703ef3, 7) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f3(ee, aa, bb) + x13 + 0x6d703ef3, 5) + cc; + aa = _rotl32(aa, 10); + + t = c; + c = cc; + cc = t; + + // + // Rounds 48-63 + // + // left + c = _rotl32(c + _f4(d, e, a) + x1 + 0x8f1bbcdc, 11) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f4(c, d, e) + x9 + 0x8f1bbcdc, 12) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f4(b, c, d) + x11 + 0x8f1bbcdc, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f4(a, b, c) + x10 + 0x8f1bbcdc, 15) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f4(e, a, b) + x0 + 0x8f1bbcdc, 14) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f4(d, e, a) + x8 + 0x8f1bbcdc, 15) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f4(c, d, e) + x12 + 0x8f1bbcdc, 9) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f4(b, c, d) + x4 + 0x8f1bbcdc, 8) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f4(a, b, c) + x13 + 0x8f1bbcdc, 9) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f4(e, a, b) + x3 + 0x8f1bbcdc, 14) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f4(d, e, a) + x7 + 0x8f1bbcdc, 5) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f4(c, d, e) + x15 + 0x8f1bbcdc, 6) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f4(b, c, d) + x14 + 0x8f1bbcdc, 8) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f4(a, b, c) + x5 + 0x8f1bbcdc, 6) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f4(e, a, b) + x6 + 0x8f1bbcdc, 5) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f4(d, e, a) + x2 + 0x8f1bbcdc, 12) + b; + e = _rotl32(e, 10); + + // right + cc = _rotl32(cc + _f2(dd, ee, aa) + x8 + 0x7a6d76e9, 15) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f2(cc, dd, ee) + x6 + 0x7a6d76e9, 5) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f2(bb, cc, dd) + x4 + 0x7a6d76e9, 8) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f2(aa, bb, cc) + x1 + 0x7a6d76e9, 11) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f2(ee, aa, bb) + x3 + 0x7a6d76e9, 14) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f2(dd, ee, aa) + x11 + 0x7a6d76e9, 14) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f2(cc, dd, ee) + x15 + 0x7a6d76e9, 6) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f2(bb, cc, dd) + x0 + 0x7a6d76e9, 14) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f2(aa, bb, cc) + x5 + 0x7a6d76e9, 6) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f2(ee, aa, bb) + x12 + 0x7a6d76e9, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f2(dd, ee, aa) + x2 + 0x7a6d76e9, 12) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f2(cc, dd, ee) + x13 + 0x7a6d76e9, 9) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f2(bb, cc, dd) + x9 + 0x7a6d76e9, 12) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f2(aa, bb, cc) + x7 + 0x7a6d76e9, 5) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f2(ee, aa, bb) + x10 + 0x7a6d76e9, 15) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f2(dd, ee, aa) + x14 + 0x7a6d76e9, 8) + bb; + ee = _rotl32(ee, 10); + + t = d; + d = dd; + dd = t; + + // + // Rounds 64-79 + // + // left + b = _rotl32(b + _f5(c, d, e) + x4 + 0xa953fd4e, 9) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f5(b, c, d) + x0 + 0xa953fd4e, 15) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f5(a, b, c) + x5 + 0xa953fd4e, 5) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f5(e, a, b) + x9 + 0xa953fd4e, 11) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f5(d, e, a) + x7 + 0xa953fd4e, 6) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f5(c, d, e) + x12 + 0xa953fd4e, 8) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f5(b, c, d) + x2 + 0xa953fd4e, 13) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f5(a, b, c) + x10 + 0xa953fd4e, 12) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f5(e, a, b) + x14 + 0xa953fd4e, 5) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f5(d, e, a) + x1 + 0xa953fd4e, 12) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f5(c, d, e) + x3 + 0xa953fd4e, 13) + a; + d = _rotl32(d, 10); + a = _rotl32(a + _f5(b, c, d) + x8 + 0xa953fd4e, 14) + e; + c = _rotl32(c, 10); + e = _rotl32(e + _f5(a, b, c) + x11 + 0xa953fd4e, 11) + d; + b = _rotl32(b, 10); + d = _rotl32(d + _f5(e, a, b) + x6 + 0xa953fd4e, 8) + c; + a = _rotl32(a, 10); + c = _rotl32(c + _f5(d, e, a) + x15 + 0xa953fd4e, 5) + b; + e = _rotl32(e, 10); + b = _rotl32(b + _f5(c, d, e) + x13 + 0xa953fd4e, 6) + a; + d = _rotl32(d, 10); + + // right + bb = _rotl32(bb + _f1(cc, dd, ee) + x12, 8) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f1(bb, cc, dd) + x15, 5) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f1(aa, bb, cc) + x10, 12) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f1(ee, aa, bb) + x4, 9) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f1(dd, ee, aa) + x1, 12) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f1(cc, dd, ee) + x5, 5) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f1(bb, cc, dd) + x8, 14) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f1(aa, bb, cc) + x7, 6) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f1(ee, aa, bb) + x6, 8) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f1(dd, ee, aa) + x2, 13) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f1(cc, dd, ee) + x13, 6) + aa; + dd = _rotl32(dd, 10); + aa = _rotl32(aa + _f1(bb, cc, dd) + x14, 5) + ee; + cc = _rotl32(cc, 10); + ee = _rotl32(ee + _f1(aa, bb, cc) + x0, 15) + dd; + bb = _rotl32(bb, 10); + dd = _rotl32(dd + _f1(ee, aa, bb) + x3, 13) + cc; + aa = _rotl32(aa, 10); + cc = _rotl32(cc + _f1(dd, ee, aa) + x9, 11) + bb; + ee = _rotl32(ee, 10); + bb = _rotl32(bb + _f1(cc, dd, ee) + x11, 11) + aa; + dd = _rotl32(dd, 10); + + // + // do (e, ee) swap as part of assignment. + // + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += ee; + state[5] += aa; + state[6] += bb; + state[7] += cc; + state[8] += dd; + state[9] += e; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits, Endian.little); + bdata.setUint32(60, messageLengthInBits >>> 32, Endian.little); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + return Uint8List.view(state.buffer).sublist(0, hashLength); + } +} diff --git a/hashlib/lib/src/algorithms/scrypt/scrypt.dart b/hashlib/lib/src/algorithms/scrypt/scrypt.dart new file mode 100644 index 0000000..0f1d148 --- /dev/null +++ b/hashlib/lib/src/algorithms/scrypt/scrypt.dart @@ -0,0 +1,282 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/hash_digest.dart'; +import 'package:hashlib/src/core/kdf_base.dart'; +import 'package:hashlib/src/pbkdf2.dart'; +import 'package:hashlib/src/random.dart'; + +import 'security.dart'; + +const int _mask32 = 0xFFFFFFFF; + +/// This is an implementation of Password Based Key Derivation Algorithm, +/// scrypt derived from [RFC-7914][rfc], which internally uses [PBKDF2]. +/// +/// The function derives one or more secret keys from a secret string. It is +/// based on memory-hard functions, which offer added protection against +/// attacks using custom hardware. +/// +/// The strength of the generated password using scrypt depends on the +/// CPU/Memory cost, block size and parallelism parameters. Poor parameter +/// choices can be harmful for security; for example, if you tune the +/// parameters so that memory use is reduced to small amounts that will affect +/// the properties of the algorithm. +/// +/// [rfc]: https://www.rfc-editor.org/rfc/rfc7914.html +class Scrypt extends KeyDerivatorBase { + @override + final String name = 'Scrypt'; + + /// The byte array containing salt + final List salt; + + /// CPU/Memory cost parameter (N) + final int cost; + + /// Block size parameter (r) + final int blockSize; + + /// Parallelization parameter (p) + final int parallelism; + + @override + final int derivedKeyLength; + + const Scrypt._({ + required this.salt, + required this.cost, + required this.blockSize, + required this.parallelism, + required this.derivedKeyLength, + }); + + /// Creates an [Scrypt] instance with a sink for MAC generation. + factory Scrypt({ + List? salt, + required int cost, + int blockSize = 8, + int parallelism = 1, + int derivedKeyLength = 64, + }) { + // validate parameters + if (cost < 1) { + throw StateError('The cost must be at least 1'); + } + if (cost > 0xFFFFFF) { + throw StateError('The cost must be less than 2^24'); + } + if (cost & (cost - 1) != 0) { + throw StateError('The cost must be a power of 2'); + } + if (derivedKeyLength < 1) { + throw StateError('The derivedKeyLength must be at least 1'); + } + if (blockSize < 1) { + throw StateError('The blockSize must be at least 1'); + } + if (parallelism < 1) { + throw StateError('The parallelism must be at least 1'); + } + if (blockSize * parallelism > 0x1FFFFFF) { + throw StateError('The blockSize * parallelism is too big'); + } + salt ??= randomBytes(16); + + // create instance + return Scrypt._( + salt: salt, + cost: cost, + blockSize: blockSize, + parallelism: parallelism, + derivedKeyLength: derivedKeyLength, + ); + } + + /// Creates an [Scrypt] instance from [ScryptSecurity] parameter. + factory Scrypt.fromSecurity( + ScryptSecurity security, { + List? salt, + int derivedKeyLength = 64, + }) { + return Scrypt( + salt: salt, + cost: security.N, + blockSize: security.r, + parallelism: security.p, + derivedKeyLength: derivedKeyLength, + ); + } + + /// Generate a derived key using the scrypt algorithm. + @override + HashDigest convert(List password) { + int N = cost; + int midRO = (blockSize << 4); + int roLength = (blockSize << 7); + int roLength32 = (roLength >>> 2); + int innerKeyLength = parallelism * roLength; + int innerKeyLength32 = parallelism * roLength32; + Uint32List inp = Uint32List(roLength32); + Uint32List out = Uint32List(roLength32); + Uint32List t = Uint32List(16); + Uint32List v; + + // Initialize the memory + List acc = List.filled(N, Uint32List(roLength32)); + for (int i = 1; i < N; ++i) { + acc[i] = Uint32List(roLength32); + } + + // Derive the inner blocks + var inner = pbkdf2(password, salt, 1, innerKeyLength).bytes; + var inner32 = Uint32List.view(inner.buffer); + + /// [length] = 128 * r = 2 * 64 * r = 4 * 32 * r bytes + @pragma('vm:prefer-inline') + void blockMix() { + int i, j, p, q; + p = 0; + q = midRO; + for (j = 0; j < 16; j++) { + t[j] = inp[roLength32 - 16 + j]; + } + for (i = 0; i < roLength32; i += 32) { + // even + for (j = 0; j < 16; j++) { + t[j] ^= inp[i + j]; + } + _salsa20(t); + for (j = 0; j < 16; j++, p++) { + out[p] = t[j]; + } + + // odd + for (j = 0; j < 16; j++) { + t[j] ^= inp[i + j + 16]; + } + _salsa20(t); + for (j = 0; j < 16; j++, q++) { + out[q] = t[j]; + } + } + } + + // Mix the inner blocks to derive the outer salt + for (int i, j, k = 0; k < innerKeyLength32; k += roLength32) { + /// Number of iterations, [N] is a power of 2 + /// length of [x] = 128 * r = 2 * 64 * r = 4 * 32 * r bytes + for (j = 0; j < roLength32; ++j) { + inp[j] = inner32[j + k]; + } + for (i = 0; i < N; ++i) { + v = acc[i]; + for (j = 0; j < roLength32; ++j) { + v[j] = inp[j]; + } + blockMix(); + // swap inp <-> out + v = inp; + inp = out; + out = v; + } + for (i = 0; i < N; ++i) { + v = acc[inp[roLength32 - 16] & (N - 1)]; + for (j = 0; j < roLength32; ++j) { + inp[j] ^= v[j]; + } + blockMix(); + // swap inp <-> out + v = inp; + inp = out; + out = v; + } + for (j = 0; j < roLength32; ++j) { + inner32[j + k] = inp[j]; + } + } + + // Derive final blocks with the outer salt + return pbkdf2(password, inner, 1, derivedKeyLength); + } + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + /// size of [b] = 4 * 16 = 64 bytes + static void _salsa20(Uint32List b) { + int i, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + x0 = b[0]; + x1 = b[1]; + x2 = b[2]; + x3 = b[3]; + x4 = b[4]; + x5 = b[5]; + x6 = b[6]; + x7 = b[7]; + x8 = b[8]; + x9 = b[9]; + x10 = b[10]; + x11 = b[11]; + x12 = b[12]; + x13 = b[13]; + x14 = b[14]; + x15 = b[15]; + + for (i = 8; i > 0; i -= 2) { + x4 ^= _rotl32(x0 + x12, 7); + x8 ^= _rotl32(x4 + x0, 9); + x12 ^= _rotl32(x8 + x4, 13); + x0 ^= _rotl32(x12 + x8, 18); + x9 ^= _rotl32(x5 + x1, 7); + x13 ^= _rotl32(x9 + x5, 9); + x1 ^= _rotl32(x13 + x9, 13); + x5 ^= _rotl32(x1 + x13, 18); + x14 ^= _rotl32(x10 + x6, 7); + x2 ^= _rotl32(x14 + x10, 9); + x6 ^= _rotl32(x2 + x14, 13); + x10 ^= _rotl32(x6 + x2, 18); + x3 ^= _rotl32(x15 + x11, 7); + x7 ^= _rotl32(x3 + x15, 9); + x11 ^= _rotl32(x7 + x3, 13); + x15 ^= _rotl32(x11 + x7, 18); + x1 ^= _rotl32(x0 + x3, 7); + x2 ^= _rotl32(x1 + x0, 9); + x3 ^= _rotl32(x2 + x1, 13); + x0 ^= _rotl32(x3 + x2, 18); + x6 ^= _rotl32(x5 + x4, 7); + x7 ^= _rotl32(x6 + x5, 9); + x4 ^= _rotl32(x7 + x6, 13); + x5 ^= _rotl32(x4 + x7, 18); + x11 ^= _rotl32(x10 + x9, 7); + x8 ^= _rotl32(x11 + x10, 9); + x9 ^= _rotl32(x8 + x11, 13); + x10 ^= _rotl32(x9 + x8, 18); + x12 ^= _rotl32(x15 + x14, 7); + x13 ^= _rotl32(x12 + x15, 9); + x14 ^= _rotl32(x13 + x12, 13); + x15 ^= _rotl32(x14 + x13, 18); + } + + b[0] += x0; + b[1] += x1; + b[2] += x2; + b[3] += x3; + b[4] += x4; + b[5] += x5; + b[6] += x6; + b[7] += x7; + b[8] += x8; + b[9] += x9; + b[10] += x10; + b[11] += x11; + b[12] += x12; + b[13] += x13; + b[14] += x14; + b[15] += x15; + } +} diff --git a/hashlib/lib/src/algorithms/scrypt/security.dart b/hashlib/lib/src/algorithms/scrypt/security.dart new file mode 100644 index 0000000..35f1e9f --- /dev/null +++ b/hashlib/lib/src/algorithms/scrypt/security.dart @@ -0,0 +1,95 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'scrypt.dart'; + +/// This contains some recommended values of memory, iteration and parallelism +/// values for [Scrypt] algorithm. +/// +/// It is best to try out different combinations of these values to achieve the +/// desired runtime on a target machine. +class ScryptSecurity { + final String name; + + /// The size of a single block in bytes + final int r; + + /// The CPU/Memory cost parameter as a power of 2. 1 < [N] < 2^32 + final int N; + + /// The parallelization parameter. [p] <= (2^32 - 1) / (128 * [r]) + final int p; + + const ScryptSecurity( + this.name, { + required this.N, + required this.r, + required this.p, + }); + + /// Provides a very low security. Use it only for test purposes. + /// + /// It uses cost of 16, block size of 2 and parallelism of 1. + /// + /// **WARNING: Not recommended for general use.** + static const test = ScryptSecurity('test', N: 1 << 4, r: 2, p: 1); + + /// Provides low security. Can be used on low-end devices. + /// + /// It uses cost of 256, block size of 4 and parallelism of 2. + /// + /// **WARNING: Not recommended for general use.** + static const little = ScryptSecurity('little', N: 1 << 8, r: 4, p: 2); + + /// Provides moderate security. + /// + /// It uses cost of 2^10, block size of 8 and parallelism of 3. + static const moderate = ScryptSecurity('moderate', N: 1 << 10, r: 8, p: 3); + + /// Provides good security. The default parameters from [RFC-7914][rfc] + /// + /// It uses cost of 2^14, block size of 8 and parallelism of 1. + /// + /// [rfc]: https://www.ietf.org/rfc/rfc7914.html + static const good = ScryptSecurity('good', N: 1 << 14, r: 8, p: 1); + + /// Provides strong security. + /// + /// It uses cost of 2^18, block size of 16 and parallelism of 2. + static const strong = ScryptSecurity('strong', N: 1 << 18, r: 8, p: 2); + + /// Provides strong security recommended by [OWASP][link]. + /// + /// It uses cost of 2^17, block size of 8 and parallelism of 1. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp = ScryptSecurity('owasp1', N: 1 << 17, r: 8, p: 1); + + /// The second recommendation by [OWASP][link]. + /// + /// It uses cost of 2^16, block size of 8 and parallelism of 2. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp2 = ScryptSecurity('owasp2', N: 1 << 16, r: 8, p: 2); + + /// The third recommendation by [OWASP][link]. + /// + /// It uses cost of 2^15, block size of 8 and parallelism of 3. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp3 = ScryptSecurity('owasp3', N: 1 << 15, r: 8, p: 3); + + /// The fourth recommendation by [OWASP][link]. + /// + /// It uses cost of 2^14, block size of 8 and parallelism of 5. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp4 = ScryptSecurity('owasp4', N: 1 << 14, r: 8, p: 5); + + /// The fifth recommendation by [OWASP][link]. + /// + /// It uses cost of 2^13, block size of 8 and parallelism of 10. + /// + /// [link]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + static const owasp5 = ScryptSecurity('owasp5', N: 1 << 13, r: 8, p: 10); +} diff --git a/hashlib/lib/src/algorithms/sha1.dart b/hashlib/lib/src/algorithms/sha1.dart new file mode 100644 index 0000000..3244c1a --- /dev/null +++ b/hashlib/lib/src/algorithms/sha1.dart @@ -0,0 +1,163 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x67452301, // a + 0xEFCDAB89, // b + 0x98BADCFE, // c + 0x10325476, // d + 0xC3D2E1F0, // e +]; + +/// This implementation is derived from The Internet Society +/// [US Secure Hash Algorithm 1 (SHA1)][rfc3174]. +/// +/// [rfc3174]: https://www.ietf.org/rfc/rfc3174.html +class SHA1Hash extends BlockHashSink { + final Uint32List state; + final Uint32List chunk; + + @override + final int hashLength; + + SHA1Hash() + : chunk = Uint32List(80), + hashLength = 160 >>> 3, + state = Uint32List.fromList(_iv), + super(512 >>> 3); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $update(List block, [int offset = 0, bool last = false]) { + var w = chunk; + + int a, b, c, d, e; + int t, x, ch, i, j; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + // Convert the block to chunk + i = 0; + j = offset; + for (; i < 16; i++, j += 4) { + w[i] = ((block[j] & 0xFF) << 24) | + ((block[j + 1] & 0xFF) << 16) | + ((block[j + 2] & 0xFF) << 8) | + (block[j + 3] & 0xFF); + } + + // Extend the first 16 words into the remaining 64 words + for (i = 16; i < 80; i++) { + x = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]; + w[i] = (x << 1) | ((x & _mask32) >>> 31); + } + + for (i = 0; i < 20; i++) { + ch = (b & c) | ((~b) & d); + t = ((a << 5) & _mask32) | (a >>> 27); + x = t + ch + e + w[i] + 0x5A827999; + e = d; + d = c; + c = ((b << 30) & _mask32) | (b >>> 2); + b = a; + a = x & _mask32; + } + + for (; i < 40; i++) { + ch = (b ^ c ^ d); + t = ((a << 5) & _mask32) | (a >>> 27); + x = t + ch + e + w[i] + 0x6ED9EBA1; + e = d; + d = c; + c = ((b << 30) & _mask32) | (b >>> 2); + b = a; + a = x & _mask32; + } + + for (; i < 60; i++) { + ch = ((b & c) | (b & d) | (c & d)); + t = ((a << 5) & _mask32) | (a >>> 27); + x = t + ch + e + w[i] + 0x8F1BBCDC; + e = d; + d = c; + c = ((b << 30) & _mask32) | (b >>> 2); + b = a; + a = x & _mask32; + } + + for (; i < 80; i++) { + ch = (b ^ c ^ d); + t = ((a << 5) & _mask32) | (a >>> 27); + x = t + ch + e + w[i] + 0xCA62C1D6; + e = d; + d = c; + c = ((b << 30) & _mask32) | (b >>> 2); + b = a; + a = x & _mask32; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(buffer); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + int n = messageLengthInBits; + buffer[56] = n >>> 56; + buffer[57] = n >>> 48; + buffer[58] = n >>> 40; + buffer[59] = n >>> 32; + buffer[60] = n >>> 24; + buffer[61] = n >>> 16; + buffer[62] = n >>> 8; + buffer[63] = n; + + // Update with the final block + $update(buffer); + + // Convert the state to 8-bit byte array + var bytes = Uint8List(hashLength); + for (int j = 0, i = 0; j < hashLength; i++, j += 4) { + bytes[j] = state[i] >>> 24; + bytes[j + 1] = state[i] >>> 16; + bytes[j + 2] = state[i] >>> 8; + bytes[j + 3] = state[i]; + } + return bytes; + } +} diff --git a/hashlib/lib/src/algorithms/sha2/sha2.dart b/hashlib/lib/src/algorithms/sha2/sha2.dart new file mode 100644 index 0000000..c843d12 --- /dev/null +++ b/hashlib/lib/src/algorithms/sha2/sha2.dart @@ -0,0 +1,113 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'sha2_1024_64bit.dart' if (dart.library.js) 'sha2_1024_32bit.dart'; +import 'sha2_512.dart'; + +/// Implementation of 224-bit hash generator based on 512-bit SHA2. +class SHA224Hash extends SHA2of512 { + SHA224Hash() + : super( + hashLength: 224 >>> 3, + seed: [ + 0xC1059ED8, // a + 0x367CD507, // b + 0x3070DD17, // c + 0xF70E5939, // d + 0xFFC00B31, // e + 0x68581511, // f + 0x64F98FA7, // g + 0xBEFA4FA4, // h + ], + ); +} + +/// Implementation of 256-bit hash generator based on 512-bit SHA2. +class SHA256Hash extends SHA2of512 { + SHA256Hash() + : super( + hashLength: 256 >>> 3, + seed: [ + 0x6A09E667, // a + 0xBB67AE85, // b + 0x3C6EF372, // c + 0xA54FF53A, // d + 0x510E527F, // e + 0x9B05688C, // f + 0x1F83D9AB, // g + 0x5BE0CD19, // h + ], + ); +} + +/// Implementation of 384-bit hash generator based on 1024-bit SHA2. +class SHA384Hash extends SHA2of1024 { + SHA384Hash() + : super( + hashLength: 384 >>> 3, + seed: [ + 0xCBBB9D5D, 0xC1059ED8, // a + 0x629A292A, 0x367CD507, // b + 0x9159015A, 0x3070DD17, // c + 0x152FECD8, 0xF70E5939, // d + 0x67332667, 0xFFC00B31, // e + 0x8EB44A87, 0x68581511, // f + 0xDB0C2E0D, 0x64F98FA7, // g + 0x47B5481D, 0xBEFA4FA4, // h + ], + ); +} + +/// Implementation of 512-bit hash generator based on 1024-bit SHA2. +class SHA512Hash extends SHA2of1024 { + SHA512Hash() + : super( + hashLength: 512 >>> 3, + seed: [ + 0x6A09E667, 0xF3BCC908, // a + 0xBB67AE85, 0x84CAA73B, // b + 0x3C6EF372, 0xFE94F82B, // c + 0xA54FF53A, 0x5F1D36F1, // d + 0x510E527F, 0xADE682D1, // e + 0x9B05688C, 0x2B3E6C1F, // f + 0x1F83D9AB, 0xFB41BD6B, // g + 0x5BE0CD19, 0x137E2179, // h + ], + ); +} + +/// Implementation of 224-bit hash generator based on 1024-bit SHA2. +class SHA512t224Hash extends SHA2of1024 { + SHA512t224Hash() + : super( + hashLength: 224 >>> 3, + seed: [ + 0x8C3D37C8, 0x19544DA2, // a + 0x73E19966, 0x89DCD4D6, // b + 0x1DFAB7AE, 0x32FF9C82, // c + 0x679DD514, 0x582F9FCF, // d + 0x0F6D2B69, 0x7BD44DA8, // e + 0x77E36F73, 0x04C48942, // f + 0x3F9D85A8, 0x6A1D36C8, // g + 0x1112E6AD, 0x91D692A1, // h + ], + ); +} + +/// Implementation of 256-bit hash generator based on 1024-bit SHA2. +class SHA512t256Hash extends SHA2of1024 { + SHA512t256Hash() + : super( + hashLength: 256 >>> 3, + seed: [ + 0x22312194, 0xFC2BF72C, // a + 0x9F555FA3, 0xC84C64C2, // b + 0x2393B86B, 0x6F53B151, // c + 0x96387719, 0x5940EABD, // d + 0x96283EE2, 0xA88EFFE3, // e + 0xBE5E1E25, 0x53863992, // f + 0x2B0199FC, 0x2C85B8AA, // g + 0x0EB72DDC, 0x81C52CA2, // h + ], + ); +} diff --git a/hashlib/lib/src/algorithms/sha2/sha2_1024_32bit.dart b/hashlib/lib/src/algorithms/sha2/sha2_1024_32bit.dart new file mode 100644 index 0000000..6d1861b --- /dev/null +++ b/hashlib/lib/src/algorithms/sha2/sha2_1024_32bit.dart @@ -0,0 +1,305 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +// Initialize array of round 64-bit constants +const List _k = [ + 0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD, 0xB5C0FBCF, 0xEC4D3B2F, // + 0xE9B5DBA5, 0x8189DBBC, 0x3956C25B, 0xF348B538, 0x59F111F1, 0xB605D019, + 0x923F82A4, 0xAF194F9B, 0xAB1C5ED5, 0xDA6D8118, 0xD807AA98, 0xA3030242, + 0x12835B01, 0x45706FBE, 0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2, + 0x72BE5D74, 0xF27B896F, 0x80DEB1FE, 0x3B1696B1, 0x9BDC06A7, 0x25C71235, + 0xC19BF174, 0xCF692694, 0xE49B69C1, 0x9EF14AD2, 0xEFBE4786, 0x384F25E3, + 0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65, 0x2DE92C6F, 0x592B0275, + 0x4A7484AA, 0x6EA6E483, 0x5CB0A9DC, 0xBD41FBD4, 0x76F988DA, 0x831153B5, + 0x983E5152, 0xEE66DFAB, 0xA831C66D, 0x2DB43210, 0xB00327C8, 0x98FB213F, + 0xBF597FC7, 0xBEEF0EE4, 0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725, + 0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70, 0x27B70A85, 0x46D22FFC, + 0x2E1B2138, 0x5C26C926, 0x4D2C6DFC, 0x5AC42AED, 0x53380D13, 0x9D95B3DF, + 0x650A7354, 0x8BAF63DE, 0x766A0ABB, 0x3C77B2A8, 0x81C2C92E, 0x47EDAEE6, + 0x92722C85, 0x1482353B, 0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001, + 0xC24B8B70, 0xD0F89791, 0xC76C51A3, 0x0654BE30, 0xD192E819, 0xD6EF5218, + 0xD6990624, 0x5565A910, 0xF40E3585, 0x5771202A, 0x106AA070, 0x32BBD1B8, + 0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53, 0x2748774C, 0xDF8EEB99, + 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3, 0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB, + 0x5B9CCA4F, 0x7763E373, 0x682E6FF3, 0xD6B2B8A3, 0x748F82EE, 0x5DEFB2FC, + 0x78A5636F, 0x43172F60, 0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC, + 0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9, 0xBEF9A3F7, 0xB2C67915, + 0xC67178F2, 0xE372532B, 0xCA273ECE, 0xEA26619C, 0xD186B8C7, 0x21C0C207, + 0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F, 0xEE6ED178, 0x06F067AA, 0x72176FBA, + 0x0A637DC5, 0xA2C898A6, 0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B, + 0x28DB77F5, 0x23047D84, 0x32CAAB7B, 0x40C72493, 0x3C9EBE0A, 0x15C9BEBC, + 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, 0xFC657E2A, + 0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817, +]; + +const int _sig1 = 0; +const int _sig2 = _sig1 + 2; +const int _sig3 = _sig2 + 2; +const int _sig4 = _sig3 + 2; +const int _a = _sig4 + 2; +const int _b = _a + 2; +const int _c = _b + 2; +const int _d = _c + 2; +const int _e = _d + 2; +const int _f = _e + 2; +const int _g = _f + 2; +const int _h = _g + 2; +const int _t1 = _h + 2; +const int _t2 = _t1 + 2; +const int _t3 = _t2 + 2; +const int _t4 = _t3 + 2; +const int _t5 = _t4 + 2; + +/// Implementation is derived from [RFC6234][rfc6234] which follows the +/// [FIPS 180-4][fips180] standard for SHA and SHA-based HMAC and HKDF. +/// +/// It uses 32-bit integers to accommodate 64-bit integer operations, designed +/// specially to be supported by Web VM. It is albeit slower than the native +/// implementation. +/// +/// [rfc6234]: https://www.ietf.org/rfc/rfc6234.html +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +class SHA2of1024 extends BlockHashSink { + final List seed; + final Uint32List state; + final Uint32List chunk; + final _var = Uint32List(_t5 + 2); + + @override + final int hashLength; + + /// For internal use only. + SHA2of1024({ + required this.seed, + required this.hashLength, + }) : chunk = Uint32List(160), + state = Uint32List.fromList(seed), + super(1024 >>> 3); + + @override + void reset() { + state.setAll(0, seed); + super.reset(); + } + + /// z = x ^ y + static void _xor(List x, int i, List y, int j, List z, int k) { + z[k] = x[i] ^ y[j]; + z[k + 1] = x[i + 1] ^ y[j + 1]; + } + + /// z = x + y + static void _add(List x, int i, List y, int j, List z, int k) { + z[k + 1] = x[i + 1] + y[j + 1]; + z[k] = x[i] + y[j] + (z[k + 1] < x[i + 1] ? 1 : 0); + } + + /// x += z + static void _addAndSet(List x, int i, List z, int j) { + var t = x[i + 1]; + x[i + 1] += z[j + 1]; + x[i] += z[j] + (x[i + 1] < t ? 1 : 0); + } + + // x >>> n + static void _shr(int n, List x, int i, List z, int k) { + var a = x[i]; + var b = x[i + 1]; + if (n == 32) { + z[k] = 0; + z[k + 1] = a; + } else if (n < 32) { + z[k] = a >>> n; + z[k + 1] = (a << (32 - n)) | (b >>> n); + } else { + z[k] = 0; + z[k + 1] = a >>> (n - 32); + } + } + + // (x << (64 - n)) | (x >>> n) + static void _rotr(int n, List x, int i, List z, int k) { + var a = x[i]; + var b = x[i + 1]; + if (n == 32) { + z[k] = b; + z[k + 1] = a; + } else if (n < 32) { + z[k] = (b << (32 - n)) | (a >>> n); + z[k + 1] = (a << (32 - n)) | (b >>> n); + } else { + z[k] = (a << (64 - n)) | (b >>> (n - 32)); + z[k + 1] = (b << (64 - n)) | (a >>> (n - 32)); + } + } + + // z = _rotr(x, 28) ^ _rotr(x, 34) ^ _rotr(x, 39) + void _bsig0(List x, int i, List z, int j) { + _rotr(28, x, i, _var, _sig1); + _rotr(34, x, i, _var, _sig2); + _rotr(39, x, i, _var, _sig3); + _xor(_var, _sig2, _var, _sig3, _var, _sig4); + _xor(_var, _sig1, _var, _sig4, z, j); + } + + // z = _rotr(x, 14) ^ _rotr(x, 18) ^ _rotr(x, 41) + void _bsig1(List x, int i, List z, int j) { + _rotr(14, x, i, _var, _sig1); + _rotr(18, x, i, _var, _sig2); + _rotr(41, x, i, _var, _sig3); + _xor(_var, _sig2, _var, _sig3, _var, _sig4); + _xor(_var, _sig1, _var, _sig4, z, j); + } + + // z = _rotr(x, 1) ^ _rotr(x, 8) ^ (x >>> 7) + void _ssig0(List x, int i, List z, int j) { + _rotr(1, x, i, _var, _sig1); + _rotr(8, x, i, _var, _sig2); + _shr(7, x, i, _var, _sig3); + _xor(_var, _sig2, _var, _sig3, _var, _sig4); + _xor(_var, _sig1, _var, _sig4, z, j); + } + + // z = _rotr(x, 19) ^ _rotr(x, 61) ^ (x >>> 6) + void _ssig1(List x, int i, List z, int j) { + _rotr(19, x, i, _var, _sig1); + _rotr(61, x, i, _var, _sig2); + _shr(6, x, i, _var, _sig3); + _xor(_var, _sig2, _var, _sig3, _var, _sig4); + _xor(_var, _sig1, _var, _sig4, z, j); + } + + // z = (e & f) ^ ((~e) & g) + static void _ch(List e, int i, List f, int j, List g, int k, + List z, int l) { + z[l] = (e[i] & (f[j] ^ g[k])) ^ g[k]; + z[l + 1] = (e[i + 1] & (f[j + 1] ^ g[k + 1])) ^ g[k + 1]; + } + + // z = (a & b) ^ (a & c) ^ (b & c) + static void _maj(List a, int i, List b, int j, List c, int k, + List z, int l) { + z[l] = (a[i] & (b[j] | c[k])) | (b[j] & c[k]); + z[l + 1] = (a[i + 1] & (b[j + 1] | c[k + 1])) | (b[j + 1] & c[k + 1]); + } + + @override + void $update(List block, [int offset = 0, bool last = false]) { + var w = chunk; + + _var.setAll(_a, state); + + // Convert the block to chunk + for (int i = 0, j = offset; i < 32; i++, j += 4) { + w[i] = ((block[j] & 0xFF) << 24) | + ((block[j + 1] & 0xFF) << 16) | + ((block[j + 2] & 0xFF) << 8) | + ((block[j + 3] & 0xFF)); + } + + // Extend the first 32 words into nest 160 words + for (var i = 32; i < 160; i += 2) { + // w[i] = _ssig1(w[i - 2]) + w[i - 7] + _ssig0(w[i - 15]) + w[i - 16]; + _ssig1(w, i - 4, _var, _t1); + _add(_var, _t1, w, i - 14, _var, _t2); + _ssig0(w, i - 30, _var, _t1); + _add(_var, _t1, w, i - 32, _var, _t3); + _add(_var, _t2, _var, _t3, w, i); + } + + for (int i = 0; i < 160; i += 2) { + // t1 = h + _bsig1(e) + _ch(e, f, g) + k[i] + w[i]; + _bsig1(_var, _e, _var, _t1); + _add(_var, _h, _var, _t1, _var, _t2); + _ch(_var, _e, _var, _f, _var, _g, _var, _t3); + _add(_var, _t2, _var, _t3, _var, _t4); + _add(_k, i, w, i, _var, _t5); + _add(_var, _t4, _var, _t5, _var, _t1); + + // t2 = _bsig0(A) + _maj(a, b, c); + _bsig0(_var, _a, _var, _t3); + _maj(_var, _a, _var, _b, _var, _c, _var, _t4); + _add(_var, _t3, _var, _t4, _var, _t2); + + // h = g; + _var[_h] = _var[_g]; + _var[_h + 1] = _var[_g + 1]; + // g = f; + _var[_g] = _var[_f]; + _var[_g + 1] = _var[_f + 1]; + // f = e; + _var[_f] = _var[_e]; + _var[_f + 1] = _var[_e + 1]; + // e = d + t1; + _add(_var, _d, _var, _t1, _var, _e); + // d = c; + _var[_d] = _var[_c]; + _var[_d + 1] = _var[_c + 1]; + // c = b; + _var[_c] = _var[_b]; + _var[_c + 1] = _var[_b + 1]; + // b = a; + _var[_b] = _var[_a]; + _var[_b + 1] = _var[_a + 1]; + // a = t1 + t2; + _add(_var, _t1, _var, _t2, _var, _a); + } + + _addAndSet(state, 0, _var, _a); + _addAndSet(state, 2, _var, _b); + _addAndSet(state, 4, _var, _c); + _addAndSet(state, 6, _var, _d); + _addAndSet(state, 8, _var, _e); + _addAndSet(state, 10, _var, _f); + _addAndSet(state, 12, _var, _g); + _addAndSet(state, 14, _var, _h); + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 112) { + for (; pos < 128; pos++) { + buffer[pos] = 0; + } + $update(buffer); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 120; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + int n = messageLengthInBits; + buffer[120] = n >>> 56; + buffer[121] = n >>> 48; + buffer[122] = n >>> 40; + buffer[123] = n >>> 32; + buffer[124] = n >>> 24; + buffer[125] = n >>> 16; + buffer[126] = n >>> 8; + buffer[127] = n; + + // Update with the final block + $update(buffer); + + // Convert the state to 8-bit byte array + var bytes = Uint8List(hashLength); + for (int j = 0, i = 0; j < hashLength; i++, j += 4) { + bytes[j] = state[i] >>> 24; + bytes[j + 1] = state[i] >>> 16; + bytes[j + 2] = state[i] >>> 8; + bytes[j + 3] = state[i]; + } + return bytes; + } +} diff --git a/hashlib/lib/src/algorithms/sha2/sha2_1024_64bit.dart b/hashlib/lib/src/algorithms/sha2/sha2_1024_64bit.dart new file mode 100644 index 0000000..383f6f7 --- /dev/null +++ b/hashlib/lib/src/algorithms/sha2/sha2_1024_64bit.dart @@ -0,0 +1,208 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +// Initialize array of round 64-bit constants +const List _k = [ + 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, // + 0xE9B5DBA58189DBBC, 0x3956C25BF348B538, 0x59F111F1B605D019, + 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118, 0xD807AA98A3030242, + 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2, + 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, + 0xC19BF174CF692694, 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, + 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65, 0x2DE92C6F592B0275, + 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5, + 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, + 0xBF597FC7BEEF0EE4, 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, + 0x06CA6351E003826F, 0x142929670A0E6E70, 0x27B70A8546D22FFC, + 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF, + 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, + 0x92722C851482353B, 0xA2BFE8A14CF10364, 0xA81A664BBC423001, + 0xC24B8B70D0F89791, 0xC76C51A30654BE30, 0xD192E819D6EF5218, + 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8, + 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, + 0x34B0BCB5E19B48A8, 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, + 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3, 0x748F82EE5DEFB2FC, + 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC, + 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, + 0xC67178F2E372532B, 0xCA273ECEEA26619C, 0xD186B8C721C0C207, + 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178, 0x06F067AA72176FBA, + 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B, + 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, + 0x431D67C49C100D4C, 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, + 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817, +]; + +/// Implementation is derived from [RFC6234][rfc6234] which follows the +/// [FIPS 180-4][fips180] standard for SHA and SHA-based HMAC and HKDF. +/// +/// It uses 64-bit integer operations internally which is not supported by +/// Web VM, but a lot faster. +/// +/// [rfc6234]: https://www.ietf.org/rfc/rfc6234.html +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +class SHA2of1024 extends BlockHashSink { + final List seed; + final Uint32List state; + final Uint64List chunk; + + @override + final int hashLength; + + /// For internal use only. + SHA2of1024({ + required this.seed, + required this.hashLength, + }) : chunk = Uint64List(80), + state = Uint32List.fromList(seed), + super(1024 >>> 3); + + @override + void reset() { + state.setAll(0, seed); + super.reset(); + } + + /// Rotates 64-bit number x by n bits + @pragma('vm:prefer-inline') + static int _bsig0(int x) => + ((x >>> 28) | (x << 36)) ^ + ((x >>> 34) | (x << 30)) ^ + ((x >>> 39) | (x << 25)); + + @pragma('vm:prefer-inline') + static int _bsig1(int x) => + ((x >>> 14) | (x << 50)) ^ + ((x >>> 18) | (x << 46)) ^ + ((x >>> 41) | (x << 23)); + + @pragma('vm:prefer-inline') + static int _ssig0(int x) => + ((x >>> 1) | (x << 63)) ^ ((x >>> 8) | (x << 56)) ^ (x >>> 7); + + @pragma('vm:prefer-inline') + static int _ssig1(int x) => + ((x >>> 19) | (x << 45)) ^ ((x >>> 61) | (x << 3)) ^ (x >>> 6); + + @override + void $update(List block, [int offset = 0, bool last = false]) { + // Convert the block to chunk + for (int i = 0, j = offset; i < 16; i++, j += 8) { + chunk[i] = ((block[j] & 0xFF) << 56) | + ((block[j + 1] & 0xFF) << 48) | + ((block[j + 2] & 0xFF) << 40) | + ((block[j + 3] & 0xFF) << 32) | + ((block[j + 4] & 0xFF) << 24) | + ((block[j + 5] & 0xFF) << 16) | + ((block[j + 6] & 0xFF) << 8) | + (block[j + 7] & 0xFF); + } + + var w = chunk; + int t1, t2, ch, maj; + int a, b, c, d, e, f, g, h; + int ta, tb, tc, td, te, tf, tg, th; + + ta = a = (state[0] << 32) | (state[1]); + tb = b = (state[2] << 32) | (state[3]); + tc = c = (state[4] << 32) | (state[5]); + td = d = (state[6] << 32) | (state[7]); + te = e = (state[8] << 32) | (state[9]); + tf = f = (state[10] << 32) | (state[11]); + tg = g = (state[12] << 32) | (state[13]); + th = h = (state[14] << 32) | (state[15]); + + // Extend the first 16 words into the 80 words (64-bit) + for (int i = 16; i < 80; i++) { + w[i] = _ssig1(w[i - 2]) + w[i - 7] + _ssig0(w[i - 15]) + w[i - 16]; + } + + for (int i = 0; i < 80; ++i) { + ch = (e & f) ^ ((~e) & g); + maj = (a & b) ^ (a & c) ^ (b & c); + t1 = h + _bsig1(e) + ch + _k[i] + w[i]; + t2 = _bsig0(a) + maj; + + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ta += a; + tb += b; + tc += c; + td += d; + te += e; + tf += f; + tg += g; + th += h; + state[0] = ta >>> 32; + state[1] = ta; + state[2] = tb >>> 32; + state[3] = tb; + state[4] = tc >>> 32; + state[5] = tc; + state[6] = td >>> 32; + state[7] = td; + state[8] = te >>> 32; + state[9] = te; + state[10] = tf >>> 32; + state[11] = tf; + state[12] = tg >>> 32; + state[13] = tg; + state[14] = th >>> 32; + state[15] = th; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 112) { + for (; pos < 128; pos++) { + buffer[pos] = 0; + } + $update(buffer); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 120; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + int n = messageLengthInBits; + buffer[120] = n >>> 56; + buffer[121] = n >>> 48; + buffer[122] = n >>> 40; + buffer[123] = n >>> 32; + buffer[124] = n >>> 24; + buffer[125] = n >>> 16; + buffer[126] = n >>> 8; + buffer[127] = n; + + // Update with the final block + $update(buffer); + + // Convert the state to 8-bit byte array + var bytes = Uint8List(hashLength); + for (int j = 0, i = 0; j < hashLength; i++, j += 4) { + bytes[j] = state[i] >>> 24; + bytes[j + 1] = state[i] >>> 16; + bytes[j + 2] = state[i] >>> 8; + bytes[j + 3] = state[i]; + } + return bytes; + } +} diff --git a/hashlib/lib/src/algorithms/sha2/sha2_512.dart b/hashlib/lib/src/algorithms/sha2/sha2_512.dart new file mode 100644 index 0000000..1109da3 --- /dev/null +++ b/hashlib/lib/src/algorithms/sha2/sha2_512.dart @@ -0,0 +1,179 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +// Initialize array of round constants +const List _k = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, // + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, +]; + +/// Implementation is derived from [RFC6234][rfc6234] which follows the +/// [FIPS 180-4][fips180] standard for SHA and SHA-based HMAC and HKDF. +/// +/// [rfc6234]: https://www.ietf.org/rfc/rfc6234.html +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +class SHA2of512 extends BlockHashSink { + final List seed; + final Uint32List state; + final Uint32List chunk; + + @override + final int hashLength; + + /// For internal use only. + SHA2of512({ + required this.seed, + required this.hashLength, + }) : chunk = Uint32List(64), + state = Uint32List.fromList(seed), + super(64); + + @override + void reset() { + state.setAll(0, seed); + super.reset(); + } + + /// Rotates x right by n bits. + @pragma('vm:prefer-inline') + static int _bsig0(int x) => + (((x & _mask32) >>> 2) | ((x << 30) & _mask32)) ^ + (((x & _mask32) >>> 13) | ((x << 19) & _mask32)) ^ + (((x & _mask32) >>> 22) | ((x << 10) & _mask32)); + + @pragma('vm:prefer-inline') + static int _bsig1(int x) => + (((x & _mask32) >>> 6) | ((x << 26) & _mask32)) ^ + (((x & _mask32) >>> 11) | ((x << 21) & _mask32)) ^ + (((x & _mask32) >>> 25) | ((x << 7) & _mask32)); + + @pragma('vm:prefer-inline') + static int _ssig0(int x) => + (((x & _mask32) >>> 7) | ((x << 25) & _mask32)) ^ + (((x & _mask32) >>> 18) | ((x << 14) & _mask32)) ^ + (x >>> 3); + + @pragma('vm:prefer-inline') + static int _ssig1(int x) => + (((x & _mask32) >>> 17) | ((x << 15) & _mask32)) ^ + (((x & _mask32) >>> 19) | ((x << 13) & _mask32)) ^ + (x >>> 10); + + @override + void $update(List block, [int offset = 0, bool last = false]) { + // Convert the block to chunk + for (int i = 0, j = offset; i < 16; i++, j += 4) { + chunk[i] = ((block[j] & 0xFF) << 24) | + ((block[j + 1] & 0xFF) << 16) | + ((block[j + 2] & 0xFF) << 8) | + (block[j + 3] & 0xFF); + } + + var w = chunk; + int t1, t2, ch, maj; + int a, b, c, d, e, f, g, h; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + // Extend the first 16 words into the 64 words + for (int i = 16; i < 64; i++) { + w[i] = _ssig1(w[i - 2]) + w[i - 7] + _ssig0(w[i - 15]) + w[i - 16]; + } + + for (int i = 0; i < 64; ++i) { + ch = (e & f) ^ ((~e) & g); + maj = (a & b) ^ (a & c) ^ (b & c); + t1 = h + _bsig1(e) + ch + _k[i] + w[i]; + t2 = _bsig0(a) + maj; + + h = g; + g = f; + f = e; + e = (d + t1) & _mask32; + d = c; + c = b; + b = a; + a = (t1 + t2) & _mask32; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(buffer); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + int n = messageLengthInBits; + buffer[56] = n >>> 56; + buffer[57] = n >>> 48; + buffer[58] = n >>> 40; + buffer[59] = n >>> 32; + buffer[60] = n >>> 24; + buffer[61] = n >>> 16; + buffer[62] = n >>> 8; + buffer[63] = n; + + // Update with the final block + $update(buffer); + + // Convert the state to 8-bit byte array + var bytes = Uint8List(hashLength); + for (int j = 0, i = 0; j < hashLength; i++, j += 4) { + bytes[j] = state[i] >>> 24; + bytes[j + 1] = state[i] >>> 16; + bytes[j + 2] = state[i] >>> 8; + bytes[j + 3] = state[i]; + } + return bytes; + } +} diff --git a/hashlib/lib/src/algorithms/sha3.dart b/hashlib/lib/src/algorithms/sha3.dart new file mode 100644 index 0000000..a4c0c29 --- /dev/null +++ b/hashlib/lib/src/algorithms/sha3.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'keccak/keccak.dart'; + +/// Implementation of 224-bit hash generator based on [KeccakHash] +/// with SHA3 padding. +class SHA3d224Hash extends KeccakHash { + SHA3d224Hash() + : super( + stateSize: 224 >>> 3, + paddingByte: 0x06, + ); +} + +/// Implementation of 256-bit hash generator based on [KeccakHash] +/// with SHA3 padding. +class SHA3d256Hash extends KeccakHash { + SHA3d256Hash() + : super( + stateSize: 256 >>> 3, + paddingByte: 0x06, + ); +} + +/// Implementation of 384-bit hash generator based on [KeccakHash] +/// with SHA3 padding. +class SHA3d384Hash extends KeccakHash { + SHA3d384Hash() + : super( + stateSize: 384 >>> 3, + paddingByte: 0x06, + ); +} + +/// Implementation of 512-bit hash generator based on [KeccakHash] +/// with SHA3 padding. +class SHA3d512Hash extends KeccakHash { + SHA3d512Hash() + : super( + stateSize: 512 >>> 3, + paddingByte: 0x06, + ); +} diff --git a/hashlib/lib/src/algorithms/shake.dart b/hashlib/lib/src/algorithms/shake.dart new file mode 100644 index 0000000..0de8aca --- /dev/null +++ b/hashlib/lib/src/algorithms/shake.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'keccak/keccak.dart'; + +/// Implementation of 128-bit arbitrary hash generator based on [KeccakHash]. +class Shake128Hash extends KeccakHash { + /// Create a SHAKE-128 hash generator with arbitrary output size. + /// + /// If [outputLengthInBytes] is 0, it will generate an infinite sequence of + /// numbers with generate(), but the digest() will return an empty string. + /// + /// If [outputLengthInBytes] is null, 128-bit output is generated by default. + Shake128Hash([int? outputLengthInBytes]) + : super( + stateSize: 128 >>> 3, + paddingByte: 0x1f, + outputSize: outputLengthInBytes, + ); +} + +/// Implementation of 256-bit arbitrary hash generator based on [KeccakHash]. +class Shake256Hash extends KeccakHash { + /// Create a SHAKE-256 hash generator with arbitrary output size. + /// + /// If [outputLengthInBytes] is 0, it will generate an infinite sequence of + /// numbers with generate(), but the digest() will return an empty string. + /// + /// If [outputLengthInBytes] is null, 256-bit output is generated by default. + Shake256Hash([int? outputLengthInBytes]) + : super( + stateSize: 256 >>> 3, + paddingByte: 0x1f, + outputSize: outputLengthInBytes, + ); +} diff --git a/hashlib/lib/src/algorithms/sm3.dart b/hashlib/lib/src/algorithms/sm3.dart new file mode 100644 index 0000000..69899b8 --- /dev/null +++ b/hashlib/lib/src/algorithms/sm3.dart @@ -0,0 +1,176 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const _iv = [ + 0x7380166f, + 0x4914b2b9, + 0x172442d7, + 0xda8a0600, + 0xa96f30bc, + 0x163138aa, + 0xe38dee4d, + 0xb0fb0e4e, +]; + +/// This implementation is derived from the draft of +/// [The SM3 Cryptographic Hash Function][rfc]. +/// +/// [rfc]: https://datatracker.ietf.org/doc/draft-sca-cfrg-sm3/ +class SM3Hash extends BlockHashSink { + final Uint32List state; + + @override + final int hashLength; + + SM3Hash() + : state = Uint32List.fromList(_iv), + hashLength = 256 >>> 3, + super( + 512 >>> 3, + bufferLength: 68 << 2, + ); + + @override + void reset() { + state.setAll(0, _iv); + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(buffer); + pos = 0; + } + } + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + @pragma('vm:prefer-inline') + static int _swap32(int x) => + ((x << 24) & 0xff000000) | + ((x << 8) & 0x00ff0000) | + ((x >>> 8) & 0x0000ff00) | + ((x >>> 24) & 0x000000ff); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int a, b, c, d, e, f, g, h; + int i, t, ss1, ss2, tt1, tt2; + var x = sbuffer; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + // Message Expansion + for (i = 0; i < 16; i++) { + x[i] = _swap32(x[i]); + } + for (i = 16; i < 68; i++) { + t = x[i - 16] ^ x[i - 9] ^ _rotl32(x[i - 3], 15); + t ^= _rotl32(t, 15) ^ _rotl32(t, 23); + t ^= _rotl32(x[i - 13], 7) ^ x[i - 6]; + x[i] = t; + } + + // Compression Function + for (i = 0; i < 16; i++) { + t = _rotl32(a, 12) + e + _rotl32(0x79cc4519, i); + ss1 = _rotl32(t, 7); + ss2 = ss1 ^ _rotl32(a, 12); + t = a ^ b ^ c; + tt1 = (t + d + ss2 + (x[i] ^ x[i + 4])) & _mask32; + t = e ^ f ^ g; + tt2 = (t + h + ss1 + x[i]) & _mask32; + d = c; + c = _rotl32(b, 9); + b = a; + a = tt1; + h = g; + g = _rotl32(f, 19); + f = e; + e = tt2 ^ _rotl32(tt2, 9) ^ _rotl32(tt2, 17); + } + for (i = 16; i < 64; i++) { + t = _rotl32(a, 12) + e + _rotl32(0x7a879d8a, i & 31); + ss1 = _rotl32(t, 7); + ss2 = ss1 ^ _rotl32(a, 12); + t = (a & b) | (b & c) | (c & a); + tt1 = (t + d + ss2 + (x[i] ^ x[i + 4])) & _mask32; + t = (e & f) | (g & (~e)); + tt2 = (t + h + ss1 + x[i]) & _mask32; + d = c; + c = _rotl32(b, 9); + b = a; + a = tt1; + h = g; + g = _rotl32(f, 19); + f = e; + e = tt2 ^ _rotl32(tt2, 9) ^ _rotl32(tt2, 17); + } + + state[0] ^= a; + state[1] ^= b; + state[2] ^= c; + state[3] ^= d; + state[4] ^= e; + state[5] ^= f; + state[6] ^= g; + state[7] ^= h; + } + + @override + Uint8List $finalize() { + // Adding the signature byte + buffer[pos++] = 0x80; + + // If no more space left in buffer for the message length + if (pos > 56) { + for (; pos < 64; pos++) { + buffer[pos] = 0; + } + $update(); + pos = 0; + } + + // Fill remaining buffer to put the message length at the end + for (; pos < 56; pos++) { + buffer[pos] = 0; + } + + // Append original message length in bits to message + bdata.setUint32(56, messageLengthInBits >>> 32, Endian.big); + bdata.setUint32(60, messageLengthInBits, Endian.big); + + // Update with the final block + $update(); + + // Convert the state to 8-bit byte array + var output = Uint32List(hashLength >>> 2); + for (int i = 0; i < output.length; i++) { + output[i] = _swap32(state[i]); + } + return Uint8List.view(output.buffer); + } +} diff --git a/hashlib/lib/src/algorithms/xxh3/xxh3_128.dart b/hashlib/lib/src/algorithms/xxh3/xxh3_128.dart new file mode 100644 index 0000000..68e2d11 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh3/xxh3_128.dart @@ -0,0 +1,4 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'xxh3_128_64bit.dart' if (dart.library.js) 'xxh3_128_32bit.dart'; diff --git a/hashlib/lib/src/algorithms/xxh3/xxh3_128_32bit.dart b/hashlib/lib/src/algorithms/xxh3/xxh3_128_32bit.dart new file mode 100644 index 0000000..1ee4f68 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh3/xxh3_128_32bit.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +/// Stub for 32-bit machines. +class XXH3Sink128bit extends BlockHashSink { + @override + final int hashLength = 16; + + factory XXH3Sink128bit.withSeed(int seed) { + seed; + throw UnimplementedError('XXH3-128 is not supported in Node platform'); + } + + factory XXH3Sink128bit.withSecret([List? secret]) { + secret; + throw UnimplementedError('XXH3-128 is not supported in Node platform'); + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + throw UnimplementedError('XXH3-128 is not supported in Node platform'); + } + + @override + Uint8List $finalize() { + throw UnimplementedError('XXH3-128 is not supported in Node platform'); + } +} diff --git a/hashlib/lib/src/algorithms/xxh3/xxh3_128_64bit.dart b/hashlib/lib/src/algorithms/xxh3/xxh3_128_64bit.dart new file mode 100644 index 0000000..7439fc5 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh3/xxh3_128_64bit.dart @@ -0,0 +1,509 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:collection'; +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const int _stripeLen = 64; +const int _midsizeMax = 240; +const int _minSecretSize = 136; + +// Pseudorandom secret taken directly from FARSH (little-endian) +const List _kSecret = [ + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, // + 0xf7, 0x21, 0xad, 0x1c, 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, + 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, 0xcb, 0x79, 0xe6, 0x4e, + 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, + 0x81, 0x3a, 0x26, 0x4c, 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, + 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, 0x71, 0x64, 0x48, 0x97, + 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, + 0xc7, 0x0b, 0x4f, 0x1d, 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, + 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, 0xea, 0xc5, 0xac, 0x83, + 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, + 0x29, 0xd4, 0x68, 0x9e, 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, + 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, 0x45, 0xcb, 0x3a, 0x8f, + 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, +]; + +/// This implementation is derived from +/// https://github.com/RedSpah/xxhash_cpp/blob/master/include/xxhash.hpp +class XXH3Sink128bit extends BlockHashSink { + final int seed; + final int rounds; + final Uint8List secret; + final Uint64List state = Uint64List(8); + final ListQueue last = ListQueue(_midsizeMax); + late final Uint64List qbuffer = Uint64List.view(buffer.buffer); + late final Uint64List secret64 = Uint64List.view(secret.buffer); + late final ByteData secretBD = secret.buffer.asByteData(); + + @override + final int hashLength = 16; + + static const int prime32_1 = 0x9E3779B1; + static const int prime32_2 = 0x85EBCA77; + static const int prime32_3 = 0xC2B2AE3D; + static const int prime64_1 = 0x9E3779B185EBCA87; + static const int prime64_2 = 0xC2B2AE3D27D4EB4F; + static const int prime64_3 = 0x165667B19E3779F9; + static const int prime64_4 = 0x85EBCA77C2B2AE63; + static const int prime64_5 = 0x27D4EB2F165667C5; + + factory XXH3Sink128bit.withSeed(int seed) { + if (seed == 0) { + return XXH3Sink128bit.withSecret(); + } + var secret = Uint8List.fromList(_kSecret); + var secret64 = Uint64List.view(secret.buffer); + for (int i = 0; i < secret64.length; i += 2) { + secret64[i] += seed; + } + for (int i = 1; i < secret64.length; i += 2) { + secret64[i] -= seed; + } + return XXH3Sink128bit._( + seed: seed, + secret: secret, + rounds: (secret.lengthInBytes - _stripeLen) >>> 3, + ); + } + + factory XXH3Sink128bit.withSecret([List? secret]) { + var key = Uint8List.fromList(secret ?? _kSecret); + if (key.lengthInBytes < _minSecretSize) { + throw ArgumentError('The secret length must be at least $_minSecretSize'); + } + return XXH3Sink128bit._( + seed: 0, + secret: key, + rounds: (key.lengthInBytes - _stripeLen) >>> 3, + ); + } + + XXH3Sink128bit._({ + required this.seed, + required this.secret, + required this.rounds, + }) : super(rounds << 6) { + reset(); + } + + @override + void reset() { + state[0] = prime32_3; + state[1] = prime64_1; + state[2] = prime64_2; + state[3] = prime64_3; + state[4] = prime64_4; + state[5] = prime32_2; + state[6] = prime64_5; + state[7] = prime32_1; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + if (last.length == _midsizeMax) { + last.removeFirst(); + } + last.add(chunk[start]); + } + } + + @pragma('vm:prefer-inline') + static int _crossSwap(int x) => (x & _mask32) * (x >>> 32); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int n, i, v, l, k; + // accumulate + for (n = 0; n < rounds; n++) { + l = n << 3; + for (i = 0; i < state.length; i++) { + v = qbuffer[l + i]; + state[i ^ 1] += v; + v ^= secret64[n + i]; + state[i] += _crossSwap(v); + } + } + // scramble + k = secret.lengthInBytes - _stripeLen; + for (i = 0; i < 8; ++i) { + state[i] ^= state[i] >>> 47; + state[i] ^= secretBD.getUint64(k + (i << 3), Endian.little); + state[i] *= prime32_1; + } + } + + @pragma('vm:prefer-inline') + static int _avalanche(int hash) { + hash ^= hash >>> 37; + hash *= 0x165667919E3779F9; + hash ^= hash >>> 32; + return hash; + } + + @pragma('vm:prefer-inline') + static int _midsizeAvalanche(int hash) { + hash ^= hash >>> 33; + hash *= prime64_2; + hash ^= hash >>> 29; + hash *= prime64_3; + hash ^= hash >>> 32; + return hash; + } + + @pragma('vm:prefer-inline') + static Uint8List _combine(int a, int b) { + return Uint8List.fromList([ + b >>> 56, + b >>> 48, + b >>> 40, + b >>> 32, + b >>> 24, + b >>> 16, + b >>> 8, + b, + a >>> 56, + a >>> 48, + a >>> 40, + a >>> 32, + a >>> 24, + a >>> 16, + a >>> 8, + a, + ]); + } + + Uint8List _finalizeLong(Uint64List stripe) { + // XXH3_hashLong_128b + int low, high; + int t, n, i, v, l, a, b; + const int lastAccStart = 7; + const int mergeAccStart = 11; + + // accumulate last partial block + for (t = n = 0; t + _stripeLen < pos; n++, t += _stripeLen) { + l = n << 3; + for (i = 0; i < state.length; i++) { + v = qbuffer[l + i]; + state[i ^ 1] += v; + v ^= secret64[n + i]; + state[i] += _crossSwap(v); + } + } + + // last stripe + t = secret.lengthInBytes - _stripeLen - lastAccStart; + for (i = 0; i < state.length; i++, t += 8) { + v = stripe[i]; + state[i ^ 1] += v; + v ^= secretBD.getUint64(t, Endian.little); + state[i] += _crossSwap(v); + } + + // converge into final hash + low = messageLength * prime64_1; + high = ~(messageLength * prime64_2); + t = mergeAccStart; + for (i = 0; i < 8; i += 2, t += 16) { + a = secretBD.getUint64(t, Endian.little); + b = secretBD.getUint64(t + 8, Endian.little); + low += _mul128fold64(state[i] ^ a, state[i + 1] ^ b); + } + t = secret.lengthInBytes - _stripeLen - mergeAccStart; + for (i = 0; i < 8; i += 2, t += 16) { + a = secretBD.getUint64(t, Endian.little); + b = secretBD.getUint64(t + 8, Endian.little); + high += _mul128fold64(state[i] ^ a, state[i + 1] ^ b); + } + + // avalanche + return _combine(_avalanche(low), _avalanche(high)); + } + + @pragma('vm:prefer-inline') + static int _swap32(int x) => + ((x << 24) & 0xff000000) | + ((x << 8) & 0x00ff0000) | + ((x >>> 8) & 0x0000ff00) | + ((x >>> 24) & 0x000000ff); + + @pragma('vm:prefer-inline') + static int _swap64(int x) => + ((x << 56) & 0xff00000000000000) | + ((x << 40) & 0x00ff000000000000) | + ((x << 24) & 0x0000ff0000000000) | + ((x << 8) & 0x000000ff00000000) | + ((x >>> 8) & 0x00000000ff000000) | + ((x >>> 24) & 0x0000000000ff0000) | + ((x >>> 40) & 0x000000000000ff00) | + ((x >>> 56) & 0x00000000000000ff); + + @pragma('vm:prefer-inline') + static int _rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + // Multiply two 64-bit numbers to get 128-bit number + static void _mul128(int a, int b, Uint64List result) { + int al, ah, bl, bh, ll, hl, lh, hh, cross; + + al = a & _mask32; + ah = a >>> 32; + bl = b & _mask32; + bh = b >>> 32; + + ll = al * bl; + hl = ah * bl; + lh = al * bh; + hh = ah * bh; + + cross = (ll >>> 32) + (hl & _mask32) + lh; + result[0] = (cross << 32) | (ll & _mask32); + result[1] = (hl >>> 32) + (cross >>> 32) + hh; + } + + // Multiply two 64-bit numbers to get 128-bit number and + // xor the low bits of the product with the high bits + static int _mul128fold64(int a, int b) { + int al, ah, bl, bh, ll, hl, lh, hh, cross, upper, lower; + + al = a & _mask32; + ah = a >>> 32; + bl = b & _mask32; + bh = b >>> 32; + + ll = al * bl; + hl = ah * bl; + lh = al * bh; + hh = ah * bh; + + cross = (ll >>> 32) + (hl & _mask32) + lh; + upper = (hl >>> 32) + (cross >>> 32) + hh; + lower = (cross << 32) | (ll & _mask32); + + return upper ^ lower; + } + + static int _mix16B(ByteData input, int i, ByteData key, int j, int seed) { + int lhs, rhs; + lhs = key.getUint64(j, Endian.little) + seed; + rhs = key.getUint64(j + 8, Endian.little) - seed; + lhs ^= input.getUint64(i, Endian.little); + rhs ^= input.getUint64(i + 8, Endian.little); + return _mul128fold64(lhs, rhs); + } + + static void _mix32B( + Uint64List acc, + ByteData input, + int a, + int b, + ByteData key, + int c, + int seed, + ) { + acc[0] += _mix16B(input, a, key, c, seed); + acc[0] ^= input.getUint64(b, Endian.little) + + input.getUint64(b + 8, Endian.little); + acc[1] += _mix16B(input, b, key, c + 16, seed); + acc[1] ^= input.getUint64(a, Endian.little) + + input.getUint64(a + 8, Endian.little); + } + + Uint8List _finalizeShort(ByteData input, int length, ByteData key) { + int low, high; + int i, lhs, rhs, a, b, c, x, y; + Uint64List acc = Uint64List(2); + if (length == 0) { + // hash_t len_0to16 + low = seed; + low ^= key.getUint64(64, Endian.little); + low ^= key.getUint64(72, Endian.little); + + high = seed; + high ^= key.getUint64(80, Endian.little); + high ^= key.getUint64(88, Endian.little); + + low = _midsizeAvalanche(low); + high = _midsizeAvalanche(high); + } else if (length <= 3) { + // hash_t len_1to3 + a = input.getUint8(0); + b = input.getUint8(length >>> 1); + c = input.getUint8(length - 1); + x = (a << 16) | (b << 24) | (c) | (length << 8); + y = _rotl32(_swap32(x), 13); + + low = key.getUint32(0, Endian.little); + low ^= key.getUint32(4, Endian.little); + low += seed; + low ^= x; + + high = key.getUint32(8, Endian.little); + high ^= key.getUint32(12, Endian.little); + high -= seed; + high ^= y; + + low = _midsizeAvalanche(low); + high = _midsizeAvalanche(high); + } else if (length <= 8) { + // hash_t len_4to8 + lhs = input.getUint32(0, Endian.little); + rhs = input.getUint32(length - 4, Endian.little); + + x = key.getUint64(16, Endian.little); + x ^= key.getUint64(24, Endian.little); + x += seed ^ (_swap32(seed & _mask32) << 32); + x ^= (rhs << 32) | lhs; + + _mul128(x, prime64_1 + (length << 2), acc); + low = acc[0]; + high = acc[1]; + + high += low << 1; + low ^= high >>> 3; + low ^= low >>> 35; + low *= 0x9FB21C651E98DF25; + low ^= low >>> 28; + + high = _avalanche(high); + } else if (length <= 16) { + // hash_t len_9to16 + lhs = key.getUint64(32, Endian.little); + lhs ^= key.getUint64(40, Endian.little); + lhs -= seed; + lhs ^= input.getUint64(0, Endian.little); + lhs ^= input.getUint64(length - 8, Endian.little); + + rhs = key.getUint64(48, Endian.little); + rhs ^= key.getUint64(56, Endian.little); + rhs += seed; + rhs ^= input.getUint64(length - 8, Endian.little); + + _mul128(lhs, prime64_1, acc); + low = acc[0]; + high = acc[1]; + low += length - 1 << 54; + high += (rhs & (_mask32 << 32)) + ((rhs & _mask32) * prime32_2); + + low ^= _swap64(high); + _mul128(low, prime64_2, acc); + low = acc[0]; + high = acc[1] + (high * prime64_2); + + low = _avalanche(low); + high = _avalanche(high); + } else if (length <= 128) { + // hash_t len_17to128 + acc[0] = length * prime64_1; + acc[1] = 0; + if (length > 32) { + if (length > 64) { + if (length > 96) { + _mix32B(acc, input, 48, length - 64, key, 96, seed); + } + _mix32B(acc, input, 32, length - 48, key, 64, seed); + } + _mix32B(acc, input, 16, length - 32, key, 32, seed); + } + _mix32B(acc, input, 0, length - 16, key, 0, seed); + + low = acc[0] + acc[1]; + high = acc[0] * prime64_1 + acc[1] * prime64_4; + high += (length - seed) * prime64_2; + low = _avalanche(low); + high = -_avalanche(high); + } else { + // hash_t len_129to240 + const int startOffset = 3; + const int lastOffset = 17; + acc[0] = length * prime64_1; + acc[1] = 0; + // first 128 bytes + for (i = 0; i < 128; i += 32) { + _mix32B( + acc, + input, + i, + i + 16, + key, + i, + seed, + ); + } + acc[0] = _avalanche(acc[0]); + acc[1] = _avalanche(acc[1]); + // remaining bytes + for (i = 128; i + 32 <= length; i += 32) { + _mix32B( + acc, + input, + i, + i + 16, + key, + startOffset + i - 128, + seed, + ); + } + // last byte + _mix32B( + acc, + input, + length - 16, + length - 32, + key, + _minSecretSize - lastOffset - 16, + -seed, + ); + // mid-range avalanche + low = _avalanche(acc[0] + acc[1]); + high = acc[1] * prime64_4; + high += acc[0] * prime64_1; + high += (length - seed) * prime64_2; + high = -_avalanche(high); + } + // combine + return _combine(low, high); + } + + @override + Uint8List $finalize() { + int i; + ByteData key; + Uint64List input = Uint64List(_midsizeMax >>> 3); + Uint8List input8 = Uint8List.view(input.buffer); + + if (messageLength <= _midsizeMax) { + var it = last.iterator; + for (i = 0; it.moveNext(); ++i) { + input8[i] = it.current; + } + if (seed == 0) { + key = secretBD; + } else { + key = Uint8List.fromList(_kSecret).buffer.asByteData(); + } + return _finalizeShort(input.buffer.asByteData(), i, key); + } else { + for (i = _stripeLen - 1; i >= 0; --i) { + input8[i] = last.removeLast(); + } + return _finalizeLong(input); + } + } +} diff --git a/hashlib/lib/src/algorithms/xxh3/xxh3_64.dart b/hashlib/lib/src/algorithms/xxh3/xxh3_64.dart new file mode 100644 index 0000000..8e5d659 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh3/xxh3_64.dart @@ -0,0 +1,4 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'xxh3_64_64bit.dart' if (dart.library.js) 'xxh3_64_32bit.dart'; diff --git a/hashlib/lib/src/algorithms/xxh3/xxh3_64_32bit.dart b/hashlib/lib/src/algorithms/xxh3/xxh3_64_32bit.dart new file mode 100644 index 0000000..98cc433 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh3/xxh3_64_32bit.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +/// Stub for 32-bit machines. +class XXH3Sink64bit extends BlockHashSink { + @override + final int hashLength = 8; + + factory XXH3Sink64bit.withSeed(int seed) { + seed; + throw UnimplementedError('XXH3 is not supported in Node platform'); + } + + factory XXH3Sink64bit.withSecret([List? secret]) { + secret; + throw UnimplementedError('XXH3 is not supported in Node platform'); + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + throw UnimplementedError('XXH3 is not supported in Node platform'); + } + + @override + Uint8List $finalize() { + throw UnimplementedError('XXH3 is not supported in Node platform'); + } +} diff --git a/hashlib/lib/src/algorithms/xxh3/xxh3_64_64bit.dart b/hashlib/lib/src/algorithms/xxh3/xxh3_64_64bit.dart new file mode 100644 index 0000000..b1923d2 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh3/xxh3_64_64bit.dart @@ -0,0 +1,391 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:collection'; +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const int _stripeLen = 64; +const int _midsizeMax = 240; +const int _minSecretSize = 136; + +// Pseudorandom secret taken directly from FARSH (little-endian) +const List _kSecret = [ + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, // + 0xf7, 0x21, 0xad, 0x1c, 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, + 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, 0xcb, 0x79, 0xe6, 0x4e, + 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, + 0x81, 0x3a, 0x26, 0x4c, 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, + 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, 0x71, 0x64, 0x48, 0x97, + 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, + 0xc7, 0x0b, 0x4f, 0x1d, 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, + 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, 0xea, 0xc5, 0xac, 0x83, + 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, + 0x29, 0xd4, 0x68, 0x9e, 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, + 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, 0x45, 0xcb, 0x3a, 0x8f, + 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, +]; + +/// This implementation is derived from +/// https://github.com/RedSpah/xxhash_cpp/blob/master/include/xxhash.hpp +class XXH3Sink64bit extends BlockHashSink { + final int seed; + final int rounds; + final Uint8List secret; + final Uint64List acc = Uint64List(8); + final ListQueue last = ListQueue(_midsizeMax); + late final Uint64List qbuffer = Uint64List.view(buffer.buffer); + late final Uint64List secret64 = Uint64List.view(secret.buffer); + late final ByteData secretBD = secret.buffer.asByteData(); + + @override + final int hashLength = 8; + + static const int prime32_1 = 0x9E3779B1; + static const int prime32_2 = 0x85EBCA77; + static const int prime32_3 = 0xC2B2AE3D; + static const int prime64_1 = 0x9E3779B185EBCA87; + static const int prime64_2 = 0xC2B2AE3D27D4EB4F; + static const int prime64_3 = 0x165667B19E3779F9; + static const int prime64_4 = 0x85EBCA77C2B2AE63; + static const int prime64_5 = 0x27D4EB2F165667C5; + + factory XXH3Sink64bit.withSeed(int seed) { + if (seed == 0) { + return XXH3Sink64bit.withSecret(); + } + var secret = Uint8List.fromList(_kSecret); + var secret64 = Uint64List.view(secret.buffer); + for (int i = 0; i < secret64.length; i += 2) { + secret64[i] += seed; + } + for (int i = 1; i < secret64.length; i += 2) { + secret64[i] -= seed; + } + return XXH3Sink64bit._( + seed: seed, + secret: secret, + rounds: (secret.lengthInBytes - _stripeLen) >>> 3, + ); + } + + factory XXH3Sink64bit.withSecret([List? secret]) { + var key = Uint8List.fromList(secret ?? _kSecret); + if (key.lengthInBytes < _minSecretSize) { + throw ArgumentError('The secret length must be at least $_minSecretSize'); + } + return XXH3Sink64bit._( + seed: 0, + secret: key, + rounds: (key.lengthInBytes - _stripeLen) >>> 3, + ); + } + + XXH3Sink64bit._({ + required this.seed, + required this.secret, + required this.rounds, + }) : super(rounds << 6) { + reset(); + } + + @override + void reset() { + acc[0] = prime32_3; + acc[1] = prime64_1; + acc[2] = prime64_2; + acc[3] = prime64_3; + acc[4] = prime64_4; + acc[5] = prime32_2; + acc[6] = prime64_5; + acc[7] = prime32_1; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + if (last.length == _midsizeMax) { + last.removeFirst(); + } + last.add(chunk[start]); + } + } + + @pragma('vm:prefer-inline') + static int _crossSwap(int x) => (x & _mask32) * (x >>> 32); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + int n, i, v, l, k; + // accumulate + for (n = 0; n < rounds; n++) { + l = n << 3; + for (i = 0; i < acc.length; i++) { + v = qbuffer[l + i]; + acc[i ^ 1] += v; + v ^= secret64[n + i]; + acc[i] += _crossSwap(v); + } + } + // scramble + k = secret.lengthInBytes - _stripeLen; + for (i = 0; i < 8; ++i) { + acc[i] ^= acc[i] >>> 47; + acc[i] ^= secretBD.getUint64(k + (i << 3), Endian.little); + acc[i] *= prime32_1; + } + } + + @pragma('vm:prefer-inline') + static int _avalanche(int hash) { + hash ^= hash >>> 37; + hash *= 0x165667919E3779F9; + hash ^= hash >>> 32; + return hash; + } + + @pragma('vm:prefer-inline') + static int _midsizeAvalanche(int hash) { + hash ^= hash >>> 33; + hash *= prime64_2; + hash ^= hash >>> 29; + hash *= prime64_3; + hash ^= hash >>> 32; + return hash; + } + + @pragma('vm:prefer-inline') + static int _rrmxmx(int hash, int length) { + hash ^= _rotl64(hash, 49) ^ _rotl64(hash, 24); + hash *= 0x9FB21C651E98DF25; + hash ^= (hash >>> 35) + length; + hash *= 0x9FB21C651E98DF25; + hash ^= hash >>> 28; + return hash; + } + + int _finalizeLong(Uint64List stripe) { + // void hash_long_internal_loop + int hash; + int t, n, i, v, l, a, b; + const int lastAccStart = 7; + const int mergeAccStart = 11; + + // last partial block + for (t = n = 0; t + _stripeLen < pos; n++, t += _stripeLen) { + l = n << 3; + for (i = 0; i < acc.length; i++) { + v = qbuffer[l + i]; + acc[i ^ 1] += v; + v ^= secret64[n + i]; + acc[i] += _crossSwap(v); + } + } + + // last stripe + t = secret.lengthInBytes - _stripeLen - lastAccStart; + for (i = 0; i < acc.length; i++, t += 8) { + v = stripe[i]; + acc[i ^ 1] += v; + v ^= secretBD.getUint64(t, Endian.little); + acc[i] += _crossSwap(v); + } + + // converge into final hash: uint64_t merge_accs + hash = messageLength * prime64_1; + t = mergeAccStart; + for (i = 0; i < 8; i += 2, t += 16) { + a = acc[i] ^ secretBD.getUint64(t, Endian.little); + b = acc[i + 1] ^ secretBD.getUint64(t + 8, Endian.little); + hash += _mul128fold64(a, b); + } + + // avalanche + return _avalanche(hash); + } + + @pragma('vm:prefer-inline') + static int _swap32(int x) => + ((x << 24) & 0xff000000) | + ((x << 8) & 0x00ff0000) | + ((x >>> 8) & 0x0000ff00) | + ((x >>> 24) & 0x000000ff); + + @pragma('vm:prefer-inline') + static int _swap64(int x) => + ((x << 56) & 0xff00000000000000) | + ((x << 40) & 0x00ff000000000000) | + ((x << 24) & 0x0000ff0000000000) | + ((x << 8) & 0x000000ff00000000) | + ((x >>> 8) & 0x00000000ff000000) | + ((x >>> 24) & 0x0000000000ff0000) | + ((x >>> 40) & 0x000000000000ff00) | + ((x >>> 56) & 0x00000000000000ff); + + @pragma('vm:prefer-inline') + static int _rotl64(int x, int n) => (x << n) | (x >>> (64 - n)); + + // Multiply two 64-bit numbers to get 128-bit number and + // xor the low bits of the product with the high bits + static int _mul128fold64(int a, int b) { + int al, ah, bl, bh, ll, hl, lh, hh, cross, upper, lower; + + al = a & _mask32; + ah = a >>> 32; + bl = b & _mask32; + bh = b >>> 32; + + ll = al * bl; + hl = ah * bl; + lh = al * bh; + hh = ah * bh; + + cross = (ll >>> 32) + (hl & _mask32) + lh; + upper = (hl >>> 32) + (cross >>> 32) + hh; + lower = (cross << 32) | (ll & _mask32); + + return upper ^ lower; + } + + static int _mix16B(ByteData input, int i, ByteData key, int j, int seed) { + int lhs, rhs; + lhs = input.getUint64(i, Endian.little); + rhs = input.getUint64(i + 8, Endian.little); + lhs ^= key.getUint64(j, Endian.little) + seed; + rhs ^= key.getUint64(j + 8, Endian.little) - seed; + return _mul128fold64(lhs, rhs); + } + + int _finalizeShort(ByteData input, int length, ByteData key) { + int hash, lhs, rhs, a, b, c, i; + if (length == 0) { + // hash_t len_0to16 + hash = seed; + hash ^= key.getUint64(56, Endian.little); + hash ^= key.getUint64(64, Endian.little); + return _midsizeAvalanche(hash); + } else if (length <= 3) { + // hash_t len_1to3 + a = input.getUint8(0); + b = input.getUint8(length >>> 1); + c = input.getUint8(length - 1); + hash = key.getUint32(0, Endian.little); + hash ^= key.getUint32(4, Endian.little); + hash += seed; + hash ^= (a << 16) | (b << 24) | (c) | (length << 8); + return _midsizeAvalanche(hash); + } else if (length <= 8) { + // hash_t len_4to8 + lhs = input.getUint32(0, Endian.little); + rhs = input.getUint32(length - 4, Endian.little); + hash = key.getUint64(8, Endian.little); + hash ^= key.getUint64(16, Endian.little); + hash -= seed ^ ((_swap32(seed) & _mask32) << 32); + hash ^= (lhs << 32) | rhs; + return _rrmxmx(hash, length); + } else if (length <= 16) { + // hash_t len_9to16 + lhs = key.getUint64(24, Endian.little); + lhs ^= key.getUint64(32, Endian.little); + lhs += seed; + + rhs = key.getUint64(40, Endian.little); + rhs ^= key.getUint64(48, Endian.little); + rhs -= seed; + + lhs ^= input.getUint64(0, Endian.little); + rhs ^= input.getUint64(length - 8, Endian.little); + + hash = length + _swap64(lhs) + rhs + _mul128fold64(lhs, rhs); + return _avalanche(hash); + } else if (length <= 128) { + // hash_t len_17to128 + hash = length * prime64_1; + if (length > 32) { + if (length > 64) { + if (length > 96) { + hash += _mix16B(input, 48, key, 96, seed); + hash += _mix16B(input, length - 64, key, 112, seed); + } + hash += _mix16B(input, 32, key, 64, seed); + hash += _mix16B(input, length - 48, key, 80, seed); + } + hash += _mix16B(input, 16, key, 32, seed); + hash += _mix16B(input, length - 32, key, 48, seed); + } + hash += _mix16B(input, 0, key, 0, seed); + hash += _mix16B(input, length - 16, key, 16, seed); + return _avalanche(hash); + } else { + // hash_t len_129to240 + const int startOffset = 3; + const int lastOffset = 17; + hash = length * prime64_1; + // first 128 bytes + for (i = 0; i < 128; i += 16) { + hash += _mix16B(input, i, key, i, seed); + } + hash = _avalanche(hash); + // remaining bytes + for (i = 128; i + 16 <= length; i += 16) { + c = startOffset + i - 128; + hash += _mix16B(input, i, key, c, seed); + } + // last byte + c = _minSecretSize - lastOffset; + hash += _mix16B(input, length - 16, key, c, seed); + return _avalanche(hash); + } + } + + @override + Uint8List $finalize() { + int i; + int hash; + ByteData key; + Uint64List input = Uint64List(_midsizeMax >>> 3); + Uint8List input8 = Uint8List.view(input.buffer); + + if (messageLength <= _midsizeMax) { + var it = last.iterator; + for (i = 0; it.moveNext(); ++i) { + input8[i] = it.current; + } + if (seed == 0) { + key = secretBD; + } else { + key = Uint8List.fromList(_kSecret).buffer.asByteData(); + } + hash = _finalizeShort(input.buffer.asByteData(), i, key); + } else { + for (i = 63; i >= 0; --i) { + input8[i] = last.removeLast(); + } + hash = _finalizeLong(input); + } + + return Uint8List.fromList([ + hash >>> 56, + hash >>> 48, + hash >>> 40, + hash >>> 32, + hash >>> 24, + hash >>> 16, + hash >>> 8, + hash, + ]); + } +} diff --git a/hashlib/lib/src/algorithms/xxh32/xxh32.dart b/hashlib/lib/src/algorithms/xxh32/xxh32.dart new file mode 100644 index 0000000..5863dea --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh32/xxh32.dart @@ -0,0 +1,4 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'xxh32_64bit.dart' if (dart.library.js) 'xxh32_32bit.dart'; diff --git a/hashlib/lib/src/algorithms/xxh32/xxh32_32bit.dart b/hashlib/lib/src/algorithms/xxh32/xxh32_32bit.dart new file mode 100644 index 0000000..fa16e08 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh32/xxh32_32bit.dart @@ -0,0 +1,136 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask16 = 0xFFFF; +const int _mask32 = 0xFFFFFFFF; + +/// This implementation is derived from +/// https://github.com/easyaspi314/xxhash-clean/blob/master/xxhash32-ref.c +class XXHash32Sink extends BlockHashSink { + final int seed; + + @override + final int hashLength = 4; + + static const int prime32_1 = 0x9E3779B1; + static const int prime32_2 = 0x85EBCA77; + static const int prime32_3 = 0xC2B2AE3D; + static const int prime32_4 = 0x27D4EB2F; + static const int prime32_5 = 0x165667B1; + + int _acc1 = 0; + int _acc2 = 0; + int _acc3 = 0; + int _acc4 = 0; + + XXHash32Sink(this.seed) : super(16) { + reset(); + } + + @override + void reset() { + _acc1 = (seed & _mask32) + prime32_1 + prime32_2; + _acc2 = (seed & _mask32) + prime32_2; + _acc3 = (seed & _mask32) + 0; + _acc4 = (seed & _mask32) - prime32_1; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(); + pos = 0; + } + } + + /// Returns ([a] * [b]) within 32-bit Galois field + static int cross32(int a, int b) { + int ah = (a >>> 16) & _mask16; + int al = a & _mask16; + int bh = (b >>> 16) & _mask16; + int bl = b & _mask16; + a = (ah * bl + al * bh) & _mask32; + b = (al * bl) & _mask32; + return ((a << 16) + b) & _mask32; + } + + /// Rotates 32-bit number [x] by [n] bits + static int rotl32(int x, int n) => + ((x << n) & _mask32) | ((x & _mask32) >>> (32 - n)); + + @override + void $update([List? block, int offset = 0, bool last = false]) { + _acc1 += cross32(sbuffer[0], prime32_2); + _acc1 = rotl32(_acc1, 13); + _acc1 = cross32(_acc1, prime32_1); + + _acc2 += cross32(sbuffer[1], prime32_2); + _acc2 = rotl32(_acc2, 13); + _acc2 = cross32(_acc2, prime32_1); + + _acc3 += cross32(sbuffer[2], prime32_2); + _acc3 = rotl32(_acc3, 13); + _acc3 = cross32(_acc3, prime32_1); + + _acc4 += cross32(sbuffer[3], prime32_2); + _acc4 = rotl32(_acc4, 13); + _acc4 = cross32(_acc4, prime32_1); + } + + @override + Uint8List $finalize() { + int i, t; + int hash; + + if (messageLength < 16) { + hash = (seed & _mask32) + prime32_5; + } else { + hash = rotl32(_acc1, 1); + hash += rotl32(_acc2, 7); + hash += rotl32(_acc3, 12); + hash += rotl32(_acc4, 18); + } + + hash += messageLength & _mask32; + + // process the remaining data + for (i = t = 0; t + 4 <= pos; ++i, t += 4) { + hash += cross32(sbuffer[i], prime32_3); + hash = rotl32(hash, 17); + hash = cross32(hash, prime32_4); + } + for (; t < pos; t++) { + hash += cross32(buffer[t], prime32_5); + hash = rotl32(hash, 11); + hash = cross32(hash, prime32_1); + } + + // avalanche + hash &= _mask32; + hash ^= hash >>> 15; + hash = cross32(hash, prime32_2); + hash ^= hash >>> 13; + hash = cross32(hash, prime32_3); + hash ^= hash >>> 16; + + return Uint8List.fromList([ + hash >>> 24, + hash >>> 16, + hash >>> 8, + hash, + ]); + } +} diff --git a/hashlib/lib/src/algorithms/xxh32/xxh32_64bit.dart b/hashlib/lib/src/algorithms/xxh32/xxh32_64bit.dart new file mode 100644 index 0000000..af20e76 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh32/xxh32_64bit.dart @@ -0,0 +1,119 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +const int _mask32 = 0xFFFFFFFF; + +/// This implementation is derived from +/// https://github.com/easyaspi314/xxhash-clean/blob/master/xxhash32-ref.c +class XXHash32Sink extends BlockHashSink { + final int seed; + + @override + final int hashLength = 4; + + static const int prime32_1 = 0x9E3779B1; + static const int prime32_2 = 0x85EBCA77; + static const int prime32_3 = 0xC2B2AE3D; + static const int prime32_4 = 0x27D4EB2F; + static const int prime32_5 = 0x165667B1; + + int _acc1 = 0; + int _acc2 = 0; + int _acc3 = 0; + int _acc4 = 0; + + XXHash32Sink(this.seed) : super(16) { + reset(); + } + + @override + void reset() { + _acc1 = (seed & _mask32) + prime32_1 + prime32_2; + _acc2 = (seed & _mask32) + prime32_2; + _acc3 = (seed & _mask32) + 0; + _acc4 = (seed & _mask32) - prime32_1; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(); + pos = 0; + } + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + _acc1 = (_acc1 + sbuffer[0] * prime32_2) & _mask32; + _acc1 = (_acc1 << 13) | (_acc1 >>> 19); + _acc1 = (_acc1 * prime32_1) & _mask32; + + _acc2 = (_acc2 + sbuffer[1] * prime32_2) & _mask32; + _acc2 = (_acc2 << 13) | (_acc2 >>> 19); + _acc2 = (_acc2 * prime32_1) & _mask32; + + _acc3 = (_acc3 + sbuffer[2] * prime32_2) & _mask32; + _acc3 = (_acc3 << 13) | (_acc3 >>> 19); + _acc3 = (_acc3 * prime32_1) & _mask32; + + _acc4 = (_acc4 + sbuffer[3] * prime32_2) & _mask32; + _acc4 = (_acc4 << 13) | (_acc4 >>> 19); + _acc4 = (_acc4 * prime32_1) & _mask32; + } + + @override + Uint8List $finalize() { + int i, t; + int hash; + + if (messageLength < 16) { + hash = (seed & _mask32) + prime32_5; + } else { + hash = (_acc1 << 1) | (_acc1 >>> 31); + hash += (_acc2 << 7) | (_acc2 >>> 25); + hash += (_acc3 << 12) | (_acc3 >>> 20); + hash += (_acc4 << 18) | (_acc4 >>> 14); + } + + hash = (hash + messageLength) & _mask32; + + // process the remaining data + for (i = t = 0; t + 4 <= pos; ++i, t += 4) { + hash = (hash + sbuffer[i] * prime32_3) & _mask32; + hash = (hash << 17) | (hash >>> 15); + hash = (hash * prime32_4) & _mask32; + } + for (; t < pos; t++) { + hash = (hash + buffer[t] * prime32_5) & _mask32; + hash = (hash << 11) | (hash >>> 21); + hash = (hash * prime32_1) & _mask32; + } + + // avalanche + hash ^= hash >>> 15; + hash = (hash * prime32_2) & _mask32; + hash ^= hash >>> 13; + hash = (hash * prime32_3) & _mask32; + hash ^= hash >>> 16; + + return Uint8List.fromList([ + hash >>> 24, + hash >>> 16, + hash >>> 8, + hash, + ]); + } +} diff --git a/hashlib/lib/src/algorithms/xxh64/xxh64.dart b/hashlib/lib/src/algorithms/xxh64/xxh64.dart new file mode 100644 index 0000000..5d5f8c7 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh64/xxh64.dart @@ -0,0 +1,4 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'xxh64_64bit.dart' if (dart.library.js) 'xxh64_32bit.dart'; diff --git a/hashlib/lib/src/algorithms/xxh64/xxh64_32bit.dart b/hashlib/lib/src/algorithms/xxh64/xxh64_32bit.dart new file mode 100644 index 0000000..6db62b7 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh64/xxh64_32bit.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +/// Stub for 32-bit machines. +class XXHash64Sink extends BlockHashSink { + @override + final int hashLength = 8; + + XXHash64Sink(int seed) : super(32) { + seed; + throw UnimplementedError('XXHash64 is not supported in Node platform'); + } + + @override + void $update([List? block, int offset = 0, bool last = false]) { + throw UnimplementedError('XXHash64 is not supported in Node platform'); + } + + @override + Uint8List $finalize() { + throw UnimplementedError('XXHash64 is not supported in Node platform'); + } +} diff --git a/hashlib/lib/src/algorithms/xxh64/xxh64_64bit.dart b/hashlib/lib/src/algorithms/xxh64/xxh64_64bit.dart new file mode 100644 index 0000000..f6e0677 --- /dev/null +++ b/hashlib/lib/src/algorithms/xxh64/xxh64_64bit.dart @@ -0,0 +1,137 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/block_hash.dart'; + +/// This implementation is derived from +/// https://github.com/easyaspi314/xxhash-clean/blob/master/xxhash64-ref.c +class XXHash64Sink extends BlockHashSink { + final int seed; + + @override + final int hashLength = 8; + + static const int prime64_1 = 0x9E3779B185EBCA87; + static const int prime64_2 = 0xC2B2AE3D27D4EB4F; + static const int prime64_3 = 0x165667B19E3779F9; + static const int prime64_4 = 0x85EBCA77C2B2AE63; + static const int prime64_5 = 0x27D4EB2F165667C5; + + int _acc1 = 0; + int _acc2 = 0; + int _acc3 = 0; + int _acc4 = 0; + + late final Uint64List qbuffer = Uint64List.view(buffer.buffer); + + XXHash64Sink(this.seed) : super(32) { + reset(); + } + + @override + void reset() { + _acc1 = seed + prime64_1 + prime64_2; + _acc2 = seed + prime64_2; + _acc3 = seed + 0; + _acc4 = seed - prime64_1; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + messageLength += end - start; + for (; start < end; start++, pos++) { + if (pos == blockLength) { + $update(); + pos = 0; + } + buffer[pos] = chunk[start]; + } + if (pos == blockLength) { + $update(); + pos = 0; + } + } + + @pragma('vm:prefer-inline') + static int _rotl(int x, int n) => (x << n) | (x >>> (64 - n)); + + @pragma('vm:prefer-inline') + static int _accumulate(int x, int y) => + _rotl((x + y * prime64_2), 31) * prime64_1; + + @override + void $update([List? block, int offset = 0, bool last = false]) { + _acc1 = _accumulate(_acc1, qbuffer[0]); + _acc2 = _accumulate(_acc2, qbuffer[1]); + _acc3 = _accumulate(_acc3, qbuffer[2]); + _acc4 = _accumulate(_acc4, qbuffer[3]); + } + + @pragma('vm:prefer-inline') + static int _merge(int h, int a) => + (h ^ _accumulate(0, a)) * prime64_1 + prime64_4; + + @override + Uint8List $finalize() { + int i, t; + int hash; + + if (messageLength < 32) { + hash = seed + prime64_5; + } else { + // accumulate + hash = _rotl(_acc1, 1); + hash += _rotl(_acc2, 7); + hash += _rotl(_acc3, 12); + hash += _rotl(_acc4, 18); + + // merge round + hash = _merge(hash, _acc1); + hash = _merge(hash, _acc2); + hash = _merge(hash, _acc3); + hash = _merge(hash, _acc4); + } + + hash += messageLength; + + // process the remaining data + for (i = t = 0; t + 8 <= pos; ++i, t += 8) { + hash ^= _accumulate(0, qbuffer[i]); + hash = _rotl(hash, 27); + hash *= prime64_1; + hash += prime64_4; + } + for (i <<= 1; t + 4 <= pos; ++i, t += 4) { + hash ^= sbuffer[i] * prime64_1; + hash = _rotl(hash, 23); + hash *= prime64_2; + hash += prime64_3; + } + for (; t < pos; t++) { + hash ^= buffer[t] * prime64_5; + hash = _rotl(hash, 11); + hash *= prime64_1; + } + + // avalanche + hash ^= hash >>> 33; + hash *= prime64_2; + hash ^= hash >>> 29; + hash *= prime64_3; + hash ^= hash >>> 32; + + return Uint8List.fromList([ + hash >>> 56, + hash >>> 48, + hash >>> 40, + hash >>> 32, + hash >>> 24, + hash >>> 16, + hash >>> 8, + hash, + ]); + } +} diff --git a/hashlib/lib/src/argon2.dart b/hashlib/lib/src/argon2.dart new file mode 100644 index 0000000..1080775 --- /dev/null +++ b/hashlib/lib/src/argon2.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/algorithms/argon2/argon2.dart'; + +export 'package:hashlib/src/algorithms/argon2/argon2.dart'; + +const _defaultSecurity = Argon2Security.good; + +/// Verifies if the original [password] was derived from the [encoded] +/// Argon2 hash. +/// +/// The encoded hash may look like this: +/// `$argon2i$v=19$m=16,t=2,p=1$c29tZSBzYWx0$u1eU6mZFG4/OOoTdAtM5SQ` +bool argon2Verify(String encoded, List password) { + var data = fromCrypt(encoded); + var hash = data.hashBytes(); + if (hash == null) { + throw ArgumentError('No password hash in the encoded string'); + } + var instance = Argon2.fromEncoded(data); + return instance.verify(hash, password); +} + +/// Encode a password using default Argon2d algorithm +/// +/// Parameters: +/// - [password] is the raw password to be encoded +/// - [salt] should be at least 8 bytes long. 16 bytes is recommended. +/// - [security] is the parameter choice for the algorithm. +/// - [hashLength] is the number of output bytes +/// - [key] is an optional key bytes to use +/// - [personalization] is optional additional data bytes +Argon2HashDigest argon2d( + List password, + List salt, { + int? hashLength, + List? key, + List? personalization, + Argon2Security security = _defaultSecurity, +}) => + Argon2( + salt: salt, + type: Argon2Type.argon2d, + hashLength: hashLength, + iterations: security.t, + parallelism: security.p, + memorySizeKB: security.m, + key: key, + personalization: personalization, + ).convert(password); + +/// Encode a password using default Argon2i algorithm +/// +/// Parameters: +/// - [password] is the raw password to be encoded +/// - [salt] should be at least 8 bytes long. 16 bytes is recommended. +/// - [security] is the parameter choice for the algorithm. +/// - [hashLength] is the number of output bytes +/// - [key] is an optional key bytes to use +/// - [personalization] is optional additional data bytes +/// +/// +Argon2HashDigest argon2i( + List password, + List salt, { + int? hashLength, + List? key, + List? personalization, + Argon2Security security = _defaultSecurity, +}) => + Argon2( + salt: salt, + type: Argon2Type.argon2i, + hashLength: hashLength, + iterations: security.t, + parallelism: security.p, + memorySizeKB: security.m, + key: key, + personalization: personalization, + ).convert(password); + +/// Encode a password using default Argon2id algorithm +/// +/// Parameters: +/// - [password] is the raw password to be encoded +/// - [salt] should be at least 8 bytes long. 16 bytes is recommended. +/// - [security] is the parameter choice for the algorithm. +/// - [hashLength] is the number of output bytes +/// - [key] is an optional key bytes to use +/// - [personalization] is optional additional data bytes +Argon2HashDigest argon2id( + List password, + List salt, { + int? hashLength, + List? key, + List? personalization, + Argon2Security security = _defaultSecurity, +}) => + Argon2( + salt: salt, + type: Argon2Type.argon2id, + hashLength: hashLength, + iterations: security.t, + parallelism: security.p, + memorySizeKB: security.m, + key: key, + personalization: personalization, + ).convert(password); diff --git a/hashlib/lib/src/bcrypt.dart b/hashlib/lib/src/bcrypt.dart new file mode 100644 index 0000000..dfdde97 --- /dev/null +++ b/hashlib/lib/src/bcrypt.dart @@ -0,0 +1,88 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/algorithms/bcrypt/bcrypt.dart'; +import 'package:hashlib/src/algorithms/bcrypt/common.dart'; +import 'package:hashlib/src/algorithms/bcrypt/security.dart'; + +export 'algorithms/bcrypt/bcrypt.dart' show Bcrypt; +export 'algorithms/bcrypt/common.dart' + show BcryptContext, BcryptHashDigest, BcryptVersion; +export 'algorithms/bcrypt/security.dart' show BcryptSecurity; + +/// Generate a secure password using the [Bcrypt] algorithm. +/// +/// [Bcrypt][wiki] is a password hashing algorithm based on the Blowfish cipher. +/// It uses a unique salt and a configurable cost factor to prevent rainbow +/// table attacks and remain secure as hardware improves. Bcrypt's iterative +/// hashing and expensive key setup phase ensure resistance to brute-force +/// attacks. +/// +/// Parameters: +/// - [password] : The password to hash. The algorithm uses first 72 bytes, and +/// the rest are ignored. +/// - [salt] : An randomly generated 16-byte string. +/// - [nb] : Number of rounds in terms of power of 2. 0 < [nb] < 31 +/// - [version] : The [BcryptVersion] to use. Default [BcryptVersion.$2b] +/// - [security] : The default parameter source for [nb] if not provided +/// (default is [BcryptSecurity.good]). +/// +/// [wiki]: https://en.wikipedia.org/wiki/Bcrypt +BcryptHashDigest bcryptDigest( + List password, { + List? salt, + BcryptVersion version = BcryptVersion.$2b, + BcryptSecurity security = BcryptSecurity.good, + int? nb, +}) => + Bcrypt( + version: version, + salt: salt, + cost: nb ?? security.nb, + ).convert(password); + +/// Generate the encoded salt to be used by the [Bcrypt] algorithm. +/// +/// Parameters: +/// - [nb] : Number of rounds in terms of power of 2. 0 < [nb] < 31 +/// - [version] : The [BcryptVersion] to use. Default [BcryptVersion.$2b] +/// - [security] : The default parameter source for [nb] if not provided +/// (default is [BcryptSecurity.good]). +String bcryptSalt({ + int? nb, + BcryptVersion version = BcryptVersion.$2b, + BcryptSecurity security = BcryptSecurity.good, +}) => + BcryptContext( + version: version, + cost: nb ?? security.nb, + ).toEncoded(); + +/// Generates a secure password using the [Bcrypt] algorithm, and returns a +/// 60-byte encoded string containing the version, cost, salt, and password. +/// +/// Parameters: +/// - [password] : The password to hash. The algorithm uses first 72 bytes, and +/// the rest are ignored. +/// - [salt] : Encoded salt, e.g.: `$2b$04$SQe9knOzepOVKoYXo9xTte` +/// If not provided, [bcryptSalt] is used to get a random one. +/// +/// **Note**: Complete encoded string is also accepted, e.g.: +/// `$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW` +String bcrypt(List password, [String? salt]) => + Bcrypt.fromEncoded(fromCrypt(salt ?? bcryptSalt())) + .convert(password) + .encoded(); + +/// Verifies if the [plain] password was derived from the [encoded] hash. +/// +/// The encoded hash may look like this: +/// `$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW` +bool bcryptVerify(String encoded, List plain) { + var data = fromCrypt(encoded); + var hash = data.hash!.substring(22); + var hashBytes = fromBase64(hash, codec: Base64Codec.bcrypt); + var instance = Bcrypt.fromEncoded(data); + return instance.verify(hashBytes, plain); +} diff --git a/hashlib/lib/src/blake2b.dart b/hashlib/lib/src/blake2b.dart new file mode 100644 index 0000000..e37e77d --- /dev/null +++ b/hashlib/lib/src/blake2b.dart @@ -0,0 +1,126 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/blake2/blake2b.dart'; +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +export 'algorithms/blake2/blake2b.dart' show Blake2bHash; + +/// For generating un-keyed message digest with BLAKE2b-160. +/// +/// Use [Blake2b] for keyed hash generation. +const Blake2b blake2b160 = Blake2b._(160 >>> 3); + +/// For generating un-keyed message digest with BLAKE2b-256. +/// +/// Use [Blake2b] for keyed hash generation. +const Blake2b blake2b256 = Blake2b._(256 >>> 3); + +/// For generating un-keyed message digest with BLAKE2b-384. +/// +/// Use [Blake2b] for keyed hash generation. +const Blake2b blake2b384 = Blake2b._(384 >>> 3); + +/// For generating un-keyed message digest with BLAKE2b-512. +/// +/// Use [Blake2b] for keyed hash generation. +const Blake2b blake2b512 = Blake2b._(512 >>> 3); + +/// Blake2b is a highly secure cryptographic hash function optimized for 64-bit +/// platforms. It generates hash values of data ranging from 1 to 64 bytes in +/// size. It doesn't require a separate keying mechanism and can be used in +/// various applications, serving as a more efficient alternative to other hash +/// algorithms like SHA and HMAC-SHA. +/// +/// This implementation is based on the [RFC-7693][rfc] +/// +/// [rfc]: https://www.ietf.org/rfc/rfc7693.html +class Blake2b extends BlockHashBase with MACHashBase { + final List? _key; + final List? _salt; + final List? _aad; + + /// The number of bytes in the output. + final int digestSize; + + @override + final String name; + + const Blake2b._( + this.digestSize, [ + this._key, + this._salt, + this._aad, + String? _name, + ]) : name = _name ?? 'BLAKE2b-${digestSize << 3}'; + + /// Creates an instance to generate hash using BLAKE-2b algorithm. + /// + /// Parameters: + /// - [digestSize] The number of bytes in the output. + /// - [salt] An optional nonce. Must be exactly 16 bytes long. + /// - [aad] Second optional nonce. Must be exactly 16 bytes long. + /// + /// See also: + /// - [mac] or [Blake2bMAC] for generating MAC with this algorithm. + factory Blake2b( + int digestSize, { + List? salt, + List? aad, + }) => + Blake2b._(digestSize, null, salt, aad); + + @override + Blake2bHash createSink() => Blake2bHash( + digestSize, + key: _key, + salt: _salt, + aad: _aad, + ); + + /// Get a builder to generate MAC using this algorithm. + /// + /// Example: + /// ``` + /// final key = 'secret key'.codeUnits; + /// final message = 'plain message'.codeUnits; + /// final mac = blake2s256.mac.by(key).convert(message); + /// ``` + Blake2bMAC get mac => Blake2bMAC(digestSize); +} + +/// A MAC generator based on Blake2b algorithm. +class Blake2bMAC extends MACHash { + /// The number of bytes in the output. + final int digestSize; + + @override + final String name; + + /// Creates an instance to generate MAC using BLAKE-2b algorithm. + /// + /// Parameters: + /// - [digestSize] The number of bytes in the output. + /// + /// See also: + /// - [Blake2b] for generating hash only. + const Blake2bMAC( + this.digestSize, + ) : name = 'BLAKE2b-${digestSize << 3}/MAC'; + + /// Get an [MACHashBase] instance initialized by a [key]. + /// + /// Parameters: + /// - [key] An optional key for MAC generation. Should not exceed 64 bytes. + /// - [salt] An optional nonce. Must be exactly 16 bytes long. + /// - [aad] Second optional nonce. Must be exactly 16 bytes long. + @override + @pragma('vm:prefer-inline') + MACHashBase by( + List key, { + List? salt, + List? aad, + }) => + Blake2b._(digestSize, key, salt, aad, name); +} diff --git a/hashlib/lib/src/blake2s.dart b/hashlib/lib/src/blake2s.dart new file mode 100644 index 0000000..e47a09d --- /dev/null +++ b/hashlib/lib/src/blake2s.dart @@ -0,0 +1,125 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/blake2/blake2s.dart'; +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +export 'algorithms/blake2/blake2s.dart' show Blake2sHash; + +/// For generating un-keyed message digest with BLAKE2s-128. +/// +/// Use [Blake2s] for keyed hash generation. +const Blake2s blake2s128 = Blake2s._(128 >>> 3); + +/// For generating un-keyed message digest with BLAKE2s-160. +/// +/// Use [Blake2s] for keyed hash generation. +const Blake2s blake2s160 = Blake2s._(160 >>> 3); + +/// For generating un-keyed message digest with BLAKE2s-224. +/// +/// Use [Blake2s] for keyed hash generation. +const Blake2s blake2s224 = Blake2s._(224 >>> 3); + +/// For generating un-keyed message digest with BLAKE2s-256. +/// +/// Use [Blake2s] for keyed hash generation. +const Blake2s blake2s256 = Blake2s._(256 >>> 3); + +/// Blake2s is a cryptographic hash function optimized for 8-bit to 32-bit +/// platforms. It generates hash values of data ranging from 1 to 32 bytes in +/// size. Blake2s is highly secure and can be used in various applications as a +/// fast and secure replacement for legacy algorithms like MD5 and HMAC-MD5. +/// +/// This implementation is based on the [RFC-7693][rfc] +/// +/// [rfc]: https://www.ietf.org/rfc/rfc7693.html +class Blake2s extends BlockHashBase with MACHashBase { + final List? _key; + final List? _salt; + final List? _aad; + + /// The number of bytes in the output. + final int digestSize; + + @override + final String name; + + const Blake2s._( + this.digestSize, [ + this._key, + this._salt, + this._aad, + String? _name, + ]) : name = _name ?? 'BLAKE2s-${digestSize << 3}'; + + /// Creates an instance to generate hash using BLAKE-2s algorithm. + /// + /// Parameters: + /// - [digestSize] The number of bytes in the output. + /// - [salt] An optional nonce. Must be exactly 8 bytes long. + /// - [aad] Second optional nonce. Must be exactly 8 bytes long. + /// + /// See also: + /// - [mac] or [Blake2sMAC] for generating MAC with this algorithm. + factory Blake2s( + int digestSize, { + List? salt, + List? aad, + }) => + Blake2s._(digestSize, null, salt, aad); + + @override + Blake2sHash createSink() => Blake2sHash( + digestSize, + key: _key, + salt: _salt, + aad: _aad, + ); + + /// Get a builder to generate MAC using this algorithm. + /// + /// Example: + /// ``` + /// final key = 'secret key'.codeUnits; + /// final message = 'plain message'.codeUnits; + /// final mac = blake2s256.mac.by(key).convert(message); + /// ``` + Blake2sMAC get mac => Blake2sMAC(digestSize); +} + +/// A MAC generator based on Blake2s algorithm. +class Blake2sMAC extends MACHash { + /// The number of bytes in the output. + final int digestSize; + + @override + final String name; + + /// Creates an instance to generate MAC using BLAKE-2s algorithm. + /// + /// Parameters: + /// - [digestSize] The number of bytes in the output. + /// + /// See also: + /// - [Blake2s] for generating hash only. + const Blake2sMAC( + this.digestSize, + ) : name = 'BLAKE2s-${digestSize << 3}/MAC'; + + /// Get an [MACHashBase] instance initialized by a [key]. + /// + /// Parameters: + /// - [key] The key for MAC generation. Should not exceed 32 bytes. + /// - [salt] An optional nonce. Must be exactly 8 bytes long. + /// - [aad] Second optional nonce. Must be exactly 8 bytes long. + @override + @pragma('vm:prefer-inline') + MACHashBase by( + List key, { + List? salt, + List? aad, + }) => + Blake2s._(digestSize, key, salt, aad, name); +} diff --git a/hashlib/lib/src/core/block_hash.dart b/hashlib/lib/src/core/block_hash.dart new file mode 100644 index 0000000..6da21c9 --- /dev/null +++ b/hashlib/lib/src/core/block_hash.dart @@ -0,0 +1,82 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/core/hash_base.dart'; + +/// Base class used by block hash algorithms +abstract class BlockHashBase extends HashBase { + const BlockHashBase(); +} + +/// Base class used by block hash algorithm sink implementations +abstract class BlockHashSink extends HashDigestSink { + /// The current position of data in the [buffer] + int pos = 0; + + /// The message length in bytes + int messageLength = 0; + + /// The internal block length of the algorithm in bytes + final int blockLength; + + /// The main buffer + final Uint8List buffer; + + /// The [buffer] as Uint32List + late final Uint32List sbuffer = Uint32List.view(buffer.buffer); + + /// The [buffer] as ByteData + late final ByteData bdata = buffer.buffer.asByteData(); + + /// Get the message length in bits + int get messageLengthInBits => messageLength << 3; + + /// Initialize a new sink for the block hash + /// + /// Parameters: + /// - [blockLength] is the length of each block in each [$update] call. + /// - [bufferLength] is the buffer length where blocks are stored temporarily + BlockHashSink(this.blockLength, {int? bufferLength}) + : assert(blockLength > 0 && (bufferLength ?? 0) >= 0), + buffer = Uint8List(bufferLength ?? blockLength); + + @override + void reset() { + pos = 0; + messageLength = 0; + super.reset(); + } + + @override + void $process(List chunk, int start, int end) { + int t = start; + if (pos > 0) { + for (; t < end && pos < blockLength; pos++, t++) { + buffer[pos] = chunk[t]; + } + messageLength += t - start; + if (pos < blockLength) return; + + $update(buffer); + pos = 0; + } + + while ((end - t) >= blockLength) { + messageLength += blockLength; + $update(chunk, t); + t += blockLength; + } + + messageLength += end - t; + for (; t < end; pos++, t++) { + buffer[pos] = chunk[t]; + } + } + + /// Internal method to update the message-digest with a single [block]. + /// + /// The method starts reading the block from [offset] index + void $update(List block, [int offset = 0, bool last = false]); +} diff --git a/hashlib/lib/src/core/hash_base.dart b/hashlib/lib/src/core/hash_base.dart new file mode 100644 index 0000000..722e5bd --- /dev/null +++ b/hashlib/lib/src/core/hash_base.dart @@ -0,0 +1,170 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:convert' show Encoding; +import 'dart:typed_data' show Uint8List; + +import 'package:hashlib/src/core/hash_digest.dart'; + +export 'hash_base_stub.dart' if (dart.library.io) 'hash_base_io.dart'; + +/// This sink allows adding arbitrary length byte arrays +/// and produces a [HashDigest] on [close]. +abstract class HashDigestSink implements Sink> { + HashDigestSink(); + + /// The flag tracking if the [digest] is called once. + bool _closed = false; + + /// The message digest (available after the [digest] call) + late HashDigest _digest; + + /// Returns true if the sink is closed, false otherwise + bool get closed => _closed; + + /// The length of generated hash in bytes + int get hashLength; + + /// Resets the current state to start from fresh state + void reset() { + _closed = false; + } + + /// Adds [data] to the message-digest. + /// + /// Throws [StateError], if it is called after closing the digest. + @override + void add(List data, [int start = 0, int? end]) { + if (_closed) { + throw StateError('The message-digest is already closed'); + } + $process(data, start, end ?? data.length); + } + + /// Processes a chunk of input data + void $process(List chunk, int start, int end); + + /// Finalizes the message-digest and returns a [HashDigest] + HashDigest digest() { + if (_closed) return _digest; + _digest = HashDigest($finalize()); + _closed = true; + return _digest; + } + + /// Finalizes the message digest with the remaining message block, + /// and returns the output as byte array. + Uint8List $finalize(); + + /// Finalizes the message-digest. It calls [digest] method internally. + @override + @pragma('vm:prefer-inline') + void close() => digest(); +} + +/// The base class used by the hash algorithm implementations. It implements +/// the [StreamTransformer] and exposes few convenient methods to handle any +/// types of data source. +abstract class HashBase + implements StreamTransformer, HashDigest> { + const HashBase(); + + /// The name of this algorithm + String get name; + + /// Create a [HashDigestSink] for generating message-digests + T createSink(); + + /// Process the byte array [input] and returns a [HashDigest]. + @pragma('vm:prefer-inline') + HashDigest convert(List input) { + var sink = createSink(); + sink.add(input); + return sink.digest(); + } + + /// Process the byte array [input] and returns a hash in hexadecimal. + @pragma('vm:prefer-inline') + String hex(List input) => convert(input).hex(); + + /// Process the [input] string and returns a [HashDigest]. + /// + /// If [encoding] is not specified, the [String.codeUnits] are used. + HashDigest string(String input, [Encoding? encoding]) { + var sink = createSink(); + if (encoding != null) { + sink.add(encoding.encode(input)); + } else { + sink.add(input.codeUnits); + } + return sink.digest(); + } + + /// Transforms the byte array input stream to generate a new stream + /// which contains a single [HashDigest] + /// + /// The expected behavior of this method is described below: + /// + /// - When the returned stream has a subscriber (calling [Stream.listen]), + /// the message-digest generation begins from the input [stream]. + /// - If the returned stream is paused, the processing of the input [stream] + /// is also paused, and on resume, it continue processing from where it was + /// left off. + /// - If the returned stream is cancelled, the subscription to the input + /// [stream] is also cancelled. + /// - When the input [stream] is closed, the returned stream also gets closed + /// with a [HashDigest] data. The returned stream may produce only one + /// such data event in its life-time. + /// - On error reading the input [stream], or while processing the message + /// digest, the subscription to input [stream] cancels immediately and the + /// returned stream closes with an error event. + @override + Stream bind(Stream> stream) async* { + var sink = createSink(); + await for (var x in stream) { + sink.add(x); + } + yield sink.digest(); + } + + /// Consumes the entire [stream] of byte array and generates a [HashDigest]. + Future byteStream( + Stream stream, [ + int bufferSize = 1024, + ]) async { + var sink = createSink(); + var buffer = Uint8List(bufferSize); + int p = 0; + await for (var x in stream) { + buffer[p++] = x; + if (p == bufferSize) { + sink.add(buffer); + p = 0; + } + } + if (p > 0) { + sink.add(buffer, 0, p); + } + return sink.digest(); + } + + /// Consumes the entire [stream] of string and generates a [HashDigest]. + /// + /// If [encoding] is not specified, the [String.codeUnits] are used. + Future stringStraem( + Stream stream, [ + Encoding? encoding, + ]) { + if (encoding == null) { + return bind(stream.map((s) => s.codeUnits)).first; + } else { + return bind(stream.transform(encoding.encoder)).first; + } + } + + @override + StreamTransformer cast() { + throw UnsupportedError('The transformer do not support casting'); + } +} diff --git a/hashlib/lib/src/core/hash_base_io.dart b/hashlib/lib/src/core/hash_base_io.dart new file mode 100644 index 0000000..193a029 --- /dev/null +++ b/hashlib/lib/src/core/hash_base_io.dart @@ -0,0 +1,55 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'hash_base.dart'; +import 'hash_digest.dart'; + +/// Extends the base hash algorithm class with file IO support +extension HashBaseFileSupport on HashBase { + /// Converts the [input] file and returns a [HashDigest] asynchronously. + /// + /// If [start] is present, the file will be read from byte-offset [start]. + /// Otherwise from the beginning (index 0). + /// + /// If [end] is present, only bytes up to byte-index [end] will be read. + /// Otherwise, until end of file. + @pragma('vm:prefer-inline') + Future file(File input, [int start = 0, int? end]) { + return bind(input.openRead(start, end)).first; + } + + /// Converts the [input] file and returns a [HashDigest] synchronously. + /// + /// If [start] is present, the file will be read from byte-offset [start]. + /// Otherwise from the beginning (index 0). + /// + /// If [end] is present, only bytes up to byte-index [end] will be read. + /// Otherwise, until end of file. + /// + /// If [bufferSize] is present, the file will be read in chunks of this size. + /// By default the [bufferSize] is `2048`. + HashDigest fileSync( + File input, { + int start = 0, + int? end, + int bufferSize = 2048, + }) { + var raf = input.openSync(); + try { + var sink = createSink(); + var buffer = Uint8List(bufferSize); + int length = end ?? raf.lengthSync(); + for (int i = start, l; i < length; i += l) { + l = raf.readIntoSync(buffer); + sink.add(buffer, 0, l); + } + return sink.digest(); + } finally { + raf.closeSync(); + } + } +} diff --git a/hashlib/lib/src/core/hash_base_stub.dart b/hashlib/lib/src/core/hash_base_stub.dart new file mode 100644 index 0000000..18da769 --- /dev/null +++ b/hashlib/lib/src/core/hash_base_stub.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; + +import 'hash_base.dart'; +import 'hash_digest.dart'; + +/// Stub for machines that does not have file IO support. +extension HashBaseFileSupport on HashBase { + /// Converts the [input] file and returns a [HashDigest] asynchronously. + /// + /// If [start] is present, the file will be read from byte-offset [start]. + /// Otherwise from the beginning (index 0). + /// + /// If [end] is present, only bytes up to byte-index [end] will be read. + /// Otherwise, until end of file. + @pragma('vm:prefer-inline') + Future file(dynamic input, [int start = 0, int? end]) { + throw UnsupportedError('Unavailable for this platform'); + } + + /// Converts the [input] file and returns a [HashDigest] synchronously. + /// + /// If [start] is present, the file will be read from byte-offset [start]. + /// Otherwise from the beginning (index 0). + /// + /// If [end] is present, only bytes up to byte-index [end] will be read. + /// Otherwise, until end of file. + /// + /// If [bufferSize] is present, the file will be read in chunks of this size. + /// By default the [bufferSize] is `2048`. + HashDigest fileSync( + dynamic input, { + int start = 0, + int? end, + int bufferSize = 2048, + }) { + throw UnsupportedError('Unavailable for this platform'); + } +} diff --git a/hashlib/lib/src/core/hash_digest.dart b/hashlib/lib/src/core/hash_digest.dart new file mode 100644 index 0000000..45d4f2f --- /dev/null +++ b/hashlib/lib/src/core/hash_digest.dart @@ -0,0 +1,146 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert' as cvt; +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; + +/// This holds generated hash digest and provides utilities to extract it in +/// multiple formats. +class HashDigest extends Object { + final Uint8List bytes; + + const HashDigest(this.bytes); + + /// Returns the length of this digest in bytes. + int get length => bytes.length; + + /// Returns the byte buffer associated with this digest. + ByteBuffer get buffer => bytes.buffer; + + /// The message digest as a string of hexadecimal digits. + @override + String toString() => hex(); + + /// The message digest as a binary string. + String binary() => toBinary(bytes); + + /// The message digest as a octal string. + String octal() => toOctal(bytes); + + /// The message digest as a hexadecimal string. + /// + /// Parameters: + /// - If [upper] is true, the string will be in uppercase alphabets. + String hex([bool upper = false]) => toHex(bytes, upper: upper); + + /// The message digest as a Base-32 string. + /// + /// If [upper] is true, the output will have uppercase alphabets. + /// If [padding] is true, the output will have `=` padding at the end. + String base32({bool upper = true, bool padding = true}) => + toBase32(bytes, lower: !upper, padding: padding); + + /// The message digest as a Base-64 string with no padding. + /// + /// If [urlSafe] is true, the output will have URL-safe base64 alphabets. + /// If [padding] is true, the output will have `=` padding at the end. + String base64({bool urlSafe = false, bool padding = true}) => + toBase64(bytes, padding: padding, url: urlSafe); + + /// The message digest as a BigInt. + /// + /// If [endian] is [Endian.little], it will treat the digest bytes as a little + /// endian number; Otherwise, if [endian] is [Endian.big], it will treat the + /// digest bytes as a big endian number. + BigInt bigInt({Endian endian = Endian.little}) => + toBigInt(bytes, msbFirst: endian == Endian.big); + + /// Gets unsiged integer of [bitLength]-bit from the message digest. + /// + /// If [endian] is [Endian.little], it will treat the digest bytes as a little + /// endian number; Otherwise, if [endian] is [Endian.big], it will treat the + /// digest bytes as a big endian number. + int number([int bitLength = 64, Endian endian = Endian.big]) { + if (bitLength < 8 || bitLength > 64 || (bitLength & 7) > 0) { + throw ArgumentError( + 'Invalid bit length. ' + 'It must be a number between 8 to 64 and a multiple of 8.', + ); + } else { + bitLength >>>= 3; + } + int result = 0; + int n = bytes.length; + if (endian == Endian.little) { + for (int i = (n > bitLength ? bitLength : n) - 1; i >= 0; i--) { + result <<= 8; + result |= bytes[i]; + } + } else { + for (int i = n > bitLength ? n - bitLength : 0; i < n; i++) { + result <<= 8; + result |= bytes[i]; + } + } + return result; + } + + /// The message digest as a string of ASCII alphabets. + String ascii() => cvt.ascii.decode(bytes); + + /// The message digest as a string of UTF-8 alphabets. + String utf8() => cvt.utf8.decode(bytes); + + /// Returns the digest in the given [encoding] + String to(cvt.Encoding encoding) => encoding.decode(bytes); + + @override + int get hashCode => bytes.hashCode; + + @override + bool operator ==(Object other) => other is HashDigest && bytes == other.bytes; + + /// Checks if the message digest equals to [other]. + /// + /// Here, the [other] can be a one of the following: + /// - Another [HashDigest] object. + /// - An [Iterable] containing an array of bytes + /// - Any [ByteBuffer] or [TypedData] that will be converted to [Uint8List] + /// - A [String], which will be treated as a hexadecimal encoded byte array + /// + /// This function will return True if all bytes in the [other] matches with + /// the [bytes] of this object. If the length does not match, or the type of + /// [other] is not supported, it returns False immediately. + bool isEqual(dynamic other) { + if (other is HashDigest) { + return isEqual(other.bytes); + } else if (other is ByteBuffer) { + return isEqual(Uint8List.view(buffer)); + } else if (other is TypedData && other is! Uint8List) { + return isEqual(Uint8List.view(other.buffer)); + } else if (other is String) { + return isEqual(fromHex(other)); + } else if (other is List) { + if (other.length != bytes.length) { + return false; + } + for (int i = 0; i < bytes.length; ++i) { + if (other[i] != bytes[i++]) { + return false; + } + } + return true; + } else if (other is Iterable) { + int i = 0; + for (int x in other) { + if (i >= bytes.length || x != bytes[i++]) { + return false; + } + } + return true; + } + return false; + } +} diff --git a/hashlib/lib/src/core/kdf_base.dart b/hashlib/lib/src/core/kdf_base.dart new file mode 100644 index 0000000..b621517 --- /dev/null +++ b/hashlib/lib/src/core/kdf_base.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/core/hash_digest.dart'; + +/// Base class for key generator algorithms +abstract class KeyDerivatorBase { + const KeyDerivatorBase(); + + /// The name of this algorithm + String get name; + + /// The length of derived key in bytes + int get derivedKeyLength; + + /// Generate a derived key from a [password] + HashDigest convert(List password); + + /// Returns the derived key in hexadecimal. + @pragma('vm:prefer-inline') + String hex(List password) => convert(password).hex(); + + /// Process the [password] string and returns derived key as [HashDigest]. + /// + /// If [encoding] is not specified, the [String.codeUnits] are used. + @pragma('vm:prefer-inline') + HashDigest string(String password, [Encoding? encoding]) => convert( + encoding != null ? encoding.encode(password) : password.codeUnits, + ); + + /// Verify if the [derivedKey] was derived from the original [password] + /// using the current parameters. + bool verify(List derivedKey, List password) { + if (derivedKey.length != derivedKeyLength) { + return false; + } + var other = convert(password).bytes; + for (int i = 0; i < other.length; ++i) { + if (derivedKey[i] != other[i]) { + return false; + } + } + return true; + } +} diff --git a/hashlib/lib/src/core/mac_base.dart b/hashlib/lib/src/core/mac_base.dart new file mode 100644 index 0000000..520b0b6 --- /dev/null +++ b/hashlib/lib/src/core/mac_base.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/core/hash_base.dart'; +import 'package:hashlib/src/core/hash_digest.dart'; + +/// Base class for the sink used by Message-Authentication-Code generators +abstract class MACSinkBase extends HashDigestSink { + /// The length of generated key in bytes + int get derivedKeyLength => hashLength; +} + +/// This can be used as a mixin for MAC algorithm interfaces +abstract class MACHashBase implements HashBase { + /// Signing the [message] using this MAC to generate a tag. + @pragma('vm:prefer-inline') + HashDigest sign(List message) => convert(message); + + /// Verify if the [tag] is derived from the [message] using this MAC. + @pragma('vm:prefer-inline') + bool verify(List tag, List message) => + convert(message).isEqual(tag); +} + +abstract class MACHash { + const MACHash(); + + /// The name of this algorithm + String get name; + + /// Get a [MACHashBase] instance initialized by a [key]. + @pragma('vm:prefer-inline') + MACHashBase by(List key); + + /// Get a [MACHashBase] instance initialized by a string [key]. + /// + /// If [encoding] is not specified, the [String.codeUnits] are used. + @pragma('vm:prefer-inline') + MACHashBase byString(String key, [Encoding? encoding]) => + by(encoding != null ? encoding.encode(key) : key.codeUnits); + + /// Signing the [message] using a [key] to generate a tag. + @pragma('vm:prefer-inline') + HashDigest sign(List key, List message) => by(key).sign(message); + + /// Verify if the [tag] is derived from the [message] using a [key]. + @pragma('vm:prefer-inline') + bool verify(List key, List tag, List message) => + by(key).verify(tag, message); +} diff --git a/hashlib/lib/src/core/otpauth.dart b/hashlib/lib/src/core/otpauth.dart new file mode 100644 index 0000000..bb6a758 --- /dev/null +++ b/hashlib/lib/src/core/otpauth.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +/// Represents an abstract class for implementing [ One-Time Password (OTP) +/// authentication ][rfc2289] methods in Dart. +/// +/// This class provides a foundation for creating variable length OTP generation +/// algorithms. Subclasses must implement the [value] method to generate OTP +/// values based on a specific algorithm. +/// +/// [rfc2289]: https://www.ietf.org/rfc/rfc2289.html +abstract class OTPAuth { + /// The number of digits in the generated OTP + final int digits; + final String? label; + final String? issuer; + + const OTPAuth( + this.digits, { + this.label, + this.issuer, + }) : assert(digits >= 4); + + /// Generates the next OTP value + int value(); + + /// Returns the next OTP value as string + @pragma('vm:prefer-inline') + String valueString() => value().toString().padLeft(digits, '0'); +} diff --git a/hashlib/lib/src/core/registry.dart b/hashlib/lib/src/core/registry.dart new file mode 100644 index 0000000..c914154 --- /dev/null +++ b/hashlib/lib/src/core/registry.dart @@ -0,0 +1,141 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; + +const int _zero = 48; +const int _nine = 57; +const int _smallA = 97; +const int _smallZ = 122; +const int _bigA = 65; +const int _bigZ = 90; + +final _hash = {}; +final _blockHash = {}; + +/// Transform [value] to uppercase and keeps only letters and digits. +@Deprecated('It will be removed in 2.0.0') +String normalizeName(String value) { + List normal = []; + for (int c in value.codeUnits) { + if ((c >= _zero && c <= _nine) || (c >= _bigA && c <= _bigZ)) { + normal.add(c); + } else if (c >= _smallA && c <= _smallZ) { + normal.add(c - _smallA + _bigA); + } + } + return String.fromCharCodes(normal); +} + +@pragma('vm:prefer-inline') +String _norm(String name) => + // ignore: deprecated_member_use_from_same_package + normalizeName(name); + +void _buildRegistry() { + if (_hash.isNotEmpty) return; + + _hash.addAll({ + _norm(adler32.name): adler32, + _norm(crc16.name): crc16, + _norm(crc32.name): crc32, + _norm(crc64.name): crc64, + }); + + _blockHash.addAll({ + _norm(blake2b160.name): blake2b160, + _norm(blake2b256.name): blake2b256, + _norm(blake2b384.name): blake2b384, + _norm(blake2b512.name): blake2b512, + _norm('BLAKE2'): blake2b512, + _norm('BLAKE2b'): blake2b512, + _norm(blake2s128.name): blake2s128, + _norm(blake2s160.name): blake2s160, + _norm(blake2s224.name): blake2s224, + _norm(blake2s256.name): blake2s256, + _norm('BLAKE2s'): blake2s256, + _norm(keccak224.name): keccak224, + _norm(keccak256.name): keccak256, + _norm(keccak384.name): keccak384, + _norm(keccak512.name): keccak512, + _norm(md2.name): md2, + _norm(md4.name): md4, + _norm(md5.name): md5, + _norm(ripemd128.name): ripemd128, + _norm(ripemd160.name): ripemd160, + _norm(ripemd256.name): ripemd256, + _norm(ripemd320.name): ripemd320, + _norm(sha1.name): sha1, + _norm(sha3_224.name): sha3_224, + _norm(sha3_256.name): sha3_256, + _norm(sha3_384.name): sha3_384, + _norm(sha3_512.name): sha3_512, + _norm('SHA3'): sha3_512, + _norm(sha224.name): sha224, + _norm(sha256.name): sha256, + _norm('SHA2'): sha256, + _norm(sha384.name): sha384, + _norm(sha512.name): sha512, + _norm(sha512t224.name): sha512t224, + _norm(sha512t256.name): sha512t256, + _norm(shake128_128.name): shake128_128, + _norm(shake128_160.name): shake128_160, + _norm(shake128_224.name): shake128_224, + _norm(shake128_256.name): shake128_256, + _norm('SHAKE-128'): shake128_256, + _norm(shake128_384.name): shake128_384, + _norm(shake128_512.name): shake128_512, + _norm(shake256_128.name): shake256_128, + _norm(shake256_160.name): shake256_160, + _norm(shake256_224.name): shake256_224, + _norm(shake256_256.name): shake256_256, + _norm(shake256_384.name): shake256_384, + _norm(shake256_512.name): shake256_512, + _norm('SHAKE-512'): shake256_512, + _norm(sm3.name): sm3, + _norm(xxh3.name): xxh3, + _norm('XXH3-64'): xxh3, + _norm(xxh32.name): xxh32, + _norm(xxh64.name): xxh64, + _norm(xxh128.name): xxh128, + _norm('XXH3-128'): xxh128, + }); + _hash.addAll(_blockHash); +} + +/// A registry to find a block hash algorithm by name +@Deprecated('It will be removed in 2.0.0') +class BlockHashRegistry { + /// Find a [BlockHashBase] algorithm given a string name + static BlockHashBase? lookup(String name) { + _buildRegistry(); + return _blockHash[_norm(name)]; + } + + /// Register a new [BlockHashBase] algorithm on the fly given a string name + static void register(BlockHashBase algo, [String? name]) { + _buildRegistry(); + name = _norm(name ?? algo.name); + _blockHash[name] = algo; + } +} + +/// A registry to find a hash algorithm by name +@Deprecated('It will be removed in 2.0.0') +class HashRegistry { + /// Find a [HashBase] algorithm given a string name + static HashBase? lookup(String name) { + _buildRegistry(); + return _hash[_norm(name)]; + } + + /// Register a new [HashBase] algorithm on the fly given a string name + static void register(HashBase algo, [String? name]) { + _buildRegistry(); + name = _norm(name ?? algo.name); + _hash[name] = algo; + if (algo is BlockHashBase) { + _blockHash[name] = algo; + } + } +} diff --git a/hashlib/lib/src/crc16.dart b/hashlib/lib/src/crc16.dart new file mode 100644 index 0000000..484756f --- /dev/null +++ b/hashlib/lib/src/crc16.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/crc/crc16.dart'; +import 'package:hashlib/src/core/hash_base.dart'; + +export 'package:hashlib/src/algorithms/crc/crc16.dart' + show CRC16Hash, CRC16Params; + +/// A CRC or cyclic redundancy check is code commonly used for error detection +/// and correction of digital data. This generates a 16-bit number as output. +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const crc16 = CRC16(CRC16Params.ibm); + +/// CRC-16 code generator +class CRC16 extends HashBase { + final CRC16Params params; + + /// Create a instance for generating CRC-16 hashes + const CRC16(this.params); + + @override + String get name => "CRC-16/${params.name}"; + + @override + CRC16Hash createSink() => + params.reversed ? CRC16ReverseHash(params) : CRC16NormalHash(params); + + /// Gets the CRC-16 code for a String + /// + /// Parameters: + /// - [input] is the string to hash + /// - The [encoding] is the encoding to use. Default is `input.codeUnits` + int code(String input, [Encoding? encoding]) => + string(input, encoding).number(); +} + +/// Gets the CRC-16 value. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - The [params] is the parameters to use. Default: [CRC16Params.ansi] +int crc16code( + String input, { + Encoding? encoding, + CRC16Params params = CRC16Params.ansi, +}) => + CRC16(params).code(input, encoding); diff --git a/hashlib/lib/src/crc32.dart b/hashlib/lib/src/crc32.dart new file mode 100644 index 0000000..d7c7f5f --- /dev/null +++ b/hashlib/lib/src/crc32.dart @@ -0,0 +1,55 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/crc/crc32.dart'; +import 'package:hashlib/src/core/hash_base.dart'; + +export 'package:hashlib/src/algorithms/crc/crc32.dart' + show CRC32Hash, CRC32Params; + +/// A CRC-32 code generator with **IEEE** 802.3 CRC-32 polynomial. +/// +/// A CRC or cyclic redundancy check is code commonly used for error detection +/// and correction of digital data. This generates a 32-bit number as output. +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const crc32 = CRC32(CRC32Params.ieee); + +/// CRC-32 code generator +class CRC32 extends HashBase { + final CRC32Params params; + + /// Create a instance for generating CRC-32 hashes + const CRC32(this.params); + + @override + String get name => "CRC-32/${params.name}"; + + @override + CRC32Hash createSink() => + params.reversed ? CRC32ReverseHash(params) : CRC32NormalHash(params); + + /// Gets the CRC-32 code for a String + /// + /// Parameters: + /// - [input] is the string to hash + /// - The [encoding] is the encoding to use. Default is `input.codeUnits` + @pragma('vm:prefer-inline') + int code(String input, [Encoding? encoding]) => + string(input, encoding).number(); +} + +/// Gets the CRC-32 value. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - The [params] is the parameters to use. Default: [CRC32Params.ieee] +int crc32code( + String input, { + Encoding? encoding, + CRC32Params params = CRC32Params.ieee, +}) => + CRC32(params).code(input, encoding); diff --git a/hashlib/lib/src/crc64.dart b/hashlib/lib/src/crc64.dart new file mode 100644 index 0000000..4a5b9c7 --- /dev/null +++ b/hashlib/lib/src/crc64.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/crc/crc64.dart'; +import 'package:hashlib/src/core/hash_base.dart'; + +export 'package:hashlib/src/algorithms/crc/crc64.dart' + show CRC64Hash, CRC64Params; + +/// A CRC-64 code generator with **ISO** CRC-64 polynomial. +/// +/// A CRC or cyclic redundancy check is code commonly used for error detection +/// and correction of digital data. This generates a 64-bit number as output. +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const crc64 = CRC64(CRC64Params.iso); + +/// CRC-64 code generator +class CRC64 extends HashBase { + final CRC64Params params; + + /// Create a instance for generating CRC-64 hashes + const CRC64([this.params = CRC64Params.iso]); + + @override + String get name => "CRC-64/${params.name}"; + + @override + CRC64Hash createSink() => + params.reversed ? CRC64ReverseHash(params) : CRC64NormalHash(params); + + /// Gets the CRC-64 code for a String + /// + /// Parameters: + /// - [input] is the string to hash + /// - The [encoding] is the encoding to use. Default is `input.codeUnits` + @pragma('vm:prefer-inline') + int code(String input, [Encoding? encoding]) => + string(input, encoding).number(); + + /// Gets the CRC-64 checksum for a String + /// + /// Parameters: + /// - [input] is the string to hash + /// - The [encoding] is the encoding to use. Default is `input.codeUnits` + @pragma('vm:prefer-inline') + String checksum(String input, [Encoding? encoding]) => + string(input, encoding).hex(); +} + +/// Gets the CRC-64 value. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - The [params] is the parameters to use. Default: [CRC64Params.iso] +int crc64code( + String input, { + Encoding? encoding, + CRC64Params params = CRC64Params.iso, +}) => + CRC64(params).code(input, encoding); + +/// Gets the CRC-64 hash in hexadecimal. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - The [params] is the parameters to use. Default: [CRC64Params.iso] +String crc64sum( + String input, { + Encoding? encoding, + CRC64Params params = CRC64Params.iso, +}) => + CRC64(params).checksum(input, encoding); diff --git a/hashlib/lib/src/hashlib.dart b/hashlib/lib/src/hashlib.dart new file mode 100644 index 0000000..c33aaaf --- /dev/null +++ b/hashlib/lib/src/hashlib.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'adler32.dart'; +export 'argon2.dart'; +export 'bcrypt.dart'; +export 'blake2b.dart'; +export 'blake2s.dart'; +export 'core/block_hash.dart'; +export 'core/hash_base.dart'; +export 'core/hash_digest.dart'; +export 'core/kdf_base.dart'; +export 'core/mac_base.dart'; +export 'core/otpauth.dart'; +export 'core/registry.dart'; +export 'crc16.dart'; +export 'crc32.dart'; +export 'crc64.dart'; +export 'hmac.dart'; +export 'hotp.dart'; +export 'keccak224.dart'; +export 'keccak256.dart'; +export 'keccak384.dart'; +export 'keccak512.dart'; +export 'md2.dart'; +export 'md4.dart'; +export 'md5.dart'; +export 'pbkdf2.dart'; +export 'poly1305.dart'; +export 'ripemd128.dart'; +export 'ripemd160.dart'; +export 'ripemd256.dart'; +export 'ripemd320.dart'; +export 'scrypt.dart'; +export 'sha1.dart'; +export 'sha224.dart'; +export 'sha256.dart'; +export 'sha384.dart'; +export 'sha3_224.dart'; +export 'sha3_256.dart'; +export 'sha3_384.dart'; +export 'sha3_512.dart'; +export 'sha512.dart'; +export 'sha512t.dart'; +export 'shake128.dart'; +export 'shake256.dart'; +export 'sm3.dart'; +export 'totp.dart'; +export 'xxh128.dart'; +export 'xxh3.dart'; +export 'xxh32.dart'; +export 'xxh64.dart'; diff --git a/hashlib/lib/src/hmac.dart b/hashlib/lib/src/hmac.dart new file mode 100644 index 0000000..3fc2df6 --- /dev/null +++ b/hashlib/lib/src/hmac.dart @@ -0,0 +1,53 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/hmac.dart'; +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/hash_base.dart'; +import 'package:hashlib/src/core/mac_base.dart'; +import 'package:hashlib/src/sha256.dart'; + +/// The HMAC/SHA-256 algorithm +// ignore: constant_identifier_names +const hmac_sha256 = HMAC(sha256); + +/// HMAC is a hash-based message authentication code that can be used to +/// simultaneously verify both the data integrity and authenticity of a message. +class _HMAC extends HashBase> + with MACHashBase> { + /// The algorithm for the MAC generation + final T algo; + final List key; + + const _HMAC(this.algo, this.key); + + @override + String get name => '${algo.name}/HMAC'; + + @override + HMACSink createSink() => HMACSink(algo, key); +} + +/// HMAC is a hash-based message authentication code that can be used to +/// simultaneously verify both the data integrity and authenticity of a message. +class HMAC extends MACHash> { + /// The algorithm for the MAC generation + final T algo; + + const HMAC(this.algo); + + @override + String get name => '${algo.name}/HMAC'; + + @override + MACHashBase> by(List key) => _HMAC(algo, key); +} + +/// Extension on [BlockHashBase] to get an [HMAC] instance +extension HMAConBlockHashBase on T { + /// Gets a [HMAC] instance builder for this algorithm. + /// + /// HMAC is a hash-based message authentication code that can be used to + /// simultaneously verify both the data integrity and authenticity of a message. + HMAC get hmac => HMAC(this); +} diff --git a/hashlib/lib/src/hotp.dart b/hashlib/lib/src/hotp.dart new file mode 100644 index 0000000..c6ea56c --- /dev/null +++ b/hashlib/lib/src/hotp.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/mac_base.dart'; +import 'package:hashlib/src/core/otpauth.dart'; +import 'package:hashlib/src/hmac.dart'; +import 'package:hashlib/src/sha1.dart'; + +// power of 10 upto max safe integer in javascript +const _pow10 = [ + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, +]; + +/// An HMAC-based One-Time Password (HOTP) algorithm implementation derived +/// from [rfc4226]. +/// +/// [rfc4226]: https://www.ietf.org/rfc/rfc4226.html +class HOTP extends OTPAuth { + final int _max; + + /// The underlying MAC algorithm + final MACHashBase algo; + + /// The secret key + final List secret; + + /// The counter value + final List counter; + + /// The algorithm name + String get name => algo.name; + + /// Creates an instance of the [HOTP] class with the specified parameters. + /// + /// Parameters: + /// - [secret] is the shared secret as a list of bytes for generating the OTP. + /// - [digits] is the number of digits in the generated OTP (default is 6). + /// - [counter] is the counter value used in the HOTP algorithm (required). + /// - [algo] is the block hash algorithm to use (default is [sha1]). + /// - [label] is an optional string to identify the account or service the OTP + /// is associated with. + /// - [issuer] is an optional string to specify the entity issuing the OTP. + HOTP( + this.secret, { + int digits = 6, + required this.counter, + BlockHashBase algo = sha1, + String? label, + String? issuer, + }) : assert(digits <= 15), + algo = HMAC(algo).by(secret), + _max = _pow10[digits], + super( + digits, + label: label, + issuer: issuer, + ); + + @override + int value() { + var digest = algo.convert(counter).bytes; + int offset = digest.last & 0xF; + int dbc = ((digest[offset] & 0x7F) << 24) | + ((digest[offset + 1] & 0xFF) << 16) | + ((digest[offset + 2] & 0xFF) << 8) | + (digest[offset + 3] & 0xFF); + return dbc % _max; + } +} diff --git a/hashlib/lib/src/keccak224.dart b/hashlib/lib/src/keccak224.dart new file mode 100644 index 0000000..4f132c8 --- /dev/null +++ b/hashlib/lib/src/keccak224.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/keccak/keccak.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// Keccak-224 is a member of Keccak family hash functions that generates +/// a 224-bit hash. +/// +/// Keccak is a secure and versatile hash function family that uses a simple +/// [sponge construction][sponge] and Keccak-f cryptographic permutation. +/// After its selection as the winner of the SHA-3 competition, Keccak has +/// been standardized in NIST standards [FIPS 202][fips202] +/// +/// _Note that the standard implementation of Keccak-224 is available as +/// SHA3-224. This one follows the original design. However, the only +/// difference between them is the choice of the final padding._ +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase keccak224 = _Keccak224(); + +class _Keccak224 extends BlockHashBase { + const _Keccak224(); + + @override + final String name = 'Keccak-224'; + + @override + Keccak224Hash createSink() => Keccak224Hash(); +} + +/// Generates a Keccak-224 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String keccak224sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return keccak224.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/keccak256.dart b/hashlib/lib/src/keccak256.dart new file mode 100644 index 0000000..97800d5 --- /dev/null +++ b/hashlib/lib/src/keccak256.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/keccak/keccak.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// Keccak-256 is a member of Keccak family hash functions that generates +/// a 256-bit hash. +/// +/// Keccak is a secure and versatile hash function family that uses a simple +/// [sponge construction][sponge] and Keccak-f cryptographic permutation. +/// After its selection as the winner of the SHA-3 competition, Keccak has +/// been standardized in NIST standards [FIPS 202][fips202] +/// +/// _Note that the standard implementation of Keccak-256 is available as +/// SHA3-256. This one follows the original design. However, the only +/// difference between them is the choice of the final padding._ +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase keccak256 = _Keccak256(); + +class _Keccak256 extends BlockHashBase { + const _Keccak256(); + + @override + final String name = 'Keccak-256'; + + @override + Keccak256Hash createSink() => Keccak256Hash(); +} + +/// Generates a Keccak-256 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String keccak256sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return keccak256.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/keccak384.dart b/hashlib/lib/src/keccak384.dart new file mode 100644 index 0000000..196725a --- /dev/null +++ b/hashlib/lib/src/keccak384.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/keccak/keccak.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// Keccak-384 is a member of Keccak family hash functions that generates +/// a 384-bit hash. +/// +/// Keccak is a secure and versatile hash function family that uses a simple +/// [sponge construction][sponge] and Keccak-f cryptographic permutation. +/// After its selection as the winner of the SHA-3 competition, Keccak has +/// been standardized in NIST standards [FIPS 202][fips202] +/// +/// _Note that the standard implementation of Keccak-384 is available as +/// SHA3-384. This one follows the original design. However, the only +/// difference between them is the choice of the final padding._ +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase keccak384 = _Keccak384(); + +class _Keccak384 extends BlockHashBase { + const _Keccak384(); + + @override + final String name = 'Keccak-384'; + + @override + Keccak384Hash createSink() => Keccak384Hash(); +} + +/// Generates a Keccak-384 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String keccak384sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return keccak384.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/keccak512.dart b/hashlib/lib/src/keccak512.dart new file mode 100644 index 0000000..b028252 --- /dev/null +++ b/hashlib/lib/src/keccak512.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/keccak/keccak.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// Keccak-512 is a member of Keccak family hash functions that generates +/// a 512-bit hash. +/// +/// Keccak is a secure and versatile hash function family that uses a simple +/// [sponge construction][sponge] and Keccak-f cryptographic permutation. +/// After its selection as the winner of the SHA-3 competition, Keccak has +/// been standardized in NIST standards [FIPS 202][fips202] +/// +/// _Note that the standard implementation of Keccak-512 is available as +/// SHA3-512. This one follows the original design. However, the only +/// difference between them is the choice of the final padding._ +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase keccak512 = _Keccak512(); + +class _Keccak512 extends BlockHashBase { + const _Keccak512(); + + @override + final String name = 'Keccak-512'; + + @override + Keccak512Hash createSink() => Keccak512Hash(); +} + +/// Generates a Keccak-512 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String keccak512sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return keccak512.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/md2.dart b/hashlib/lib/src/md2.dart new file mode 100644 index 0000000..bfa6a63 --- /dev/null +++ b/hashlib/lib/src/md2.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/md2.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// MD2 was primarily used in early software systems and digital signature +/// standards (such as early versions of X.509 certificates), but its use has +/// been deprecated due to security weaknesses. +/// +/// **WARNING: It is considered cryptographically broken and insecure.** +const BlockHashBase md2 = _MD2(); + +class _MD2 extends BlockHashBase { + const _MD2(); + + @override + final String name = 'MD2'; + + @override + MD2Hash createSink() => MD2Hash(); +} + +/// Generates a MD2 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String md2sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return md2.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/md4.dart b/hashlib/lib/src/md4.dart new file mode 100644 index 0000000..caffa46 --- /dev/null +++ b/hashlib/lib/src/md4.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/md4.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// MD4 can be used as a checksum to verify data integrity against unintentional +/// corruption. Although it was widely used as a cryptographic hash function +/// once, it has been found to suffer from extensive vulnerabilities. +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const BlockHashBase md4 = _MD4(); + +class _MD4 extends BlockHashBase { + const _MD4(); + + @override + final String name = 'MD4'; + + @override + MD4Hash createSink() => MD4Hash(); +} + +/// Generates a MD4 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String md4sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return md4.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/md5.dart b/hashlib/lib/src/md5.dart new file mode 100644 index 0000000..abf456a --- /dev/null +++ b/hashlib/lib/src/md5.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/md5.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// MD5 can be used as a checksum to verify data integrity against unintentional +/// corruption. Although it was widely used as a cryptographic hash function +/// once, it has been found to suffer from extensive vulnerabilities. +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const BlockHashBase md5 = _MD5(); + +class _MD5 extends BlockHashBase { + const _MD5(); + + @override + final String name = 'MD5'; + + @override + MD5Hash createSink() => MD5Hash(); +} + +/// Generates a MD5 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String md5sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return md5.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/pbkdf2.dart b/hashlib/lib/src/pbkdf2.dart new file mode 100644 index 0000000..21eb48f --- /dev/null +++ b/hashlib/lib/src/pbkdf2.dart @@ -0,0 +1,81 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/pbkdf2/pbkdf2.dart'; +import 'package:hashlib/src/algorithms/pbkdf2/security.dart'; +import 'package:hashlib/src/core/block_hash.dart'; +import 'package:hashlib/src/core/hash_digest.dart'; +import 'package:hashlib/src/core/mac_base.dart'; +import 'package:hashlib/src/hmac.dart'; +import 'package:hashlib/src/sha256.dart'; + +export 'algorithms/pbkdf2/pbkdf2.dart' show PBKDF2; +export 'algorithms/pbkdf2/security.dart' show PBKDF2Security; + +/// Extension to the HashBase to get an [PBKDF2] instance +extension PBKDF2onMACHashBase on MACHash { + /// Generate a secret using [PBKDF2] hash algorithm. + @pragma('vm:prefer-inline') + PBKDF2 pbkdf2( + List salt, { + PBKDF2Security security = PBKDF2Security.good, + int? iterations, + int? keyLength, + }) => + PBKDF2.fromSecurity( + security, + mac: this, + salt: salt, + keyLength: keyLength, + iterations: iterations, + ); +} + +/// Extension on [BlockHashBase] to get an [PBKDF2] instance +extension PBKDF2onBlockHashBase on BlockHashBase { + /// Generate a secret using [PBKDF2] hash algorithm. + @pragma('vm:prefer-inline') + PBKDF2 pbkdf2( + List salt, { + PBKDF2Security security = PBKDF2Security.good, + int? iterations, + int? keyLength, + }) => + PBKDF2.fromSecurity( + security, + mac: HMAC(this), + salt: salt, + keyLength: keyLength, + iterations: iterations, + ); +} + +/// This is an implementation of Password Based Key Derivation Algorithm, +/// PBKDF2 derived from [RFC-8081][rfc], which internally uses [sha256] hash +/// function for key derivation. +/// +/// Parameters: +/// - [password] is the raw password to be encoded. +/// - [salt] should be at least 8 bytes long. 16 bytes is recommended. +/// - [iterations] is the number of iterations. Default: 50000 +/// - [keyLength] is the length of the generated key. Default: 32 +/// +/// The strength of the generated key depends on the number of [iterations]. +/// The idea is to prevent a brute force attack on the original password by +/// making the key derivation time long. +/// +/// [rfc]: https://www.rfc-editor.org/rfc/rfc8018.html#section-5.2 +@pragma('vm:prefer-inline') +HashDigest pbkdf2( + List password, + List salt, [ + int? iterations, + int? keyLength, +]) => + hmac_sha256 + .pbkdf2( + salt, + keyLength: keyLength, + iterations: iterations, + ) + .convert(password); diff --git a/hashlib/lib/src/poly1305.dart b/hashlib/lib/src/poly1305.dart new file mode 100644 index 0000000..6e0c4e6 --- /dev/null +++ b/hashlib/lib/src/poly1305.dart @@ -0,0 +1,127 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/src/algorithms/poly1305/poly1305_sink.dart'; +import 'package:hashlib/src/core/hash_base.dart'; +import 'package:hashlib/src/core/hash_digest.dart'; +import 'package:hashlib/src/core/mac_base.dart'; + +export 'algorithms/poly1305/poly1305_sink.dart' show Poly1305Sink; + +class _Poly1305 extends MACHash { + const _Poly1305(); + + @override + final String name = 'Poly1305'; + + /// Create a new instance of [_Poly1305] with a 16 or 32-byte long keypair. + /// The first 16-bytes will be used as a secret key to encode the message, + /// and the last 16-bytes will be used as the authentication key to sign it. + /// + /// Parameters: + /// - [keypair] is required and must contain exactly 16 or 32 bytes. + /// + /// If [keypair] length is 16 bytes, the final digest will not be signed. + /// + /// **Warning**: + /// The algorithm is designed to ensure unforgeability of a message with a + /// random key. Authenticating multiple messages using the same key could + /// allow for forgeries. + /// + /// See also: + /// - [_Poly1305.pair] to input key(`r`) and secret(`s`) pair separately. + @override + MACHashBase by(List keypair) => + Poly1305(keypair is Uint8List ? keypair : Uint8List.fromList(keypair)); + + /// Creates a new instance of [_Poly1305]. + /// + /// Parameters: + /// - [key] is required and must contain exactly 16 bytes. + /// - [secret] is optional and must contain exactly 16 bytes. + /// + /// Here, the [key] is used to encode the message, and the [secret] + /// is the authentication code used to sign it. The [secret] parameter is + /// optional and if not provided, the final digest will not be signed. + /// + /// **Warning**: + /// The algorithm is designed to ensure unforgeability of a message with a + /// random key. Authenticating multiple messages using the same key could + /// allow for forgeries. + /// + /// See also: + /// - [_Poly1305.by] to input key(`r`) and secret(`s`) pair together. + MACHashBase pair(List key, [List? secret]) { + if (secret == null) { + return by(key); + } + if (key.length != 16) { + throw StateError('The key length must be 16 bytes'); + } + if (secret.length != 16) { + throw StateError('The secret length must be 16 bytes'); + } + var pair = Uint8List(32); + pair.setAll(0, key); + pair.setAll(16, secret); + return Poly1305(pair); + } +} + +/// The Poly1305 MAC (message authentication code) generator for an input +/// message using either 16 or 32-byte long authentication key. +const poly1305 = _Poly1305(); + +/// Poly1305 MAC generator with a custom 16 or 32-byte long keypair. +class Poly1305 extends HashBase with MACHashBase { + final Uint8List keypair; + + @override + final String name = 'Poly1305'; + + /// Create a new instance of Poly1305 MAC with a 16 or 32-byte long keypair. + /// The first 16-bytes will be used as a secret key to encode the message, + /// and the last 16-bytes will be used as the authentication key to sign it. + /// + /// Parameters: + /// - [keypair] is required and must contain exactly 16 or 32 bytes. + /// + /// If [keypair] length is 16 bytes, the final digest will not be signed. + /// + /// **Warning**: + /// The algorithm is designed to ensure unforgeability of a message with a + /// random key. Authenticating multiple messages using the same key could + /// allow for forgeries. + /// + /// See also: + /// - [_Poly1305.pair] to input key(`r`) and secret(`s`) pair separately. + const Poly1305(this.keypair); + + @override + Poly1305Sink createSink() => Poly1305Sink(keypair); +} + +/// Computes the Poly1305 MAC (message authentication code) of the given +/// [message] using the given the 16 or 32-byte long [keypair] for authentication. +/// +/// Parameters: +/// - [message] is a variable-length list of bytes +/// - [keypair] is required and must contain exactly 16 or 32 bytes. +/// +/// If [keypair] length is 16 bytes, the final digest will not be signed. +/// +/// **Warning**: +/// The algorithm is designed to ensure unforgeability of a message with a +/// random key. Authenticating multiple messages using the same key could +/// allow for forgeries. +/// +/// Example usage: +/// ``` +/// final keypair = randomBytes(32); +/// print('TAG(signed): ${poly1305auth(message, keypair)}'); +/// ``` +@pragma('vm:prefer-inline') +HashDigest poly1305auth(List message, List keypair) => + poly1305.by(keypair).convert(message); diff --git a/hashlib/lib/src/random.dart b/hashlib/lib/src/random.dart new file mode 100644 index 0000000..8348ec9 --- /dev/null +++ b/hashlib/lib/src/random.dart @@ -0,0 +1,81 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'random/generators.dart'; +import 'random/random.dart'; + +export 'random/generators.dart' show RNG; +export 'random/random.dart' show HashlibRandom; + +/// Generate a list of random 8-bit numbers of size [length] +@pragma('vm:prefer-inline') +Uint8List randomBytes( + int length, { + RNG generator = RNG.secure, +}) => + HashlibRandom(generator).nextBytes(length); + +/// Generate a list of random 32-bit numbers of size [length] +@pragma('vm:prefer-inline') +Uint32List randomNumbers( + int length, { + RNG generator = RNG.secure, +}) => + HashlibRandom(generator).nextNumbers(length); + +/// Fills the [buffer] with random numbers. +/// +/// Both the [start] and [length] are in bytes. +@pragma('vm:prefer-inline') +void fillRandom( + ByteBuffer buffer, { + int start = 0, + int? length, + RNG generator = RNG.secure, +}) => + HashlibRandom(generator).fill(buffer, start, length); + +/// Fills the [list] with random 32-bit numbers. +/// +/// Both the [start] and [length] are in bytes. +void fillNumbers( + List list, { + int start = 0, + int? length, + RNG generator = RNG.secure, +}) { + int n = length ?? list.length; + if (n == 0) return; + var rand = HashlibRandom(generator); + for (; n > 0 && start < list.length; ++start, --n) { + list[start] = rand.nextInt(); + } +} + +/// Generate a list of random ASCII string of size [length]. +/// +/// Check the [HashlibRandom.nextString] documentation for more details. +@pragma('vm:prefer-inline') +String randomString( + int length, { + bool? lower, + bool? upper, + bool? numeric, + bool? controls, + bool? punctuations, + List? whitelist, + List? blacklist, + RNG generator = RNG.secure, +}) => + HashlibRandom(generator).nextString( + length, + lower: lower, + upper: upper, + numeric: numeric, + controls: controls, + punctuations: punctuations, + whitelist: whitelist, + blacklist: blacklist, + ); diff --git a/hashlib/lib/src/random/generator_js.dart b/hashlib/lib/src/random/generator_js.dart new file mode 100644 index 0000000..99f6fbb --- /dev/null +++ b/hashlib/lib/src/random/generator_js.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:math' show Random; + +const int _mask32 = 0xFFFFFFFF; + +int _seedCounter = Zone.current.hashCode; + +/// Returns a secure random generator in JS runtime +Random secureRandom() => Random($generateSeed()); + +/// Generates a random seed in JS runtime +int $generateSeed() { + int code = DateTime.now().millisecondsSinceEpoch; + code -= _seedCounter++; + if (code.bitLength & 1 == 1) { + code *= ~code; + } + code ^= ~_seedCounter << 5; + _seedCounter += code & 7; + return code & _mask32; +} diff --git a/hashlib/lib/src/random/generator_vm.dart b/hashlib/lib/src/random/generator_vm.dart new file mode 100644 index 0000000..3c2bb5d --- /dev/null +++ b/hashlib/lib/src/random/generator_vm.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math' show Random; + +const int _mask32 = 0xFFFFFFFF; + +/// Returns a secure random generator +@pragma('vm:prefer-inline') +Random secureRandom() => Random.secure(); + +/// Generates a random seed +@pragma('vm:prefer-inline') +int $generateSeed() => + (DateTime.now().microsecondsSinceEpoch & _mask32) ^ + Random.secure().nextInt(_mask32); diff --git a/hashlib/lib/src/random/generators.dart b/hashlib/lib/src/random/generators.dart new file mode 100644 index 0000000..31462e1 --- /dev/null +++ b/hashlib/lib/src/random/generators.dart @@ -0,0 +1,137 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math' show Random; +import 'dart:typed_data'; + +import 'package:hashlib/src/algorithms/keccak/keccak.dart'; +import 'package:hashlib/src/algorithms/md4.dart'; +import 'package:hashlib/src/algorithms/sha2/sha2.dart'; +import 'package:hashlib/src/algorithms/sm3.dart'; +import 'package:hashlib/src/algorithms/xxh64/xxh64.dart'; +import 'package:hashlib/src/core/hash_base.dart'; + +import 'generator_vm.dart' if (dart.library.js) 'generator_js.dart'; +export 'generator_vm.dart' if (dart.library.js) 'generator_js.dart'; + +const int _mask32 = 0xFFFFFFFF; + +typedef NextIntFunction = int Function(); + +/// Available Random Number Generators +enum RNG { + secure, + system, + keccak, + sha256, + md5, + xxh64, + sm3; + + /// Gets the function returning the next 32-bit integer by this RNG + NextIntFunction build([int? seed]) { + switch (this) { + case RNG.keccak: + return _keccakGenerateor(seed); + case RNG.sha256: + return _hashGenerateor(SHA256Hash(), seed); + case RNG.md5: + return _hashGenerateor(MD4Hash(), seed); + case RNG.xxh64: + return _hashGenerateor(XXHash64Sink(111), seed); + case RNG.sm3: + return _hashGenerateor(SM3Hash(), seed); + case RNG.system: + return _systemGenerator(seed); + case RNG.secure: + default: + return _secureGenerator(); + } + } +} + +/// Expands the seed to fill the list +void $seedList(TypedData data, int seed) { + var list = Uint32List.view(data.buffer); + var inp = [ + seed & _mask32, + seed >>> 32, + list.length, + 0xD5A79147, + 0x14292967 + list.length, + 0x59F111F1 ^ -seed.bitLength, + 0x106AA070 + seed, + 0x71374491 - seed, + 0x06CA6351 ^ seed, + 0x650A7354, + 0xF40E3585, + 0x766A0ABB ^ -seed, + 0x81C2C92E, + 0x92722C85, + 0x748F82EE ^ -list.length, + 0x78A5636F | -seed, + ]; + + int i, x; + for (i = 0; i < 16 && i < list.length; ++i) { + list[i] ^= inp[i]; + } + for (x = seed; i < list.length; ++i) { + list[i] ^= x = (x >>> (i & 15)) ^ seed; + list[i] ^= list[i - 16]; + list[i] ^= -list[i - 7]; + } + var list8 = Uint8List.view(data.buffer); + for (i = list.lengthInBytes; i < list8.length; ++i) { + list8[i] ^= seed >>> (i & 31); + } +} + +/// Returns a iterable of 32-bit integers backed by system's [Random]. +NextIntFunction _secureGenerator() { + final random = secureRandom(); + return () => random.nextInt(_mask32); +} + +/// Returns a iterable of 32-bit integers backed by system's [Random]. +NextIntFunction _systemGenerator([int? seed]) { + final random = Random(seed ?? $generateSeed()); + return () => random.nextInt(_mask32); +} + +/// Returns a iterable of 32-bit integers generated from the [KeccakHash]. +NextIntFunction _keccakGenerateor([int? seed]) { + int l, p; + var sink = KeccakHash(stateSize: 64, paddingByte: 0); + $seedList(sink.sbuffer, seed ?? $generateSeed()); + p = l = sink.sbuffer.length; + return () { + if (p == l) { + p = 0; + sink.$update(); + } + return sink.sbuffer[p++]; + }; +} + +/// Returns a iterable of 32-bit integers generated from the [sink]. +NextIntFunction _hashGenerateor( + HashDigestSink sink, [ + int? seed, +]) { + int l, p; + var input = Uint8List(64); + var input32 = Uint32List(0); + $seedList(input, seed ?? $generateSeed()); + l = p = sink.hashLength >>> 2; + return () { + if (p == l) { + p = 0; + sink.reset(); + sink.add(input); + input = sink.$finalize(); + input32 = Uint32List.view(input.buffer); + } + return input32[p++]; + }; +} diff --git a/hashlib/lib/src/random/random.dart b/hashlib/lib/src/random/random.dart new file mode 100644 index 0000000..0cec008 --- /dev/null +++ b/hashlib/lib/src/random/random.dart @@ -0,0 +1,203 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'generators.dart'; + +const int _mask32 = 0xFFFFFFFF; + +const String _alphaLower = 'abcdefghijklmnopqrstuvwxyz'; +const String _alphaUpper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; +const String _numeric = '0123456789'; +const List _controls = [ + 0, 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, + 127 +]; +const List _punctuations = [ + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // + 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126, +]; + +/// Provides a generator for secure random values +class HashlibRandom { + final NextIntFunction _nextInt; + + /// Create a instance with custom generator + const HashlibRandom.custom(this._nextInt); + + /// Creates an instance based on [generator] with optional [seed] value. + factory HashlibRandom(RNG generator, {int? seed}) => + HashlibRandom.custom(generator.build(seed)); + + /// Creates an instance based on `RNG.secure` generator with + /// optional [seed] value. + factory HashlibRandom.secure({int? seed}) => + HashlibRandom.custom(RNG.secure.build(seed)); + + /// Generates a 32-bit bit random number + @pragma('vm:prefer-inline') + int nextInt() => _nextInt(); + + /// Generates a 16-bit bit random number + @pragma('vm:prefer-inline') + int nextWord() => nextInt() & 0xFFFF; + + /// Generates a 8-bit bit random number + @pragma('vm:prefer-inline') + int nextByte() => (nextInt() >>> 11) & 0xFF; + + /// Generates a boolean value + @pragma('vm:prefer-inline') + bool nextBool() => nextByte() & 0x55 == 0; + + /// Generates a double number + @pragma('vm:prefer-inline') + double nextDouble() => nextInt() / _mask32; + + /// Generates a 32-bit bit random number between [low] and [high], inclusive. + int nextBetween(int low, int high) { + if (low == high) { + return low; + } + if (low > high) { + int t = low; + low = high; + high = t; + } + return (nextInt() % (high - low)) + low; + } + + /// Fill the buffer with random values. + /// + /// Paramters: + /// - [offsetInBytes] the start offset in bytes for the fill operation. + /// - [lengthInBytes] the total bytes to fill. If `null`, fills to the end. + void fill(ByteBuffer buffer, [int offsetInBytes = 0, int? lengthInBytes]) { + int i, n; + i = offsetInBytes; + n = lengthInBytes ?? buffer.lengthInBytes; + if (n <= 0) return; + var list8 = Uint8List.view(buffer); + for (; n > 0 && i < list8.length && i & 3 != 0; i++, n--) { + list8[i] = nextByte(); + } + if (n <= 0) return; + var list32 = Uint32List.view(buffer); + for (i >>>= 2; n >= 4 && i < list32.length; i++, n -= 4) { + list32[i] = nextInt(); + } + if (n <= 0) return; + for (i <<= 2; n > 0 && i < list8.length; i++, n--) { + list8[i] = nextByte(); + } + } + + /// Generate a list of random 8-bit bytes of size [length] + @pragma('vm:prefer-inline') + Uint8List nextBytes(int length) { + var data = Uint8List(length); + fill(data.buffer); + return data; + } + + /// Generate a list of random 32-bit numbers of size [length] + @pragma('vm:prefer-inline') + Uint32List nextNumbers(int length) { + var data = Uint32List(length); + fill(data.buffer); + return data; + } + + /// Generate the next random string of specific [length]. + /// + /// If no parameter is provided, it will return a random string using + /// ASCII characters only (character code 0 to 127). + /// + /// If [whitelist] or [blacklist] are provided, they will get priority over + /// other parameters. Otherwise, these two list will be generated from the + /// other parameter. + /// + /// Other Parameters: + /// - [lower] : lowercase letters. + /// - [upper] : uppercase letters. + /// - [controls] : control characters. + /// - [punctuations] : punctuations. + /// + /// If these parameters are set, it will be ignored. Otherwise, if `true`, the + /// corresponding characters will be added to the [whitelist], or if `false`, + /// to the [blacklist]. + /// + /// If the [whitelist] is already set, these parameters has no effect when + /// they are set to true. If the [blacklist] is already set, these parameters + /// has no effect when they are set to false. + String nextString( + int length, { + bool? lower, + bool? upper, + bool? numeric, + bool? controls, + bool? punctuations, + List? whitelist, + List? blacklist, + }) { + Set white = {}; + Set black = {}; + if (lower != null) { + if (lower) { + white.addAll(_alphaLower.codeUnits); + } else { + black.addAll(_alphaLower.codeUnits); + } + } + if (upper != null) { + if (upper) { + white.addAll(_alphaUpper.codeUnits); + } else { + black.addAll(_alphaUpper.codeUnits); + } + } + if (numeric != null) { + if (numeric) { + white.addAll(_numeric.codeUnits); + } else { + black.addAll(_numeric.codeUnits); + } + } + if (controls != null) { + if (controls) { + white.addAll(_controls); + } else { + black.addAll(_controls); + } + } + if (punctuations != null) { + if (punctuations) { + white.addAll(_punctuations); + } else { + black.addAll(_punctuations); + } + } + + if (whitelist != null) { + white.addAll(whitelist); + black.removeAll(whitelist); + } else if (white.isEmpty) { + white.addAll(List.generate(128, (i) => i)); + } + white.removeAll(black); + if (blacklist != null) { + white.removeAll(blacklist); + } + if (white.isEmpty) { + throw StateError('Empty whitelist'); + } + + var list = white.toList(growable: false); + Iterable codes = nextBytes(length); + codes = codes.map((x) => list[x % list.length]); + return String.fromCharCodes(codes); + } +} diff --git a/hashlib/lib/src/random/uuid_v1.dart b/hashlib/lib/src/random/uuid_v1.dart new file mode 100644 index 0000000..41d442e --- /dev/null +++ b/hashlib/lib/src/random/uuid_v1.dart @@ -0,0 +1,98 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; + +import 'generators.dart' show secureRandom; + +const int _mask32 = 0xFFFFFFFF; +const int _pow32 = _mask32 + 1; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| time_low | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| time_mid | ver | time_high | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| clock_seq | node | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| node | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 1 +class UUIDv1 { + const UUIDv1(); + + static const int _g0 = 0x13814000; + static const int _g1 = 0x01b21dd2; + + /// UUIDv1 is a time-based UUID featuring a 60-bit timestamp represented by + /// Coordinated Universal Time (UTC) as a count of 100-nanosecond intervals + /// since 00:00:00.00, 15 October 1582. + String generate({ + DateTime? now, + int? clockSeq, + int? node, + }) { + final rng = secureRandom(); + final codec = Base16Codec.lower.encoder; + + now ??= DateTime.now().toUtc(); + clockSeq ??= rng.nextInt(0xFFFF); + + int tl, th, t0, t1, t2; + t0 = now.millisecondsSinceEpoch & _mask32; + t1 = now.millisecondsSinceEpoch ~/ _pow32; + t2 = now.microsecondsSinceEpoch % 1000; + + tl = (10000 * t0 + 10 * t2 + _g0); + th = (10000 * t1 + _g1); + th += tl ~/ _pow32; + tl &= _mask32; + + int nl, nh; + if (node != null) { + nl = node & _mask32; + nh = node ~/ _pow32; + } else { + nl = rng.nextInt(_mask32); + nh = rng.nextInt(0xFFFF); + } + + final part1 = codec.convert([ + tl >>> 24, + tl >>> 16, + tl >>> 8, + tl, + ]); + final part2 = codec.convert([ + th >>> 8, + th, + ]); + final part3 = codec.convert([ + 0x10 ^ ((th >>> 24) & 0xF), + th >>> 16, + ]); + final part4 = codec.convert([ + 0x80 ^ ((clockSeq >>> 8) & 0x3F), + clockSeq, + ]); + final part5 = codec.convert([ + nh >>> 8, + nh, + nl >>> 24, + nl >>> 16, + nl >>> 8, + nl, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/random/uuid_v3.dart b/hashlib/lib/src/random/uuid_v3.dart new file mode 100644 index 0000000..a7df8dd --- /dev/null +++ b/hashlib/lib/src/random/uuid_v3.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/algorithms/md5.dart'; +import 'package:hashlib/src/random.dart'; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| md5_high | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| md5_high | ver | md5_mid | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| md5_low | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| md5_low | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 3 +class UUIDv3 { + const UUIDv3(); + + /// UUIDv3 values are created by computing an MD5 hash over a given + /// [namespace] concatenated with the desired [name] value. + String generate({ + String? namespace, + String? name, + }) { + final codec = Base16Codec.lower.encoder; + + final sink = MD5Hash(); + if (namespace != null) { + sink.add(fromHex(namespace.split('-').join())); + } else { + sink.add(randomBytes(16)); + } + if (name != null) { + sink.add(utf8.encode(name)); + } + final hash = Uint32List.view(sink.digest().buffer); + int h0 = hash[0]; + int h1 = hash[1]; + int h2 = hash[2]; + int h3 = hash[3]; + + final part1 = codec.convert([ + h0, + h0 >>> 8, + h0 >>> 16, + h0 >>> 24, + ]); + final part2 = codec.convert([ + h1, + h1 >>> 8, + ]); + final part3 = codec.convert([ + 0x30 ^ ((h1 >>> 16) & 0xF), + h1 >>> 24, + ]); + final part4 = codec.convert([ + 0x80 ^ (h2 & 0x3F), + h2 >>> 8, + ]); + final part5 = codec.convert([ + h2 >>> 16, + h2 >>> 24, + h3, + h3 >>> 8, + h3 >>> 16, + h3 >>> 24, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/random/uuid_v4.dart b/hashlib/lib/src/random/uuid_v4.dart new file mode 100644 index 0000000..8391b3d --- /dev/null +++ b/hashlib/lib/src/random/uuid_v4.dart @@ -0,0 +1,73 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; + +import 'generators.dart' show secureRandom; + +const int _mask32 = 0xFFFFFFFF; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| random_a | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| random_a | ver | random_b | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| random_c | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| random_c | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 4 +class UUIDv4 { + const UUIDv4(); + + /// UUIDv4 is meant for generating UUIDs from random numbers. + String generate() { + int rah, ral, rb, rch, rcl; + final rng = secureRandom(); + final codec = Base16Codec.lower.encoder; + + rah = rng.nextInt(0xFFFF); + ral = rng.nextInt(_mask32); + rb = rng.nextInt(0xFFFF); + rch = rng.nextInt(_mask32); + rcl = rng.nextInt(_mask32); + + final part1 = codec.convert([ + rah >>> 8, + rah, + ral >>> 24, + ral >>> 16, + ]); + final part2 = codec.convert([ + ral >>> 8, + ral, + ]); + final part3 = codec.convert([ + 0x40 ^ ((rb >>> 8) & 0xF), + rb, + ]); + final part4 = codec.convert([ + 0x80 ^ ((rch >>> 24) & 0x3F), + rch >>> 16, + ]); + final part5 = codec.convert([ + rch >>> 8, + rch, + rcl >>> 24, + rcl >>> 16, + rcl >>> 8, + rcl, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/random/uuid_v5.dart b/hashlib/lib/src/random/uuid_v5.dart new file mode 100644 index 0000000..3483653 --- /dev/null +++ b/hashlib/lib/src/random/uuid_v5.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/algorithms/sha1.dart'; +import 'package:hashlib/src/random.dart'; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| sha1_high | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| sha1_high | ver | sha1_mid | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| sha1_low | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| sha1_low | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 5 +class UUIDv5 { + const UUIDv5(); + + /// UUIDv5 values are created by computing an SHA1 hash over a given + /// [namespace] concatenated with the desired [name] value. + String generate({ + String? namespace, + String? name, + }) { + final codec = Base16Codec.lower.encoder; + + final sink = SHA1Hash(); + if (namespace != null) { + sink.add(fromHex(namespace.split('-').join())); + } else { + sink.add(randomBytes(16)); + } + if (name != null) { + sink.add(utf8.encode(name)); + } + final hash = Uint32List.view(sink.digest().buffer); + int h0 = hash[0]; + int h1 = hash[1]; + int h2 = hash[2]; + int h3 = hash[3]; + + final part1 = codec.convert([ + h0, + h0 >>> 8, + h0 >>> 16, + h0 >>> 24, + ]); + final part2 = codec.convert([ + h1, + h1 >>> 8, + ]); + final part3 = codec.convert([ + 0x50 ^ ((h1 >>> 16) & 0xF), + h1 >>> 24, + ]); + final part4 = codec.convert([ + 0x80 ^ (h2 & 0x3F), + h2 >>> 8, + ]); + final part5 = codec.convert([ + h2 >>> 16, + h2 >>> 24, + h3, + h3 >>> 8, + h3 >>> 16, + h3 >>> 24, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/random/uuid_v6.dart b/hashlib/lib/src/random/uuid_v6.dart new file mode 100644 index 0000000..bca2c8d --- /dev/null +++ b/hashlib/lib/src/random/uuid_v6.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; + +import 'generators.dart' show secureRandom; + +const int _mask32 = 0xFFFFFFFF; +const int _pow32 = _mask32 + 1; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| time_high | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| time_mid | ver | time_low | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| clock_seq | node | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| node | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 6 +class UUIDv6 { + const UUIDv6(); + + static const int _g0 = 0x13814000; + static const int _g1 = 0x01b21dd2; + + /// UUIDv6 is a field-compatible version of UUIDv1 reordered for improved DB + /// locality. + String generate({ + DateTime? now, + int? clockSeq, + int? node, + }) { + final rng = secureRandom(); + final codec = Base16Codec.lower.encoder; + + now ??= DateTime.now().toUtc(); + clockSeq ??= rng.nextInt(0xFFFF); + + int tl, th, t0, t1, t2; + t0 = now.millisecondsSinceEpoch & _mask32; + t1 = now.millisecondsSinceEpoch ~/ _pow32; + t2 = now.microsecondsSinceEpoch % 1000; + + tl = (10000 * t0 + 10 * t2 + _g0); + th = (10000 * t1 + _g1); + th += tl ~/ _pow32; + tl &= _mask32; + + int nl, nh; + if (node != null) { + nl = node & _mask32; + nh = node ~/ _pow32; + } else { + nl = rng.nextInt(_mask32); + nh = rng.nextInt(0xFFFF); + } + + final part1 = codec.convert([ + th >>> 20, + th >>> 12, + th >>> 4, + ((th & 0xF) << 4) ^ (tl >>> 28), + ]); + final part2 = codec.convert([ + tl >>> 20, + tl >>> 12, + ]); + final part3 = codec.convert([ + 0x60 ^ ((tl >>> 8) & 0xF), + tl, + ]); + final part4 = codec.convert([ + 0x80 ^ ((clockSeq >>> 8) & 0x3F), + clockSeq, + ]); + final part5 = codec.convert([ + nh >>> 8, + nh, + nl >>> 24, + nl >>> 16, + nl >>> 8, + nl, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/random/uuid_v7.dart b/hashlib/lib/src/random/uuid_v7.dart new file mode 100644 index 0000000..988d5be --- /dev/null +++ b/hashlib/lib/src/random/uuid_v7.dart @@ -0,0 +1,79 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; + +import 'generators.dart' show secureRandom; + +const int _mask32 = 0xFFFFFFFF; +const int _pow32 = _mask32 + 1; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| unix_ts_ms | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| unix_ts_ms | ver | rand_a | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| rand_b | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| rand_b | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 7 +class UUIDv7 { + const UUIDv7(); + + /// UUIDv7 features a time-ordered value field derived from the widely + /// implemented and well-known Unix Epoch timestamp source, the number of + /// milliseconds since midnight 1 Jan 1970 UTC, leap seconds excluded. + String generate({ + DateTime? now, + }) { + int ra, rbh, rbl, tl, th; + final rng = secureRandom(); + final codec = Base16Codec.lower.encoder; + + now ??= DateTime.now().toUtc(); + ra = rng.nextInt(0xFFFF); + rbh = rng.nextInt(_mask32); + rbl = rng.nextInt(_mask32); + tl = now.millisecondsSinceEpoch & _mask32; + th = now.millisecondsSinceEpoch ~/ _pow32; + + final part1 = codec.convert([ + th >>> 8, + th, + tl >>> 24, + tl >>> 16, + ]); + final part2 = codec.convert([ + tl >>> 8, + tl, + ]); + final part3 = codec.convert([ + 0x70 ^ ((ra >>> 8) & 0xF), + ra, + ]); + final part4 = codec.convert([ + 0x80 ^ ((rbh >>> 24) & 0x3F), + rbh >>> 16, + ]); + final part5 = codec.convert([ + rbh >>> 8, + rbh, + rbl >>> 24, + rbl >>> 16, + rbl >>> 8, + rbl, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/random/uuid_v8.dart b/hashlib/lib/src/random/uuid_v8.dart new file mode 100644 index 0000000..74da6d2 --- /dev/null +++ b/hashlib/lib/src/random/uuid_v8.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; + +import 'generators.dart' show secureRandom; + +const int _mask32 = 0xFFFFFFFF; + +/* ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| nonce | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| nonce | ver | nonce | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|var| nonce | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| nonce | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/// Implementation of Universally Unique Identifier version 8 +class UUIDv8 { + const UUIDv8(); + + /// UUIDv8 provides a format for experimental or vendor-specific use cases. + /// This implementation uses random number by default. + String generate({Uint8List? nonce}) { + int a, b, c, d; + final rng = secureRandom(); + final codec = Base16Codec.lower.encoder; + + if (nonce != null) { + if (nonce.length != 16) { + throw ArgumentError('Nonce length must be 16-byte'); + } + var nonce32 = Uint32List.view(nonce.buffer); + a = nonce32[0]; + b = nonce32[1]; + c = nonce32[2]; + d = nonce32[3]; + } else { + a = rng.nextInt(_mask32); + b = rng.nextInt(_mask32); + c = rng.nextInt(_mask32); + d = rng.nextInt(_mask32); + } + + final part1 = codec.convert([ + a, + a >>> 8, + a >>> 16, + a >>> 24, + ]); + final part2 = codec.convert([ + b, + b >>> 8, + ]); + final part3 = codec.convert([ + 0x80 ^ ((b >>> 16) & 0xF), + b >>> 24, + ]); + final part4 = codec.convert([ + 0x80 ^ (c & 0x3F), + c >>> 8, + ]); + final part5 = codec.convert([ + c >>> 16, + c >>> 24, + d, + d >>> 8, + d >>> 16, + d >>> 24, + ]); + + return [ + String.fromCharCodes(part1), + String.fromCharCodes(part2), + String.fromCharCodes(part3), + String.fromCharCodes(part4), + String.fromCharCodes(part5), + ].join('-'); + } +} diff --git a/hashlib/lib/src/ripemd128.dart b/hashlib/lib/src/ripemd128.dart new file mode 100644 index 0000000..8eeedaf --- /dev/null +++ b/hashlib/lib/src/ripemd128.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/ripemd/ripemd128.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// RIPEMD-128 (RACE Integrity Primitives Evaluation Message Digest) is a +/// cryptographic hash function that produces a fixed-size, 128-bit hash value. +/// +/// While it provides reasonable level of security, it is less commonly used +/// than RIPEMD-160, the more secure algorithm in the same family. +const BlockHashBase ripemd128 = _RIPEMD128(); + +class _RIPEMD128 extends BlockHashBase { + const _RIPEMD128(); + + @override + final String name = 'RIPEMD-128'; + + @override + RIPEMD128Hash createSink() => RIPEMD128Hash(); +} + +/// Generates a RIPEMD-128 hash in hexadecimal +/// +/// Parameters: +/// - [input] is the message string +/// - [encoding] specifies the character encoding. Default is [utf8]. +/// - [uppercase] flag indicates whether the output should be in uppercase. +String ripemd128sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return ripemd128.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/ripemd160.dart b/hashlib/lib/src/ripemd160.dart new file mode 100644 index 0000000..da2c777 --- /dev/null +++ b/hashlib/lib/src/ripemd160.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/ripemd/ripemd160.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// RIPEMD-160 (RACE Integrity Primitives Evaluation Message Digest) is a +/// cryptographic hash function that produces a fixed-size, 160-bit hash value. +/// It is used to verify the integrity and authenticity of messages and is +/// resistant to various types of attacks, including collisions and preimage +/// attacks. It is commonly used in security protocols and applications. +const BlockHashBase ripemd160 = _RIPEMD160(); + +class _RIPEMD160 extends BlockHashBase { + const _RIPEMD160(); + + @override + final String name = 'RIPEMD-160'; + + @override + RIPEMD160Hash createSink() => RIPEMD160Hash(); +} + +/// Generates a RIPEMD-160 hash in hexadecimal +/// +/// Parameters: +/// - [input] is the message string +/// - [encoding] specifies the character encoding. Default is [utf8]. +/// - [uppercase] flag indicates whether the output should be in uppercase. +String ripemd160sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return ripemd160.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/ripemd256.dart b/hashlib/lib/src/ripemd256.dart new file mode 100644 index 0000000..6bcfa92 --- /dev/null +++ b/hashlib/lib/src/ripemd256.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/ripemd/ripemd256.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// RIPEMD-256 (RACE Integrity Primitives Evaluation Message Digest) is a +/// cryptographic hash function that produces a fixed-size, 256-bit hash value. +/// +/// It shares some design principles with RIPEMD-128, but provides a higher +/// level of security. It is also less commonly used than RIPEMD-160. +const BlockHashBase ripemd256 = _RIPEMD256(); + +class _RIPEMD256 extends BlockHashBase { + const _RIPEMD256(); + + @override + final String name = 'RIPEMD-256'; + + @override + RIPEMD256Hash createSink() => RIPEMD256Hash(); +} + +/// Generates a RIPEMD-256 hash in hexadecimal +/// +/// Parameters: +/// - [input] is the message string +/// - [encoding] specifies the character encoding. Default is [utf8]. +/// - [uppercase] flag indicates whether the output should be in uppercase. +String ripemd256sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return ripemd256.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/ripemd320.dart b/hashlib/lib/src/ripemd320.dart new file mode 100644 index 0000000..3043545 --- /dev/null +++ b/hashlib/lib/src/ripemd320.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/ripemd/ripemd320.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// RIPEMD-320 (RACE Integrity Primitives Evaluation Message Digest) is a +/// cryptographic hash function that produces a fixed-size, 320-bit hash value. +/// +/// It shares some design principles with RIPEMD-160, but provides a higher +/// level of security having a larger output size and a more complex message +/// expansion function. +const BlockHashBase ripemd320 = _RIPEMD320(); + +class _RIPEMD320 extends BlockHashBase { + const _RIPEMD320(); + + @override + final String name = 'RIPEMD-320'; + + @override + RIPEMD320Hash createSink() => RIPEMD320Hash(); +} + +/// Generates a RIPEMD-320 hash in hexadecimal +/// +/// Parameters: +/// - [input] is the message string +/// - [encoding] specifies the character encoding. Default is [utf8]. +/// - [uppercase] flag indicates whether the output should be in uppercase. +String ripemd320sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return ripemd320.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/scrypt.dart b/hashlib/lib/src/scrypt.dart new file mode 100644 index 0000000..84a57e9 --- /dev/null +++ b/hashlib/lib/src/scrypt.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/scrypt/scrypt.dart'; +import 'package:hashlib/src/algorithms/scrypt/security.dart'; +import 'package:hashlib/src/core/hash_digest.dart'; + +export 'algorithms/scrypt/scrypt.dart' show Scrypt; +export 'algorithms/scrypt/security.dart' show ScryptSecurity; + +/// Generate a secure password using the [scrypt][rfc] algorithm. +/// +/// The scrypt algorithm is a modern password-based key derivation function +/// that is designed to be highly secure against brute-force attacks. It uses +/// a large amount of memory and is highly customizable, allowing the user to +/// tune the parameters according to their specific needs. +/// +/// Parameters: +/// - [password] : The passphrase string to hash. +/// - [salt] : An uniquely and randomly generated string. +/// - [r] : The size of a single block in bytes. +/// - [N] : The CPU/Memory cost parameter as a power of 2. 1 < [N] < 2^32 +/// - [p] : The parallelization paramete. [p] <= (2^32 - 1) / (128 * [r]) +/// - [dklen] : The intended output length in bytes. [dklen] <= 2^32 - 1 +/// - [security] : The default parameter source for [N], [r], [p] if they are +/// not provided (default is [ScryptSecurity.good]). +/// +/// The parameters N, r, and p should be tuned according to the amount of +/// memory and computing power available, as well as the desired level of +/// parallelism. At the current time, the values of r=8 and p=1 appear to +/// yield good results, but as technology advances, it is likely that the +/// optimum values for both r and p will increase. +/// +/// [rfc]: https://www.rfc-editor.org/rfc/rfc7914.html +@pragma('vm:prefer-inline') +HashDigest scrypt( + List password, + List salt, { + int? N, + int? r, + int? p, + int dklen = 64, + ScryptSecurity security = ScryptSecurity.good, +}) => + Scrypt( + salt: salt, + cost: N ?? security.N, + blockSize: r ?? security.r, + parallelism: p ?? security.p, + derivedKeyLength: dklen, + ).convert(password); diff --git a/hashlib/lib/src/sha1.dart b/hashlib/lib/src/sha1.dart new file mode 100644 index 0000000..c5b53ca --- /dev/null +++ b/hashlib/lib/src/sha1.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha1.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA-1 produces a message digest based on principle similar to MD5, except +/// it can generate a 160-bit hash. Since 2005, SHA-1 has not been considered +/// secure and NIST formally deprecated it in 2001. It is no longer allowed +/// in digital signatures, however it is safe to use it as a checksum to verify +/// data integrity. +/// +/// **WARNING: It should not be used for cryptographic purposes.** +const BlockHashBase sha1 = _SHA1(); + +class _SHA1 extends BlockHashBase { + const _SHA1(); + + @override + final String name = 'SHA1'; + + @override + SHA1Hash createSink() => SHA1Hash(); +} + +/// Generates a SHA-1 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha1sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha1.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha224.dart b/hashlib/lib/src/sha224.dart new file mode 100644 index 0000000..f381dec --- /dev/null +++ b/hashlib/lib/src/sha224.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha2/sha2.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA-224 is a member of SHA-2 family which uses 256-bit internal state to +/// generate a message digest of 224-bit long. +/// +/// SHA-2 is a family of algorithms designed by the United States National +/// Security Agency (NSA), first published in 2001 and later standardized in +/// [FIPS 180-4][fips180]. +/// +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +const BlockHashBase sha224 = _SHA224(); + +class _SHA224 extends BlockHashBase { + const _SHA224(); + + @override + final String name = 'SHA-224'; + + @override + SHA224Hash createSink() => SHA224Hash(); +} + +/// Generates a SHA-224 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha224sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha224.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha256.dart b/hashlib/lib/src/sha256.dart new file mode 100644 index 0000000..ebbc0c3 --- /dev/null +++ b/hashlib/lib/src/sha256.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha2/sha2.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA-256 is a member of SHA-2 family which uses 256-bit internal state to +/// generate a message digest of 256-bit long. +/// +/// SHA-2 is a family of algorithms designed by the United States National +/// Security Agency (NSA), first published in 2001 and later standardized in +/// [FIPS 180-4][fips180]. +/// +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +const BlockHashBase sha256 = _SHA256(); + +class _SHA256 extends BlockHashBase { + const _SHA256(); + + @override + final String name = 'SHA-256'; + + @override + SHA256Hash createSink() => SHA256Hash(); +} + +/// Generates a SHA-256 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha256sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha256.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha384.dart b/hashlib/lib/src/sha384.dart new file mode 100644 index 0000000..33b246d --- /dev/null +++ b/hashlib/lib/src/sha384.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha2/sha2.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA-384 is a member of SHA-2 family which uses 512-bit internal state to +/// generate a message digest of 384-bit long. +/// +/// SHA-2 is a family of algorithms designed by the United States National +/// Security Agency (NSA), first published in 2001 and later standardized in +/// [FIPS 180-4][fips180]. +/// +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +const BlockHashBase sha384 = _SHA384(); + +class _SHA384 extends BlockHashBase { + const _SHA384(); + + @override + final String name = 'SHA-384'; + + @override + SHA384Hash createSink() => SHA384Hash(); +} + +/// Generates a SHA-384 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha384sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha384.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha3_224.dart b/hashlib/lib/src/sha3_224.dart new file mode 100644 index 0000000..54bd6f0 --- /dev/null +++ b/hashlib/lib/src/sha3_224.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha3.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA3-224 is a member of SHA-3 family which uses 224-bit blocks to +/// generate a message digest of 224-bit long. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a 224-bit output using +/// the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase sha3_224 = _SHA3d224(); + +class _SHA3d224 extends BlockHashBase { + const _SHA3d224(); + + @override + final String name = 'SHA3-224'; + + @override + SHA3d224Hash createSink() => SHA3d224Hash(); +} + +/// Generates a SHA3-224 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha3_224sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha3_224.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha3_256.dart b/hashlib/lib/src/sha3_256.dart new file mode 100644 index 0000000..e2871c8 --- /dev/null +++ b/hashlib/lib/src/sha3_256.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha3.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA3-256 is a member of SHA-3 family which uses 256-bit blocks to +/// generate a message digest of 256-bit long. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a 256-bit output using +/// the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase sha3_256 = _SHA3d256(); + +class _SHA3d256 extends BlockHashBase { + const _SHA3d256(); + + @override + final String name = 'SHA3-256'; + + @override + SHA3d256Hash createSink() => SHA3d256Hash(); +} + +/// Generates a SHA3-256 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha3_256sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha3_256.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha3_384.dart b/hashlib/lib/src/sha3_384.dart new file mode 100644 index 0000000..538a0ad --- /dev/null +++ b/hashlib/lib/src/sha3_384.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha3.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA3-384 is a member of SHA-3 family which uses 384-bit blocks to +/// generate a message digest of 384-bit long. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a 384-bit output using +/// the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase sha3_384 = _SHA3d384(); + +class _SHA3d384 extends BlockHashBase { + const _SHA3d384(); + + @override + final String name = 'SHA3-384'; + + @override + SHA3d384Hash createSink() => SHA3d384Hash(); +} + +/// Generates a SHA3-384 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha3_384sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha3_384.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha3_512.dart b/hashlib/lib/src/sha3_512.dart new file mode 100644 index 0000000..2cce916 --- /dev/null +++ b/hashlib/lib/src/sha3_512.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha3.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA3-512 is a member of SHA-3 family which uses 512-bit blocks to +/// generate a message digest of 512-bit long. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a 512-bit output using +/// the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const BlockHashBase sha3_512 = _SHA3d512(); + +class _SHA3d512 extends BlockHashBase { + const _SHA3d512(); + + @override + final String name = 'SHA3-512'; + + @override + SHA3d512Hash createSink() => SHA3d512Hash(); +} + +/// Generates a SHA3-512 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha3_512sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha3_512.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha512.dart b/hashlib/lib/src/sha512.dart new file mode 100644 index 0000000..9f49248 --- /dev/null +++ b/hashlib/lib/src/sha512.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha2/sha2.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA-512 is a member of SHA-2 family which uses 512-bit internal state to +/// generate a message digest of 512-bit long. +/// +/// SHA-2 is a family of algorithms designed by the United States National +/// Security Agency (NSA), first published in 2001 and later standardized in +/// [FIPS 180-4][fips180]. +/// +/// [fips180]: https://csrc.nist.gov/publications/detail/fips/180/4/final +const BlockHashBase sha512 = _SHA512(); + +class _SHA512 extends BlockHashBase { + const _SHA512(); + + @override + final String name = 'SHA-512'; + + @override + SHA512Hash createSink() => SHA512Hash(); +} + +/// Generates a SHA-512 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha512sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha512.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/sha512t.dart b/hashlib/lib/src/sha512t.dart new file mode 100644 index 0000000..c7d2e8f --- /dev/null +++ b/hashlib/lib/src/sha512t.dart @@ -0,0 +1,63 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sha2/sha2.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHA-512/256 is a variation of SHA-512 which uses 512-bit internal state to +/// generate a message digest of 256-bit long truncating the last bits. +const BlockHashBase sha512t256 = _SHA512t256(); + +class _SHA512t256 extends BlockHashBase { + const _SHA512t256(); + + @override + final String name = 'SHA-512/256'; + + @override + SHA512t256Hash createSink() => SHA512t256Hash(); +} + +/// SHA-512/224 is a variation of SHA-512 which uses 512-bit internal state to +/// generate a message digest of 224-bit long truncating the last bits. +const BlockHashBase sha512t224 = _SHA512t224(); + +class _SHA512t224 extends BlockHashBase { + const _SHA512t224(); + + @override + final String name = 'SHA-512/224'; + + @override + SHA512t224Hash createSink() => SHA512t224Hash(); +} + +/// Generates a SHA-512/256 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines whether the hexadecimal output should be in uppercase +String sha512t256sum( + final String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha512t256.string(input, encoding).hex(uppercase); +} + +/// Generates a SHA-512/224 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sha512t224sum( + final String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sha512t224.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/shake128.dart b/hashlib/lib/src/shake128.dart new file mode 100644 index 0000000..6a66b33 --- /dev/null +++ b/hashlib/lib/src/shake128.dart @@ -0,0 +1,119 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/shake.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHAKE-128 is a member of SHA-3 family which uses 128-bit blocks to +/// generate a message digest of arbitrary length. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a arbitrary length output +/// using the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const shake128 = _Shake128Builder(); + +/// [Shake128] instance to generate a 128-bit message digest. +const shake128_128 = Shake128(128 >>> 3); + +/// [Shake128] instance to generate a 160-bit message digest. +const shake128_160 = Shake128(160 >>> 3); + +/// [Shake128] instance to generate a 224-bit message digest. +const shake128_224 = Shake128(224 >>> 3); + +/// [Shake128] instance to generate a 256-bit message digest. +const shake128_256 = Shake128(256 >>> 3); + +/// [Shake128] instance to generate a 384-bit message digest. +const shake128_384 = Shake128(384 >>> 3); + +/// [Shake128] instance to generate a 512-bit message digest. +const shake128_512 = Shake128(512 >>> 3); + +class _Shake128Builder { + const _Shake128Builder(); + + /// Returns a [Shake128] instance. + /// + /// Parameters: + /// - [outputSizeInBytes] is the length of the output digest in bytes. + Shake128 of(int outputSizeInBytes) => Shake128(outputSizeInBytes); +} + +/// SHAKE-128 is a member of SHA-3 family which uses 128-bit blocks to +/// generate a message digest of arbitrary length. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a arbitrary length output +/// using the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +class Shake128 extends BlockHashBase { + final int outputSizeInBytes; + + /// Creates an instance to generate arbitrary size hash using SHAKE-128 + /// + /// Parameters: + /// - [outputSizeInBytes] is the length of the output digest in bytes. + const Shake128(this.outputSizeInBytes); + + @override + String get name => 'SHAKE-128/${outputSizeInBytes << 3}'; + + @override + Shake128Hash createSink() => Shake128Hash(outputSizeInBytes); +} + +/// Generates a SHAKE-128 checksum in hexadecimal of arbitrary length +/// +/// Parameters: +/// - [input] is the string to hash +/// - [outputSize] is the length of the output digest in bytes. The +/// hexadecimal string output is twice as that. You can expect a string of +/// length `2 * outputSizeInBytes` from this function. +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String shake128sum( + String input, + int outputSize, [ + Encoding? encoding, + bool uppercase = false, +]) { + return Shake128(outputSize).string(input, encoding).hex(uppercase); +} + +/// Creates a SHAKE-128 based **infinite** hash generator. +/// +/// If [seed] is provided it will be used as an input to the algorithm. +/// With a proper seed, this can work as a random number generator. +/// +/// Example: +/// ``` +/// final hash = shake128generator().take(500).toList(); +/// ``` +/// +/// **Warning: This is an infinite `Iterable`. Do not call `toList` directly!** +Iterable shake128generator([List? seed]) sync* { + int i; + final sink = Shake128Hash(0); + if (seed != null && seed.isNotEmpty) { + sink.$process(seed, 0, seed.length); + } + sink.$finalize(); + while (true) { + for (i = 0; i < sink.blockLength; ++i) { + yield sink.buffer[i]; + } + sink.$update(); + } +} diff --git a/hashlib/lib/src/shake256.dart b/hashlib/lib/src/shake256.dart new file mode 100644 index 0000000..d906c58 --- /dev/null +++ b/hashlib/lib/src/shake256.dart @@ -0,0 +1,119 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/shake.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SHAKE-256 is a member of SHA-3 family which uses 256-bit blocks to +/// generate a message digest of arbitrary length. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a arbitrary length output +/// using the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +const shake256 = _Shake256Builder(); + +/// [Shake256] instance to generate a 128-bit message digest. +const shake256_128 = Shake256(128 >>> 3); + +/// [Shake256] instance to generate a 160-bit message digest. +const shake256_160 = Shake256(160 >>> 3); + +/// [Shake256] instance to generate a 224-bit message digest. +const shake256_224 = Shake256(224 >>> 3); + +/// [Shake256] instance to generate a 256-bit message digest. +const shake256_256 = Shake256(256 >>> 3); + +/// [Shake256] instance to generate a 384-bit message digest. +const shake256_384 = Shake256(384 >>> 3); + +/// [Shake256] instance to generate a 512-bit message digest. +const shake256_512 = Shake256(512 >>> 3); + +class _Shake256Builder { + const _Shake256Builder(); + + /// Returns a [Shake256] instance. + /// + /// Parameters: + /// - [outputSizeInBytes] is the length of the output digest in bytes. + Shake256 of(int outputSizeInBytes) => Shake256(outputSizeInBytes); +} + +/// SHAKE-256 is a member of SHA-3 family which uses 256-bit blocks to +/// generate a message digest of arbitrary length. +/// +/// SHA-3 is a subset of Keccak cryptographic family, standardized by NIST +/// on 2015 to substitute SHA-2 if necessary. Since the algorithm uses the +/// [sponge construction][sponge], it can generate any arbitrary length of +/// message digest. This implementation generates a arbitrary length output +/// using the [standard SHA-3 algorithm][fips202]. +/// +/// [sponge]: https://en.wikipedia.org/wiki/Sponge_function +/// [fips202]: https://csrc.nist.gov/publications/detail/fips/202/final +class Shake256 extends BlockHashBase { + final int outputSizeInBytes; + + /// Creates an instance to generate arbitrary size hash using SHAKE-256 + /// + /// Parameters: + /// - [outputSizeInBytes] is the length of the output digest in bytes. + const Shake256(this.outputSizeInBytes); + + @override + String get name => 'SHAKE-256/${outputSizeInBytes << 3}'; + + @override + Shake256Hash createSink() => Shake256Hash(outputSizeInBytes); +} + +/// Generates a SHAKE-256 checksum in hexadecimal of arbitrary length +/// +/// Parameters: +/// - [input] is the string to hash +/// - [outputSize] is the length of the output digest in bytes. The +/// hexadecimal string output is twice as that. You can expect a string of +/// length `2 * outputSizeInBytes` from this function. +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String shake256sum( + String input, + int outputSize, [ + Encoding? encoding, + bool uppercase = false, +]) { + return Shake256(outputSize).string(input, encoding).hex(uppercase); +} + +/// Creates a SHAKE-256 based **infinite** hash generator. +/// +/// If [seed] is provided it will be used as an input to the algorithm. +/// With a proper seed, this can work as a random number generator. +/// +/// Example: +/// ``` +/// final hash = shake256generator().take(500).toList(); +/// ``` +/// +/// **Warning: This is an infinite `Iterable`. Do not call `toList` directly!** +Iterable shake256generator([List? seed]) sync* { + int i; + final sink = Shake256Hash(0); + if (seed != null && seed.isNotEmpty) { + sink.$process(seed, 0, seed.length); + } + sink.$finalize(); + while (true) { + for (i = 0; i < sink.blockLength; ++i) { + yield sink.buffer[i]; + } + sink.$update(); + } +} diff --git a/hashlib/lib/src/sm3.dart b/hashlib/lib/src/sm3.dart new file mode 100644 index 0000000..e26c35e --- /dev/null +++ b/hashlib/lib/src/sm3.dart @@ -0,0 +1,43 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/sm3.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// SM3 [ISO.IEC.10118-3] [GBT.32905-2016] is a cryptographic hash algorithm +/// published by the [State Cryptography Administration (SCA) of China][SCA] +/// as an authorized cryptographic hash algorithm for the use within China. +/// +/// It can be used on digital signatures, generating message authentication +/// codes, and random numbers. +/// +/// [SCA]: http://www.sca.gov.cn +/// [ISO.IEC.10118-3]: https://www.iso.org/standard/67116.html +/// [GBT.32905-2016]: https://www.chinesestandard.net/PDF.aspx/GBT32905-2016 +const BlockHashBase sm3 = _SM3(); + +class _SM3 extends BlockHashBase { + const _SM3(); + + @override + final String name = 'SM3'; + + @override + SM3Hash createSink() => SM3Hash(); +} + +/// Generates a SM3 checksum in hexadecimal +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +/// - [uppercase] defines if the hexadecimal output should be in uppercase +String sm3sum( + String input, [ + Encoding? encoding, + bool uppercase = false, +]) { + return sm3.string(input, encoding).hex(uppercase); +} diff --git a/hashlib/lib/src/totp.dart b/hashlib/lib/src/totp.dart new file mode 100644 index 0000000..3d217e1 --- /dev/null +++ b/hashlib/lib/src/totp.dart @@ -0,0 +1,82 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:hashlib/src/hotp.dart'; +import 'package:hashlib/src/sha1.dart'; + +/// A Time-based One-Time Password (TOTP) algorithm implementation derived +/// from [rfc6238]. +/// +/// [rfc6238]: https://www.ietf.org/rfc/rfc6238.html +class TOTP extends HOTP { + final Duration period; + int _timeDelta = 0; + final int _periodMS; + final _controller = StreamController.broadcast(); + + /// Creates an instance of the [TOTP] class with the specified parameters. + /// + /// Parameters: + /// - [secret] is the shared secret as a list of bytes for generating the OTP. + /// - [digits] is the number of digits in the generated OTP (default is 6). + /// - [period] is duration in seconds an OTP is valid for (default is 30). + /// - [algo] is the block hash algorithm to use (default is [sha1]). + /// - [label] is an optional string to identify the account or service the OTP + /// is associated with. + /// - [issuer] is an optional string to specify the entity issuing the OTP. + TOTP( + super.secret, { + super.algo = sha1, + super.digits = 6, + super.label, + super.issuer, + this.period = const Duration(seconds: 30), + }) : _periodMS = period.inMilliseconds, + super(counter: Uint8List(8)) { + // setup stream controller + Timer? timer; + _controller.onCancel = () { + timer?.cancel(); + }; + _controller.onListen = () { + int d = _periodMS - (currentTime % _periodMS); + timer = Timer(Duration(milliseconds: d), () { + timer = Timer.periodic(period, (_) { + _controller.sink.add(value()); + }); + _controller.sink.add(value()); + }); + _controller.sink.add(value()); + }; + } + + /// A broadcast stream that reports new OTP value on every [period] interval + Stream get stream => _controller.stream; + + /// A broadcast stream that reports new OTP value as string on every [period] + /// interval + Stream get streamString => + _controller.stream.map((e) => e.toString().padLeft(digits, '0')); + + /// The current time in milliseconds since EPOCH with adjusted delta shift + int get currentTime => DateTime.now().millisecondsSinceEpoch + _timeDelta; + + @override + int value() { + int i, c; + c = currentTime ~/ _periodMS; + for (i = 7; i >= 0; --i, c >>>= 8) { + counter[i] = c & 0xFF; + } + return super.value(); + } + + /// Adjust the internal clock with the parameter [delta] - the difference in + /// milliseconds between the actual clock and the current system clock. + void adjustClock(int delta) { + _timeDelta = delta; + } +} diff --git a/hashlib/lib/src/uuid.dart b/hashlib/lib/src/uuid.dart new file mode 100644 index 0000000..a07b773 --- /dev/null +++ b/hashlib/lib/src/uuid.dart @@ -0,0 +1,140 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'random/uuid_v1.dart'; +import 'random/uuid_v3.dart'; +import 'random/uuid_v4.dart'; +import 'random/uuid_v5.dart'; +import 'random/uuid_v6.dart'; +import 'random/uuid_v7.dart'; +import 'random/uuid_v8.dart'; + +const _v1 = UUIDv1(); +const _v3 = UUIDv3(); +const _v4 = UUIDv4(); +const _v5 = UUIDv5(); +const _v6 = UUIDv6(); +const _v7 = UUIDv7(); +const _v8 = UUIDv8(); + +/// A UUID is 128 bits long and is intended to guarantee uniqueness. This class +/// contains implementations for different versions of UUIDs based on the +/// specification from [RFC-9562][rfc]. +/// +/// [rfc]: https://www.ietf.org/rfc/rfc9562.html +const uuid = _UUID(); + +enum Namespace { + dns._('6ba7b810-9dad-11d1-80b4-00c04fd430c8'), + url._('6ba7b811-9dad-11d1-80b4-00c04fd430c8'), + oid._('6ba7b812-9dad-11d1-80b4-00c04fd430c8'), + x500._('6ba7b814-9dad-11d1-80b4-00c04fd430c8'), + nil._('00000000-0000-0000-0000-000000000000'), + max._('ffffffff-ffff-ffff-ffff-ffffffffffff'); + + /// The string value of this namespace + final String value; + + const Namespace._(this.value); + + static String get time => _v6.generate(); +} + +class _UUID { + const _UUID(); + + /// Generate a time-based UUID. Use [v6] instead of [v1] wherever possible. + /// + /// Parameters: + /// - [utc] : The time in UTC (Default: current time). + /// - [node] : The node ID (48-bit integer, Default: random). + /// - [clockSeq] : The clock sequence (14-bit integer, Default: random). + @pragma('vm:prefer-inline') + String v1({ + DateTime? utc, + int? node, + int? clockSeq, + }) => + _v1.generate( + now: utc, + node: node, + clockSeq: clockSeq, + ); + + /// Generate a UUID based on MD5-hash. Due to vulnerability of MD5, it is + /// recommended to use [v5] instead. + /// + /// The [namespace] must be a valid UUID. Some predefined namespaces are + /// available in [Namespace]. i.e.: `Namespace.dns.value`. A random namespace + /// is used if not provided. + @pragma('vm:prefer-inline') + String v3({ + String? namespace, + String? name, + }) => + _v3.generate( + name: name, + namespace: namespace, + ); + + /// Generate a random-based UUID. + @pragma('vm:prefer-inline') + String v4() => _v4.generate(); + + /// Generate a UUID based on SHA1-hash. + /// + /// The [namespace] must be a valid UUID. Some predefined namespaces are + /// available in [Namespace]. i.e.: `Namespace.dns.value`. A random namespace + /// is used if not provided. + @pragma('vm:prefer-inline') + String v5({ + String? namespace, + String? name, + }) => + _v5.generate( + name: name, + namespace: namespace, + ); + + /// Generate a time-based UUID. + /// + /// Parameters: + /// - [utc] : The time in UTC (Default: current time). + /// - [node] : The node ID (48-bit integer, Default: random). + /// - [clockSeq] : The clock sequence (14-bit integer, Default: random). + @pragma('vm:prefer-inline') + String v6({ + DateTime? utc, + int? node, + int? clockSeq, + }) => + _v6.generate( + now: utc, + node: node, + clockSeq: clockSeq, + ); + + /// Generate a time-based and random-based UUID. + /// + /// Parameters: + /// - [utc] : The time in UTC (Default: current time). + @pragma('vm:prefer-inline') + String v7({ + DateTime? utc, + }) => + _v7.generate(now: utc); + + /// Generate a nonce based UUID. + /// + /// Parameters: + /// - [nonce] : A 16-byte nonce (128-bit) + @pragma('vm:prefer-inline') + String v8({ + Uint8List? nonce, + }) => + _v8.generate( + nonce: nonce, + ); +} diff --git a/hashlib/lib/src/xxh128.dart b/hashlib/lib/src/xxh128.dart new file mode 100644 index 0000000..e77812d --- /dev/null +++ b/hashlib/lib/src/xxh128.dart @@ -0,0 +1,63 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/xxh3/xxh3_128.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// An instance of [XXH128] with seed = 0 +const XXH128 xxh128 = XXH128(seed: 0); + +/// An instance of [XXH128] with seed = 0 +const XXH128 xxh3_128 = xxh128; + +/// This is an implementation of 128-bit XXH3 hash algorithm of xxHash family +/// derived from https://github.com/Cyan4973/xxHash +/// +/// XXH3 is a new high-performance variant XXHash algorithm that is designed to +/// be fast, with a low memory footprint, and to produce high-quality hash +/// values with good distribution and [low collision rates][wiki]. +/// +/// One of the main improvements in XXH3 compared to XXHash is its use of a +/// new mixing function that provides better mixing of the input data and +/// results in improved distribution of the resulting hash values. +/// +/// [wiki]: https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison +/// +/// **WARNING: It should not be used for cryptographic purposes.** +class XXH128 extends BlockHashBase { + final int seed; + final List? secret; + + /// Creates a new instance of [XXH128]. + /// + /// Parameters: + /// - [seed] is an optional 64-bit integer. Default: 0 + /// - [secret] is an array of bytes. The length should be at least 136. + /// - If the [secret] is present, the [seed] is ignored. + const XXH128({this.seed = 0, this.secret}); + + @override + final String name = 'XXH128'; + + @override + XXH3Sink128bit createSink() => secret == null + ? XXH3Sink128bit.withSeed(seed) + : XXH3Sink128bit.withSecret(secret); + + /// Get an instance of [xxh128] with an specific seed + XXH128 withSeed(int seed) => XXH128(seed: seed, secret: secret); + + /// Get an instance of [xxh128] with a secret + XXH128 withSecret(List secret) => XXH128(seed: seed, secret: secret); +} + +/// Gets the 128-bit XXH3 hash of a String in hexadecimal. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +String xxh128sum(String input, [Encoding? encoding]) { + return xxh128.string(input, encoding).hex(); +} diff --git a/hashlib/lib/src/xxh3.dart b/hashlib/lib/src/xxh3.dart new file mode 100644 index 0000000..a4e4b43 --- /dev/null +++ b/hashlib/lib/src/xxh3.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/xxh3/xxh3_64.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// An instance of [XXH3] with seed = 0 +const XXH3 xxh3 = XXH3(seed: 0); + +/// An instance of [XXH3] with seed = 0 +const XXH3 xxh3_64 = xxh3; + +/// This is an implementation of 64-bit XXH3 hash algorithm of xxHash family +/// derived from https://github.com/Cyan4973/xxHash +/// +/// XXH3 is a new high-performance variant XXHash algorithm that is designed to +/// be fast, with a low memory footprint, and to produce high-quality hash +/// values with good distribution and [low collision rates][wiki]. +/// +/// One of the main improvements in XXH3 compared to XXHash is its use of a +/// new mixing function that provides better mixing of the input data and +/// results in improved distribution of the resulting hash values. +/// +/// [wiki]: https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison +/// +/// **WARNING: It should not be used for cryptographic purposes.** +class XXH3 extends BlockHashBase { + final int seed; + final List? secret; + + /// Creates a new instance of [XXH3]. + /// + /// Parameters: + /// - [seed] is an optional 64-bit integer. Default: 0 + /// - [secret] is an array of bytes. The length should be at least 136. + /// - If the [secret] is present, the [seed] is ignored. + const XXH3({this.seed = 0, this.secret}); + + @override + final String name = 'XXH3'; + + @override + XXH3Sink64bit createSink() => secret == null + ? XXH3Sink64bit.withSeed(seed) + : XXH3Sink64bit.withSecret(secret); + + /// Get an instance of [xxh3] with an specific seed + XXH3 withSeed(int seed) => XXH3(seed: seed, secret: secret); + + /// Get an instance of [xxh3] with a secret + XXH3 withSecret(List secret) => XXH3(seed: seed, secret: secret); +} + +/// Gets the 64-bit XXH3 value of a String. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +int xxh3code(String input, [Encoding? encoding]) { + return xxh3.string(input, encoding).number(); +} + +/// Gets the 64-bit XXH3 hash of a String in hexadecimal. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +String xxh3sum(String input, [Encoding? encoding]) { + return xxh3.string(input, encoding).hex(); +} diff --git a/hashlib/lib/src/xxh32.dart b/hashlib/lib/src/xxh32.dart new file mode 100644 index 0000000..2ed95f4 --- /dev/null +++ b/hashlib/lib/src/xxh32.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/xxh32/xxh32.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// An instance of [XXHash32] with seed = 0 +const XXHash32 xxh32 = XXHash32(0); + +/// XXHash32 is a fast and efficient non-cryptographic hash function for +/// 32-bit platforms. It is designed for producing a quick and reliable hash +/// value for a given data, which can be used for many applications, such as +/// checksum, data validation, etc. In addition, it has a good distribution of +/// hash values, which helps to reduce [collisions][wiki]. +/// +/// This implementation was derived from https://github.com/Cyan4973/xxHash +/// +/// [wiki]: https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison +/// +/// **WARNING: It should not be used for cryptographic purposes.** +class XXHash32 extends BlockHashBase { + final int seed; + + /// Creates a new instance of [XXHash32]. + /// + /// Parameters: + /// - [seed] is an optional 32-bit integer. Default: 0 + const XXHash32([this.seed = 0]); + + @override + final String name = 'XXH32'; + + @override + XXHash32Sink createSink() => XXHash32Sink(seed); + + /// Get and instance of [XXHash32] with an specific seed + XXHash32 withSeed(int seed) => XXHash32(seed); +} + +/// Gets the 32-bit xxHash value of a String +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +int xxh32code(String input, [Encoding? encoding]) { + return xxh32.string(input, encoding).number(); +} + +/// Gets the 32-bit xxHash hash of a String in hexadecimal. +/// +/// Parameters: +/// - [input] is the string to hash +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +String xxh32sum(String input, [Encoding? encoding]) { + return xxh32.string(input, encoding).hex(); +} diff --git a/hashlib/lib/src/xxh64.dart b/hashlib/lib/src/xxh64.dart new file mode 100644 index 0000000..b445145 --- /dev/null +++ b/hashlib/lib/src/xxh64.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/src/algorithms/xxh64/xxh64.dart'; +import 'package:hashlib/src/core/block_hash.dart'; + +/// An instance of [XXHash64] with seed = 0 +const XXHash64 xxh64 = XXHash64(0); + +/// XXHash64 is a fast and efficient non-cryptographic hash function for +/// 64-bit platforms. It is designed for producing a quick and reliable hash +/// value for a given data, which can be used for many applications, such as +/// checksum, data validation, etc. In addition, it has a good distribution of +/// hash values, which helps to reduce [collisions][wiki]. +/// +/// This implementation was derived from https://github.com/Cyan4973/xxHash +/// +/// [wiki]: https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison +/// +/// **WARNING: It should not be used for cryptographic purposes.** +class XXHash64 extends BlockHashBase { + final int seed; + + /// Creates a new instance of [XXHash64]. + /// + /// Parameters: + /// - [seed] is an optional 64-bit integer. Default: 0 + const XXHash64([this.seed = 0]); + + @override + final String name = 'XXH64'; + + @override + XXHash64Sink createSink() => XXHash64Sink(seed); + + /// Get and instance of [XXHash64] with an specific seed + XXHash64 withSeed(int seed) => XXHash64(seed); +} + +/// Gets the 64-bit xxHash value of a String. +/// +/// Parameters: +/// - [input] is the string to hash. +/// - The [encoding] is the encoding to use. Default is `input.codeUnits`. +int xxh64code(String input, [Encoding? encoding]) { + return xxh64.string(input, encoding).number(); +} + +/// Gets the 64-bit xxHash hash of a String in hexadecimal. +/// +/// Parameters: +/// - [input] is the string to hash. +/// - The [encoding] is the encoding to use. Default is `input.codeUnits` +String xxh64sum(String input, [Encoding? encoding]) { + return xxh64.string(input, encoding).hex(); +} diff --git a/hashlib/pubspec.yaml b/hashlib/pubspec.yaml new file mode 100644 index 0000000..32b9742 --- /dev/null +++ b/hashlib/pubspec.yaml @@ -0,0 +1,34 @@ +name: hashlib +description: Secure hash functions, checksum generators, and key derivation algorithms optimized for Dart. +homepage: https://github.com/bitanon/hashlib +version: 2.2.0 + +environment: + sdk: '>=2.19.0 <4.0.0' + +platforms: + android: + ios: + linux: + macos: + web: + windows: + +dependencies: + hashlib_codecs: ^3.0.1 + +dev_dependencies: + lints: any + test: any + crypto: any + hash: any + pointycastle: any + benchmark_harness: any + argon2: any + pana: any + coverage: any + cobertura: any + junitreport: any + +funding: + - https://paypal.me/sd1pu diff --git a/hashlib/test/adler32_test.dart b/hashlib/test/adler32_test.dart new file mode 100644 index 0000000..156e5d3 --- /dev/null +++ b/hashlib/test/adler32_test.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/adler32.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('Adler-32 test', () { + test("name", () { + expect(adler32.name, 'ALDER-32'); + }); + test('adler32code with empty string', () { + expect(adler32code(""), 1); + }); + test('adler32code with a string', () { + expect(adler32code("Wikipedia"), 300286872); + }); + test('sink test', () { + final sink = Adler32Hash(); + expect(sink.closed, isFalse); + expect(sink.a, 1); + expect(sink.b, 0); + sink.add([10, 20]); + expect(sink.closed, isFalse); + sink.close(); + expect(sink.closed, isTrue); + expect(() => sink.add([10]), throwsStateError); + sink.reset(); + expect(sink.closed, isFalse); + expect(sink.a, 1); + expect(sink.b, 0); + sink.add([10, 20]); + expect(sink.digest().number(), (sink.b << 16) | sink.a); + expect(sink.closed, isTrue); + }); + }); +} diff --git a/hashlib/test/argon2_test.dart b/hashlib/test/argon2_test.dart new file mode 100644 index 0000000..84c35e7 --- /dev/null +++ b/hashlib/test/argon2_test.dart @@ -0,0 +1,565 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('functionality test', () { + test("name", () { + expect( + Argon2( + parallelism: 1, + memorySizeKB: 10, + iterations: 1, + ).name, + r'argon2id', + ); + expect( + Argon2( + parallelism: 1, + memorySizeKB: 10, + iterations: 1, + type: Argon2Type.argon2id, + ).name, + r'argon2id', + ); + expect( + Argon2( + parallelism: 1, + memorySizeKB: 10, + iterations: 1, + type: Argon2Type.argon2d, + ).name, + r'argon2d', + ); + expect( + Argon2( + parallelism: 1, + memorySizeKB: 10, + iterations: 1, + type: Argon2Type.argon2i, + ).name, + r'argon2i', + ); + }); + }); + // Test cases are generated by https://argon2.online/ + group('Argon2 v19 test', () { + test("argon2i m=16, t=2, p=1 @ out = 16", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2i, + hashLength: 16, + iterations: 2, + parallelism: 1, + memorySizeKB: 16, + salt: "some salt".codeUnits, + ); + final password = 'password'.codeUnits; + final matcher = "bb5794ea66451b8fce3a84dd02d33949"; + final encoded = + r"$argon2i$v=19$m=16,t=2,p=1$c29tZSBzYWx0$u1eU6mZFG4/OOoTdAtM5SQ"; + var result = argon2.convert(password); + expect(result.toString(), equals(encoded)); + expect(result.hex(), matcher); + expect(result.encoded(), encoded); + expect(argon2.encode(password), encoded); + }); + test("argon2d m=16, t=2, p=1 @ out = 16", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2d, + hashLength: 16, + iterations: 2, + parallelism: 1, + memorySizeKB: 16, + salt: "some salt".codeUnits, + ); + final matcher = "cf916880b91ba8a1390fff6b624baa27"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + test("argon2id m=16, t=2, p=1 @ out = 16", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2id, + hashLength: 16, + iterations: 2, + parallelism: 1, + memorySizeKB: 16, + salt: "some salt".codeUnits, + ); + final matcher = "88c91661b3cea3c3853593608881f324"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + + test("argon2i m=256, t=2, p=4 @ out = 32", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2i, + hashLength: 32, + iterations: 2, + parallelism: 4, + memorySizeKB: 256, + salt: "some salt".codeUnits, + ); + final matcher = + "aaef1c23ce86889c7d76f5ea214760fb66900916546cde42ebdc47914daed123"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + test("argon2d m=256, t=2, p=4 @ out = 32", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2d, + hashLength: 32, + iterations: 2, + parallelism: 4, + memorySizeKB: 256, + salt: "some salt".codeUnits, + ); + final matcher = + "c31433dbefadf7aa527bbbcc7beace0d8d70973719c6efb1c24fb21278569701"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + test("argon2id m=256, t=2, p=4 @ out = 32", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2id, + hashLength: 32, + iterations: 2, + parallelism: 4, + memorySizeKB: 256, + salt: "some salt".codeUnits, + ); + final matcher = + "c23e4a305f649971527eda884bda6b481004aedd31740460da3d43db8946786f"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + + test("encoded hash instance check", () { + final encoded = + r"$argon2id$v=19$m=128,t=1,p=4$c29tZSBzYWx0$24VHMpaU5EkkdH5rpdnb5zeOf3Y"; + final matcher = "db8547329694e44924747e6ba5d9dbe7378e7f76"; + final argon2 = Argon2.fromEncoded(fromCrypt(encoded)); + expect(argon2.type, Argon2Type.argon2id); + expect(argon2.version, Argon2Version.v13); + expect(argon2.memorySizeKB, 128); + expect(argon2.parallelism, 4); + expect(argon2.iterations, 1); + expect(argon2.hashLength, 20); + expect(argon2.salt, "some salt".codeUnits); + var result = argon2.convert("password".codeUnits); + expect(result.hex(), matcher); + expect(result.encoded(), encoded); + }); + + test("argon2Verify with encoded", () { + final encoded = + r"$argon2id$v=19$m=128,t=1,p=4$c29tZSBzYWx0$24VHMpaU5EkkdH5rpdnb5zeOf3Y"; + expect(argon2Verify(encoded, "password".codeUnits), isTrue); + }); + + test("argon2Verify without the hash", () { + final password = "password".codeUnits; + final encoded = r"$argon2id$v=19$m=128,t=1,p=4$c29tZSBzYWx0"; + expect(() => argon2Verify(encoded, password), throwsArgumentError); + }); + + test("argon2Verify with password", () { + final matcher = "db8547329694e44924747e6ba5d9dbe7378e7f76"; + var result = Argon2( + type: Argon2Type.argon2id, + salt: 'some salt'.codeUnits, + hashLength: 20, + iterations: 1, + parallelism: 4, + memorySizeKB: 128, + ).verify( + fromHex(matcher), + "password".codeUnits, + ); + expect(result, true); + }); + + test('argon2i', () { + final result = argon2i( + 'password'.codeUnits, + "some salt".codeUnits, + hashLength: 16, + security: Argon2Security( + 'custom', + m: 16, + p: 1, + t: 2, + ), + ); + final matcher = "bb5794ea66451b8fce3a84dd02d33949"; + final encoded = + r"$argon2i$v=19$m=16,t=2,p=1$c29tZSBzYWx0$u1eU6mZFG4/OOoTdAtM5SQ"; + expect(result.hex(), matcher); + expect(result.encoded(), encoded); + }); + + test('argon2d', () { + final result = argon2d( + 'password'.codeUnits, + "some salt".codeUnits, + hashLength: 16, + security: Argon2Security( + 'custom', + m: 16, + p: 1, + t: 2, + ), + ); + final matcher = "cf916880b91ba8a1390fff6b624baa27"; + final salt = r"$argon2d$v=19$m=16,t=2,p=1$c29tZSBzYWx0"; + expect(result.hex(), matcher); + expect(result.encoded(), startsWith(salt)); + }); + + test('argon2id', () { + final result = argon2id( + 'password'.codeUnits, + "some salt".codeUnits, + hashLength: 16, + security: Argon2Security( + 'custom', + m: 16, + p: 1, + t: 2, + ), + ); + final matcher = "88c91661b3cea3c3853593608881f324"; + final salt = r"$argon2id$v=19$m=16,t=2,p=1$c29tZSBzYWx0"; + expect(result.hex(), matcher); + expect(result.encoded(), startsWith(salt)); + }); + + test("multiple call with same instance", () { + final argon2 = Argon2( + version: Argon2Version.v13, + type: Argon2Type.argon2i, + hashLength: 16, + iterations: 2, + parallelism: 1, + memorySizeKB: 16, + salt: "some salt".codeUnits, + ); + final matcher = "bb5794ea66451b8fce3a84dd02d33949"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + expect(argon2.convert('password'.codeUnits).hex(), matcher); + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + + test("with personalization", () { + final personalization = "personalization".codeUnits; + final argon2 = Argon2.fromSecurity( + Argon2Security.test, + hashLength: 16, + salt: "some salt".codeUnits, + personalization: personalization, + ); + final matcher = "33561b7ad59b447aa5f6e3113d2f32ca"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + expect(argon2.personalization, equals(personalization)); + }); + + test("with key", () { + final key = "random key".codeUnits; + final argon2 = Argon2.fromSecurity( + Argon2Security.test, + hashLength: 16, + salt: "some salt".codeUnits, + key: key, + ); + final matcher = "4ad0d2f98a6e7f6e3e99c520d1813c07"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + expect(argon2.key, equals(key)); + }); + + test("with key and personalization", () { + final argon2 = Argon2.fromSecurity( + Argon2Security.test, + hashLength: 16, + salt: "some salt".codeUnits, + key: "random key".codeUnits, + personalization: "personalization".codeUnits, + ); + final matcher = "0bd2a8c0386b4125a6f439f2f863fc35"; + expect(argon2.convert('password'.codeUnits).hex(), matcher); + }); + }); + + group('Argon2Context Tests', () { + // Test for Argon2Context constructor + test('Creates Argon2Context with valid parameters', () { + var salt = List.generate(16, (i) => i); + var context = Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + salt: salt, + hashLength: 32, + ); + + expect(context.salt, equals(salt)); + expect(context.passes, equals(3)); + expect(context.lanes, equals(2)); + expect(context.memorySizeKB, equals(8192)); + expect(context.hashLength, equals(32)); + }); + + // Tests for invalid parameters + test('Throws if hashLength is too small', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + hashLength: 3, + ), + throwsA(isA().having( + (e) => e.message, 'message', 'The tag length must be at least 4')), + ); + }); + + test('Throws if hashLength is too large', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + hashLength: 0x3FFFFFF + 1, + ), + throwsA(isA().having((e) => e.message, 'message', + 'The tag length must be at most 67108863')), + ); + }); + + test('Throws if parallelism is too small', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 0, + memorySizeKB: 8192, + ), + throwsA(isA().having( + (e) => e.message, 'message', 'The parallelism must be at least 1')), + ); + }); + + test('Throws if parallelism is too large', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 0x7FFF + 1, + memorySizeKB: 8192, + ), + throwsA(isA().having((e) => e.message, 'message', + 'The parallelism must be at most 32767')), + ); + }); + + test('Throws if iterations are too few', () { + expect( + () => Argon2Context( + iterations: 0, + parallelism: 2, + memorySizeKB: 8192, + ), + throwsA(isA().having( + (e) => e.message, 'message', 'The iterations must be at least 1')), + ); + }); + + test('Throws if iterations are too many', () { + expect( + () => Argon2Context( + iterations: 0x3FFFFFF + 1, + parallelism: 2, + memorySizeKB: 8192, + ), + throwsA(isA().having((e) => e.message, 'message', + 'The iterations must be at most 67108863')), + ); + }); + + test('Throws if memorySizeKB is too small for parallelism', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 15, + ), + throwsA(isA().having((e) => e.message, 'message', + 'The memory size must be at least 8 * parallelism')), + ); + }); + + test('Throws if memorySizeKB is too large', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 0x3FFFFFF + 1, + ), + throwsA(isA().having((e) => e.message, 'message', + 'The memorySizeKB must be at most 67108863')), + ); + }); + + test('Throws if salt is too short', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + salt: List.generate(7, (i) => i), + ), + throwsA(isA().having((e) => e.message, 'message', + 'The salt must be at least 8 bytes long')), + ); + }); + + test('Throws if salt is too long', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + salt: Uint8List(0x3FFFFFF + 1), + ), + throwsA(isA().having((e) => e.message, 'message', + 'The salt must be at most 67108863 bytes long')), + ); + }); + + test('Throws if key is too short', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + key: [], + ), + throwsA(isA().having((e) => e.message, 'message', + 'The key must be at least 1 bytes long')), + ); + }); + + test('Throws if key is too long', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + key: Uint8List(0x3FFFFFF + 1), + ), + throwsA(isA().having((e) => e.message, 'message', + 'The key must be at most 67108863 bytes long')), + ); + }); + + test('Throws if personalization data is too short', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + personalization: [], + ), + throwsA(isA()), + ); + }); + + test('Throws if personalization data is too long', () { + expect( + () => Argon2Context( + iterations: 3, + parallelism: 2, + memorySizeKB: 8192, + personalization: Uint8List(0x3FFFFFF + 1), + ), + throwsArgumentError, + ); + }); + + // Test for Argon2Context.fromEncoded factory method + test('Creates Argon2Context from encoded string with valid parameters', () { + var cryptData = fromCrypt( + r'$argon2id$v=19$m=8192,t=3,p=2$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + var context = Argon2Context.fromEncoded(cryptData); + + expect(context.type, equals(Argon2Type.argon2id)); + expect(context.version, equals(Argon2Version.v13)); + expect(context.memorySizeKB, equals(8192)); + expect(context.passes, equals(3)); + expect(context.lanes, equals(2)); + expect(context.salt.length, equals(9)); + }); + + test('Throws if encoded string has invalid type', () { + var cryptData = fromCrypt( + r'$argon2x$v=19$m=8192,t=3,p=2$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + expect( + () => Argon2Context.fromEncoded(cryptData), + throwsA(isA() + .having((e) => e.message, 'message', 'Unknown type')), + ); + }); + + test('Throws if encoded string has invalid version', () { + var cryptData = fromCrypt( + r'$argon2i$v=99$m=8192,t=3,p=2$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + expect( + () => Argon2Context.fromEncoded(cryptData), + throwsA(isA() + .having((e) => e.message, 'message', 'Unknown version')), + ); + }); + + test('Throws if encoded string has no parameters', () { + var cryptData = + fromCrypt(r'$argon2i$v=19$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + expect( + () => Argon2Context.fromEncoded(cryptData), + throwsA(isA() + .having((e) => e.message, 'message', 'No paramters')), + ); + }); + + test('Throws if encoded string is missing "m" parameter', () { + var cryptData = fromCrypt( + r'$argon2i$v=19$t=3,p=2$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + expect( + () => Argon2Context.fromEncoded(cryptData), + throwsA(isA() + .having((e) => e.message, 'message', 'Missing parameter: m')), + ); + }); + + test('Throws if encoded string is missing "t" parameter', () { + var cryptData = fromCrypt( + r'$argon2i$v=19$m=8192,p=2$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + expect( + () => Argon2Context.fromEncoded(cryptData), + throwsA(isA() + .having((e) => e.message, 'message', 'Missing parameter: t')), + ); + }); + + test('Throws if encoded string is missing "p" parameter', () { + var cryptData = fromCrypt( + r'$argon2i$v=19$m=8192,t=3$c29tZSBzYWx0$CZOgzrCgoVUzMoR/dcUZyw'); + expect( + () => Argon2Context.fromEncoded(cryptData), + throwsA(isA() + .having((e) => e.message, 'message', 'Missing parameter: p')), + ); + }); + }); +} diff --git a/hashlib/test/bcrypt_test.dart b/hashlib/test/bcrypt_test.dart new file mode 100644 index 0000000..ef8437b --- /dev/null +++ b/hashlib/test/bcrypt_test.dart @@ -0,0 +1,643 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('bcrypt test', () { + group('functionality test', () { + test("name", () { + expect(Bcrypt(cost: 10).name, r'Bcrypt/2b'); + expect(Bcrypt(cost: 10, version: BcryptVersion.$2a).name, r'Bcrypt/2a'); + expect(Bcrypt(cost: 10, version: BcryptVersion.$2x).name, r'Bcrypt/2x'); + expect(Bcrypt(cost: 10, version: BcryptVersion.$2y).name, r'Bcrypt/2y'); + expect(Bcrypt(cost: 10, version: BcryptVersion.$2b).name, r'Bcrypt/2b'); + }); + + // http://openwall.info/wiki/john/sample-hashes + test("bcrypt", () { + const password = r"password"; + const salt = r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO"; + const encoded = + r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe"; + var output = bcrypt(utf8.encode(password), salt); + expect(output, equals(encoded)); + }); + + test("bcryptVerify", () { + const password = r"password"; + const encoded = + r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe"; + expect(bcryptVerify(encoded, password.codeUnits), true); + }); + + test("bcryptSalt", () { + final salt = bcryptSalt(nb: 5, version: BcryptVersion.$2a); + expect(salt.length, 29); + expect(salt, startsWith(r"$2a$05$")); + }); + + test("bcryptSalt with security", () { + final salt = bcryptSalt(security: BcryptSecurity.strong); + expect(salt.length, 29); + expect(salt, startsWith(r"$2b$15$")); + }); + + test("bcryptSalt with security overrides", () { + final salt = bcryptSalt(security: BcryptSecurity.strong, nb: 10); + expect(salt.length, 29); + expect(salt, startsWith(r"$2b$10$")); + }); + + test("bcryptDigest", () { + var password = "password".codeUnits; + var salt = fromBase64( + "bvIG6Nmid91Mu9RcmmWZfO", + codec: Base64Codec.bcrypt, + ); + var result = fromBase64( + '5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe', + codec: Base64Codec.bcrypt, + ); + const encoded = + r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe"; + final output = bcryptDigest( + password, + nb: 5, + salt: salt, + version: BcryptVersion.$2a, + ); + expect(output.bytes, equals(result)); + expect(output.encoded(), equals(encoded)); + expect(output.toString(), equals(encoded)); + }); + test("bcryptDigest with security", () { + var password = "password".codeUnits; + var salt = fromBase64( + "bvIG6Nmid91Mu9RcmmWZfO", + codec: Base64Codec.bcrypt, + ); + var result = fromBase64( + '5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe', + codec: Base64Codec.bcrypt, + ); + final output = bcryptDigest( + password, + salt: salt, + version: BcryptVersion.$2a, + security: BcryptSecurity.little, + ); + expect(output.bytes, equals(result)); + }); + test("Bcrypt instance with security", () { + var password = "password".codeUnits; + var salt = fromBase64( + "bvIG6Nmid91Mu9RcmmWZfO", + codec: Base64Codec.bcrypt, + ); + var result = fromBase64( + '5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe', + codec: Base64Codec.bcrypt, + ); + final output = Bcrypt.fromSecurity( + BcryptSecurity.little, + salt: salt, + version: BcryptVersion.$2a, + ).convert(password); + expect(output.bytes, equals(result)); + }); + test("The cost must be at least 0", () { + BcryptContext(cost: 0); + expect(() => BcryptContext(cost: -10), throwsArgumentError); + expect(() => BcryptContext(cost: -1), throwsArgumentError); + }); + test("The cost must be at most 31", () { + BcryptContext(cost: 31); + expect(() => BcryptContext(cost: 32), throwsArgumentError); + expect(() => BcryptContext(cost: 100), throwsArgumentError); + }); + test("The salt must be exactly 16-bytes", () { + BcryptContext(cost: 4, salt: List.filled(16, 0)); + expect( + () => BcryptContext(cost: 4, salt: []), + throwsArgumentError, + ); + expect( + () => BcryptContext(cost: 4, salt: List.filled(15, 0)), + throwsArgumentError, + ); + expect( + () => BcryptContext(cost: 4, salt: List.filled(17, 0)), + throwsArgumentError, + ); + }); + test("Bcrypt from encoded", () { + Bcrypt.fromEncoded(fromCrypt(r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO")); + }); + test("Bcrypt from encoded with invalid version", () { + expect( + () => Bcrypt.fromEncoded(fromCrypt(r"$2c$05$bvIG6Nmid91Mu9RcmmWZfO")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Invalid version', + ), + ), + ); + }); + test("Bcrypt from encoded with invalid cost", () { + expect( + () => Bcrypt.fromEncoded(fromCrypt(r"$2x$bvIG6Nmid91Mu9RcmmWZfO")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Invalid cost', + ), + ), + ); + expect( + () => Bcrypt.fromEncoded(fromCrypt(r"$2y$32$bvIG6Nmid91Mu9RcmmWZfO")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'The cost must be at most 31', + ), + ), + ); + expect( + () => Bcrypt.fromEncoded(fromCrypt(r"$2y$-1$bvIG6Nmid91Mu9RcmmWZfO")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'The cost must be at least 0', + ), + ), + ); + }); + test("Bcrypt from encoded with invalid salt", () { + expect( + () => Bcrypt.fromEncoded(fromCrypt(r"$2b$05$bvIG6Nmid91Mu9RcmmWZf")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Invalid hash', + ), + ), + ); + expect( + () => Bcrypt.fromEncoded(fromCrypt(r"$2b$05$bvIG6Nmid91Mu9RcmmWZf0")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Invalid length', + ), + ), + ); + expect( + () => Bcrypt.fromEncoded(fromCrypt( + r"$2b$05$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1")), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Invalid hash', + ), + ), + ); + Bcrypt.fromEncoded(fromCrypt( + r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s1", + )); + }); + }); + + group('version 2a', () { + // http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/glibc/crypt_blowfish/wrapper.c?rev=HEAD + test(r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.", () { + const password = r""; + const encoded = + r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s."; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + // https://stackoverflow.com/a/12761326/774398 + test(r"$2a$10$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle", () { + const password = r"ππππππππ"; + const encoded = + r"$2a$10$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + // https://bitbucket.org/vadim/bcrypt.net/src/464c41416dc9/BCrypt.Net.Test/TestBCrypt.cs?fileviewer=file-view-default + test(r"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye", () { + const password = r""; + const encoded = + r"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe", () { + const password = r"a"; + const encoded = + r"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i", () { + const password = r"abc"; + const encoded = + r"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC", () { + const password = r"abcdefghijklmnopqrstuvwxyz"; + const encoded = + r"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO", () { + const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD"; + const encoded = + r"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + // https://github.com/pyca/bcrypt/blob/main/tests/test_bcrypt.py + test(r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", () { + var password = "U*U"; + var encoded = + r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", () { + var password = "U*U*"; + var encoded = + r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", () { + var password = "U*U*U"; + var encoded = + r"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", () { + var password = "0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "chars after 72 are ignored"; + var encoded = + r"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", () { + var password = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "chars after 72 are ignored as usual"; + var encoded = + r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6"; + var output = bcrypt(password.codeUnits, encoded); + expect(output, equals(encoded)); + }); + + test(r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", () { + var password = "\xa3"; + var encoded = + r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"; + var output = bcrypt(password.codeUnits, encoded); + expect(output, equals(encoded)); + }); + + test(r"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG", () { + var password = + "g7\r\x01\xf3\xd4\xd0\xa9JB^\x18\x007P\xb2N\xc7\x1c\xee\x87&\x83C" + "\x8b\xe8\x18\xc5>\x86\x14/\xd6\xcc\x1cJ\xde\xd7ix\xeb\xdeO\xef" + "\xe1i\xac\xcb\x03\x96v1' \xd6@.m\xa5!\xa0\xef\xc0("; + var encoded = + r"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG"; + var output = bcrypt(password.codeUnits, encoded); + expect(output, equals(encoded)); + }); + }); + + group('version 2y', () { + test(r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", () { + var password = "\xa3"; + var encoded = + r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"; + var output = bcrypt(password.codeUnits, encoded); + expect(output, equals(encoded)); + }); + test(r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", () { + var password = "\xff\xff\xa3"; + var encoded = + r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e"; + var output = bcrypt(password.codeUnits, encoded); + expect(output, equals(encoded)); + }); + }); + + // https://github.com/pyca/bcrypt/blob/main/tests/test_bcrypt.py + group('version 2b', () { + test(r"$2b$04$cVWp4XaNU8a4v1uMRum2SO026BWLIoQMD/TXg5uZV.0P.uO8m3YEm", () { + var password = "Kk4DQuMMfZL9o"; + var encoded = + r"$2b$04$cVWp4XaNU8a4v1uMRum2SO026BWLIoQMD/TXg5uZV.0P.uO8m3YEm"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$pQ7gRO7e6wx/936oXhNjrOUNOHL1D0h1N2IDbJZYs.1ppzSof6SPy", () { + var password = "9IeRXmnGxMYbs"; + var encoded = + r"$2b$04$pQ7gRO7e6wx/936oXhNjrOUNOHL1D0h1N2IDbJZYs.1ppzSof6SPy"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW", () { + var password = "xVQVbwa1S0M8r"; + var encoded = + r"$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$eH8zX.q5Q.j2hO1NkVYJQOM6KxntS/ow3.YzVmFrE4t//CoF4fvne", () { + var password = "Zfgr26LWd22Za"; + var encoded = + r"$2b$04$eH8zX.q5Q.j2hO1NkVYJQOM6KxntS/ow3.YzVmFrE4t//CoF4fvne"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$ahiTdwRXpUG2JLRcIznxc.s1.ydaPGD372bsGs8NqyYjLY1inG5n2", () { + var password = "Tg4daC27epFBE"; + var encoded = + r"$2b$04$ahiTdwRXpUG2JLRcIznxc.s1.ydaPGD372bsGs8NqyYjLY1inG5n2"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$nQn78dV0hGHf5wUBe0zOFu8n07ZbWWOKoGasZKRspZxtt.vBRNMIy", () { + var password = "xhQPMmwh5ALzW"; + var encoded = + r"$2b$04$nQn78dV0hGHf5wUBe0zOFu8n07ZbWWOKoGasZKRspZxtt.vBRNMIy"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$cvXudZ5ugTg95W.rOjMITuM1jC0piCl3zF5cmGhzCibHZrNHkmckG", () { + var password = "59je8h5Gj71tg"; + var encoded = + r"$2b$04$cvXudZ5ugTg95W.rOjMITuM1jC0piCl3zF5cmGhzCibHZrNHkmckG"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$YYjtiq4Uh88yUsExO0RNTuEJ.tZlsONac16A8OcLHleWFjVawfGvO", () { + var password = "wT4fHJa2N9WSW"; + var encoded = + r"$2b$04$YYjtiq4Uh88yUsExO0RNTuEJ.tZlsONac16A8OcLHleWFjVawfGvO"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$WLTjgY/pZSyqX/fbMbJzf.qxCeTMQOzgL.CimRjMHtMxd/VGKojMu", () { + var password = "uSgFRnQdOgm4S"; + var encoded = + r"$2b$04$WLTjgY/pZSyqX/fbMbJzf.qxCeTMQOzgL.CimRjMHtMxd/VGKojMu"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$2moPs/x/wnCfeQ5pCheMcuSJQ/KYjOZG780UjA/SiR.KsYWNrC7SG", () { + var password = "tEPtJZXur16Vg"; + var encoded = + r"$2b$04$2moPs/x/wnCfeQ5pCheMcuSJQ/KYjOZG780UjA/SiR.KsYWNrC7SG"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$HrEYC/AQ2HS77G78cQDZQ.r44WGcruKw03KHlnp71yVQEwpsi3xl2", () { + var password = "vvho8C6nlVf9K"; + var encoded = + r"$2b$04$HrEYC/AQ2HS77G78cQDZQ.r44WGcruKw03KHlnp71yVQEwpsi3xl2"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$vVYgSTfB8KVbmhbZE/k3R.ux9A0lJUM4CZwCkHI9fifke2.rTF7MG", () { + var password = "5auCCY9by0Ruf"; + var encoded = + r"$2b$04$vVYgSTfB8KVbmhbZE/k3R.ux9A0lJUM4CZwCkHI9fifke2.rTF7MG"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$JfoNrR8.doieoI8..F.C1OQgwE3uTeuardy6lw0AjALUzOARoyf2m", () { + var password = "GtTkR6qn2QOZW"; + var encoded = + r"$2b$04$JfoNrR8.doieoI8..F.C1OQgwE3uTeuardy6lw0AjALUzOARoyf2m"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$HP3I0PUs7KBEzMBNFw7o3O7f/uxaZU7aaDot1quHMgB2yrwBXsgyy", () { + var password = "zKo8vdFSnjX0f"; + var encoded = + r"$2b$04$HP3I0PUs7KBEzMBNFw7o3O7f/uxaZU7aaDot1quHMgB2yrwBXsgyy"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$xnFVhJsTzsFBTeP3PpgbMeMREb6rdKV9faW54Sx.yg9plf4jY8qT6", () { + var password = "I9VfYlacJiwiK"; + var encoded = + r"$2b$04$xnFVhJsTzsFBTeP3PpgbMeMREb6rdKV9faW54Sx.yg9plf4jY8qT6"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$WQp9.igoLqVr6Qk70mz6xuRxE0RttVXXdukpR9N54x17ecad34ZF6", () { + var password = "VFPO7YXnHQbQO"; + var encoded = + r"$2b$04$WQp9.igoLqVr6Qk70mz6xuRxE0RttVXXdukpR9N54x17ecad34ZF6"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$xgZtlonpAHSU/njOCdKztOPuPFzCNVpB4LGicO4/OGgHv.uKHkwsS", () { + var password = "VDx5BdxfxstYk"; + var encoded = + r"$2b$04$xgZtlonpAHSU/njOCdKztOPuPFzCNVpB4LGicO4/OGgHv.uKHkwsS"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe", () { + var password = "dEe6XfVGrrfSH"; + var encoded = + r"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$7/Qj7Kd8BcSahPO4khB8me4ssDJCW3r4OGYqPF87jxtrSyPj5cS5m", () { + var password = "cTT0EAFdwJiLn"; + var encoded = + r"$2b$04$7/Qj7Kd8BcSahPO4khB8me4ssDJCW3r4OGYqPF87jxtrSyPj5cS5m"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$04$VvlCUKbTMjaxaYJ.k5juoecpG/7IzcH1AkmqKi.lIZMVIOLClWAk.", () { + var password = "J8eHUDuxBB520"; + var encoded = + r"$2b$04$VvlCUKbTMjaxaYJ.k5juoecpG/7IzcH1AkmqKi.lIZMVIOLClWAk."; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + + test(r"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd.", () { + var password = [ + 125, 62, 179, 254, 241, 139, 160, 230, 40, 162, 76, 122, 113, 195, // + 80, 127, 204, 200, 98, 123, 249, 20, 246, 246, 96, 129, 71, 53, 236, + 29, 135, 16, 191, 167, 225, 125, 73, 55, 32, 150, 223, 99, 242, 191, + 179, 86, 104, 223, 77, 136, 113, 247, 255, 27, 130, 126, 122, 19, 221, + 233, 132, 0, 221, 52 + ]; + var encoded = + r"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd."; + var output = bcrypt(password, encoded); + expect(output, equals(encoded)); + }); + }); + + group('big cost', () { + test(r"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW", () { + const password = r""; + const encoded = + r"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO", () { + const password = r""; + const encoded = + r"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.", () { + const password = r"a"; + const encoded = + r"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V."; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u", () { + const password = r"a"; + const encoded = + r"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS", () { + const password = r"a"; + const encoded = + r"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm", () { + const password = r"abc"; + const encoded = + r"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi", () { + const password = r"abc"; + const encoded = + r"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q", () { + const password = r"abc"; + const encoded = + r"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz.", () { + const password = r"abcdefghijklmnopqrstuvwxyz"; + const encoded = + r"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz."; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq", () { + const password = r"abcdefghijklmnopqrstuvwxyz"; + const encoded = + r"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG", () { + const password = r"abcdefghijklmnopqrstuvwxyz"; + const encoded = + r"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW", () { + const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD"; + const encoded = + r"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS", () { + const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD"; + const encoded = + r"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + test(r"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC", () { + const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD"; + const encoded = + r"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC"; + var output = bcrypt(utf8.encode(password), encoded); + expect(output, equals(encoded)); + }); + }, skip: true); + }); +} diff --git a/hashlib/test/blake2b_test.dart b/hashlib/test/blake2b_test.dart new file mode 100644 index 0000000..097df95 --- /dev/null +++ b/hashlib/test/blake2b_test.dart @@ -0,0 +1,213 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('Blake2bHash functionality test', () { + test('The digest size must be between 1 and 64', () { + Blake2bHash(1); + Blake2bHash(64); + expect(() => Blake2bHash(0), throwsArgumentError); + expect(() => Blake2bHash(65), throwsArgumentError); + }); + test('The valid length of salt is 16 bytes ', () { + Blake2bHash(16, salt: Uint8List(0)); + Blake2bHash(16, salt: Uint8List(16)); + expect(() => Blake2bHash(16, salt: Uint8List(1)), throwsArgumentError); + expect(() => Blake2bHash(16, salt: Uint8List(17)), throwsArgumentError); + }); + test('The valid length of personalization is 16 bytes ', () { + Blake2bHash(16, aad: Uint8List(0)); + Blake2bHash(16, aad: Uint8List(16)); + expect(() => Blake2bHash(16, aad: Uint8List(1)), throwsArgumentError); + expect(() => Blake2bHash(16, aad: Uint8List(17)), throwsArgumentError); + }); + test('The key should not be greater than 64 bytes ', () { + Blake2bHash(16, key: Uint8List(0)); + Blake2bHash(16, key: Uint8List(1)); + Blake2bHash(16, key: Uint8List(64)); + expect(() => Blake2bHash(16, key: Uint8List(65)), throwsArgumentError); + }); + }); + + group('Blake2b funtionality test', () { + test("Blake2b name", () { + expect(Blake2b(8).name, 'BLAKE2b-64'); + expect(blake2b160.name, 'BLAKE2b-160'); + expect(blake2b256.name, 'BLAKE2b-256'); + expect(blake2b384.name, 'BLAKE2b-384'); + expect(blake2b512.name, 'BLAKE2b-512'); + }); + test("Blake2bMac name", () { + expect(blake2b160.mac.name, 'BLAKE2b-160/MAC'); + expect(blake2b256.mac.name, 'BLAKE2b-256/MAC'); + expect(blake2b384.mac.name, 'BLAKE2b-384/MAC'); + expect(blake2b512.mac.name, 'BLAKE2b-512/MAC'); + expect(blake2b160.mac.by([1]).name, 'BLAKE2b-160/MAC'); + expect(blake2b256.mac.by([1]).name, 'BLAKE2b-256/MAC'); + expect(blake2b384.mac.by([1]).name, 'BLAKE2b-384/MAC'); + expect(blake2b512.mac.by([1]).name, 'BLAKE2b-512/MAC'); + expect(blake2b512.mac.pbkdf2([2]).name, 'BLAKE2b-512/MAC/PBKDF2'); + expect(blake2b512.hmac.pbkdf2([2]).name, 'BLAKE2b-512/HMAC/PBKDF2'); + }); + test('sink test', () { + final input = List.generate(512, (i) => i & 0xFF); + final output = + "c59ab1095ca4579525338b6b74689ff234bc3fe9765fe26dfb04ddceaee0ab84" + "dfd8967594cb261fcd88687f4454d80f718116c1b3c32f9f7e169357468cbe67"; + final sink = blake2b512.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < 512; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + expect(sink.closed, isFalse); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); + + group('blake2b512 test', () { + test('with empty string', () { + expect( + blake2b512.string("").hex(), + "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419" + "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"); + }); + test('with a', () { + expect( + blake2b512.string('a').hex(), + "333fcb4ee1aa7c115355ec66ceac917c8bfd815bf7587d325aec1864edd24e34" + "d5abe2c6b1b5ee3face62fed78dbef802f2a85cb91d455a8f5249d330853cb3c"); + }); + test('with abc', () { + expect( + blake2b512.string("abc").hex(), + "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1" + "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"); + }); + test('with long string', () { + expect( + blake2b512.convert(List.generate(512, (i) => i & 0xFF)).hex(), + "c59ab1095ca4579525338b6b74689ff234bc3fe9765fe26dfb04ddceaee0ab84" + "dfd8967594cb261fcd88687f4454d80f718116c1b3c32f9f7e169357468cbe67"); + }); + test('with very long string', () { + expect( + blake2b512.convert(List.generate(646154, (i) => i & 0xFF)).hex(), + "9ddaedc61db231a9dd3de20ea031d8f612f1d541179d3cd0bf90bf5a6740880c" + "d5d4b42a5db783e04c278679e75f2047c6105441062d08175d4c2708ce2e74f3"); + }, skip: true); + test('with block size string', () { + expect( + blake2b512.convert(List.generate(128, (i) => i & 0xFF)).hex(), + "2319e3789c47e2daa5fe807f61bec2a1a6537fa03f19ff32e87eecbfd64b7e0e" + "8ccff439ac333b040f19b0c4ddd11a61e24ac1fe0f10a039806c5dcc0da3d115"); + }); + test('with block size + 1 string', () { + expect( + blake2b512.convert(List.generate(129, (i) => i & 0xFF)).hex(), + "f59711d44a031d5f97a9413c065d1e614c417ede998590325f49bad2fd444d3e" + "4418be19aec4e11449ac1a57207898bc57d76a1bcf3566292c20c683a5c4648f"); + }); + test('with twice block size string', () { + expect( + blake2b512.convert(List.generate(256, (i) => i & 0xFF)).hex(), + "1ecc896f34d3f9cac484c73f75f6a5fb58ee6784be41b35f46067b9c65c63a67" + "94d3d744112c653f73dd7deb6666204c5a9bfa5b46081fc10fdbe7884fa5cbf8"); + }); + test('with half block size string', () { + expect( + blake2b512.convert(List.generate(64, (i) => i & 0xFF)).hex(), + "2fc6e69fa26a89a5ed269092cb9b2a449a4409a7a44011eecad13d7c4b045660" + "2d402fa5844f1a7a758136ce3d5d8d0e8b86921ffff4f692dd95bdc8e5ff0052"); + }); + + test('with a secret', () { + expect( + blake2b512.mac.byString('secret').string("a").hex(), + "4a1f6558272af9c63689a9383883671379cab5ff6a38b69643529bd27c5b61fe" + "e24bc919c36d1bb3747630bf90d3459a453c2c3bb5775bbe0c15cc324222114c"); + }); + test('with empty string and a secret', () { + expect( + blake2b512.mac.byString('secret').string('').hex(), + "865aca2ba0b9b941352e4680e14f543d1af37f7a3479304262a5da8c97468d9f" + "e22636bae941d9c7b83b93efc36e82177606c72a1c00af48bb182c69d1f1abc3"); + }); + }); + + group('blake2b256 test', () { + test('with empty string', () { + expect(blake2b256.string('').hex(), + "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"); + }); + test('with abc', () { + expect(blake2b256.string('abc').hex(), + "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319"); + }); + test('with empty string and a secret', () { + expect(blake2b256.mac.byString('secret').string('').hex(), + "080989147a9b01f885f00d9b90cee0855cfb08aa68d57dc2c92333b2df70a5ea"); + }); + test('with abc and a secret', () { + expect(blake2b256.mac.byString('secret').string('abc').hex(), + "e23c35713e7249f369b7c6f60291c0af9d6ac0231d80f46e13b1313fe7f4a4d5"); + }); + }); + + group('blake2b160 test', () { + test('with empty string', () { + expect(blake2b160.string('').hex(), + "3345524abf6bbe1809449224b5972c41790b6cf2"); + }); + test('with abc', () { + expect(blake2b160.string('abc').hex(), + "384264f676f39536840523f284921cdc68b6846b"); + }); + test('with empty string and a secret', () { + expect(blake2b160.mac.byString('secret').string('').hex(), + "f8630ddf0a315edbc8977f2c52040e9cedb70a85"); + }); + test('with abc and a secret', () { + expect(blake2b160.mac.byString('secret').string('abc').hex(), + "0c3d973f5f44547f37c0c0c34ae8cd9015c324ef"); + }); + }); + + group('blake2b384 test', () { + test('with empty string', () { + expect( + blake2b384.string('').hex(), + "b32811423377f52d7862286ee1a72ee540524380fda1724a" + "6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"); + }); + test('with abc', () { + expect( + blake2b384.string('abc').hex(), + "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbd" + "a46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4"); + }); + test('with empty string and a secret', () { + expect( + blake2b384.mac.byString('secret').string('').hex(), + "6f65d5a686d1eb9783f19bc3fe7dbd077d61714ceba63b2d" + "11594faee11f98950c2c221379d98d397dfe04c697839472"); + }); + test('with abc and a secret', () { + expect( + blake2b384.mac.byString('secret').string('abc').hex(), + "5dad40c5f4f12bde483498c651ce1f5e86e6f47454c953fb" + "c953c74e34aba9541b689c2000e984c909278304af01c991"); + }); + }); +} diff --git a/hashlib/test/blake2s_test.dart b/hashlib/test/blake2s_test.dart new file mode 100644 index 0000000..ac833ee --- /dev/null +++ b/hashlib/test/blake2s_test.dart @@ -0,0 +1,182 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('Blake2sHash functionality test', () { + test('The digest size must be between 1 and 32', () { + Blake2sHash(1); + Blake2sHash(32); + expect(() => Blake2sHash(0), throwsArgumentError); + expect(() => Blake2sHash(33), throwsArgumentError); + expect(() => Blake2sHash(64), throwsArgumentError); + }); + test('The valid length of salt is 8 bytes ', () { + Blake2sHash(16, salt: Uint8List(0)); + Blake2sHash(16, salt: Uint8List(8)); + expect(() => Blake2sHash(16, salt: Uint8List(1)), throwsArgumentError); + expect(() => Blake2sHash(16, salt: Uint8List(9)), throwsArgumentError); + expect(() => Blake2sHash(16, salt: Uint8List(16)), throwsArgumentError); + }); + test('The valid length of personalization is 8 bytes ', () { + Blake2sHash(16, aad: Uint8List(0)); + Blake2sHash(16, aad: Uint8List(8)); + expect(() => Blake2sHash(16, aad: Uint8List(1)), throwsArgumentError); + expect(() => Blake2sHash(16, aad: Uint8List(9)), throwsArgumentError); + expect(() => Blake2sHash(16, aad: Uint8List(16)), throwsArgumentError); + }); + test('The key should not be greater than 32 bytes ', () { + Blake2sHash(16, key: Uint8List(0)); + Blake2sHash(16, key: Uint8List(1)); + Blake2sHash(16, key: Uint8List(32)); + expect(() => Blake2sHash(16, key: Uint8List(33)), throwsArgumentError); + expect(() => Blake2sHash(16, key: Uint8List(64)), throwsArgumentError); + }); + }); + group('Blake2s funtionality test', () { + test("Blake2s name", () { + expect(Blake2s(8).name, 'BLAKE2s-64'); + expect(blake2s128.name, 'BLAKE2s-128'); + expect(blake2s160.name, 'BLAKE2s-160'); + expect(blake2s224.name, 'BLAKE2s-224'); + expect(blake2s256.name, 'BLAKE2s-256'); + }); + test("Blake2sMac name", () { + final key = [1]; + expect(blake2s128.mac.name, 'BLAKE2s-128/MAC'); + expect(blake2s160.mac.name, 'BLAKE2s-160/MAC'); + expect(blake2s224.mac.name, 'BLAKE2s-224/MAC'); + expect(blake2s256.mac.name, 'BLAKE2s-256/MAC'); + expect(blake2s128.mac.by(key).name, 'BLAKE2s-128/MAC'); + expect(blake2s160.mac.by(key).name, 'BLAKE2s-160/MAC'); + expect(blake2s224.mac.by(key).name, 'BLAKE2s-224/MAC'); + expect(blake2s256.mac.by(key).name, 'BLAKE2s-256/MAC'); + }); + test('sink test', () { + final input = List.generate(512, (i) => i & 0xFF); + final output = + "aeb5499d81f14cb10c2539411cbe3e71167293458543bfa4ca1f9584625fd4c6"; + final sink = blake2s256.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < 512; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + expect(sink.closed, isFalse); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); + + group('blake2s256 test', () { + test('with empty string', () { + expect(blake2s256.string("").hex(), + "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"); + }); + test('with a', () { + expect(blake2s256.string('a').hex(), + "4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90"); + }); + test('with abc', () { + expect(blake2s256.string("abc").hex(), + "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"); + }); + test('with long string', () { + expect(blake2s256.convert(List.generate(512, (i) => i & 0xFF)).hex(), + "aeb5499d81f14cb10c2539411cbe3e71167293458543bfa4ca1f9584625fd4c6"); + }); + test('with very long string', () { + expect(blake2s256.convert(List.generate(646154, (i) => i & 0xFF)).hex(), + "8e13a3e326c071e9d9dabd66025e49d3f467767cd10b5e6e1df1de9354ea2af9"); + }, skip: true); + test('with block size string', () { + expect(blake2s256.convert(List.generate(64, (i) => i & 0xFF)).hex(), + "56f34e8b96557e90c1f24b52d0c89d51086acf1b00f634cf1dde9233b8eaaa3e"); + }); + test('with block size + 1 string', () { + expect(blake2s256.convert(List.generate(65, (i) => i & 0xFF)).hex(), + "1b53ee94aaf34e4b159d48de352c7f0661d0a40edff95a0b1639b4090e974472"); + }); + test('with twice block size string', () { + expect(blake2s256.convert(List.generate(128, (i) => i & 0xFF)).hex(), + "1fa877de67259d19863a2a34bcc6962a2b25fcbf5cbecd7ede8f1fa36688a796"); + }); + test('with half block size string', () { + expect(blake2s256.convert(List.generate(32, (i) => i & 0xFF)).hex(), + "05825607d7fdf2d82ef4c3c8c2aea961ad98d60edff7d018983e21204c0d93d1"); + }); + + test('with a secret', () { + expect(blake2s256.mac.byString('secret').string("a").hex(), + "6252d094f32c706b6fa11529126bdf2910c4dd7638bf866348808df63f62531d"); + }); + test('with empty string and a secret', () { + expect(blake2s256.mac.byString('secret').string('').hex(), + "864f60ce88fc1c80c7b3b4f0bb920255fb464484a9dc7346f1d0e4e190d358cd"); + }); + }); + + group('blake2s128 test', () { + test('with empty string', () { + expect(blake2s128.string('').hex(), "64550d6ffe2c0a01a14aba1eade0200c"); + }); + test('with abc', () { + expect( + blake2s128.string('abc').hex(), "aa4938119b1dc7b87cbad0ffd200d0ae"); + }); + test('with empty string and a secret', () { + expect(blake2s128.mac.byString('secret').string('').hex(), + "5697f332469e36135bad2a52a79803be"); + }); + test('with abc and a secret', () { + expect(blake2s128.mac.byString('secret').string('abc').hex(), + "9af4e6ccbbfafb7c9dbc6088ca27f3da"); + }); + }); + + group('blake2s160 test', () { + test('with empty string', () { + expect(blake2s160.string('').hex(), + "354c9c33f735962418bdacb9479873429c34916f"); + }); + test('with abc', () { + expect(blake2s160.string('abc').hex(), + "5ae3b99be29b01834c3b508521ede60438f8de17"); + }); + test('with empty string and a secret', () { + expect(blake2s160.mac.byString('secret').string('').hex(), + "3bdb8b311ae9f0547671fef3933653996ee65f45"); + }); + test('with abc and a secret', () { + expect(blake2s160.mac.byString('secret').string('abc').hex(), + "1fda19951bd14742e8b3587b1f195f09975ff628"); + }); + }); + + group('blake2s224 test', () { + test('with empty string', () { + expect(blake2s224.string('').hex(), + "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"); + }); + test('with abc', () { + expect(blake2s224.string('abc').hex(), + "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55"); + }); + test('with empty string and a secret', () { + expect(blake2s224.mac.byString('secret').string('').hex(), + "7a37923d75c9d7be6b8fb2946a23d2d7f46067637380f0e91ef8ad0c"); + }); + test('with abc and a secret', () { + expect(blake2s224.mac.byString('secret').string('abc').hex(), + "d19a652b914f52e1437a5273d74aee9aba8921bbde5656ebddc8ffa8"); + }); + }); +} diff --git a/hashlib/test/compare_test.dart b/hashlib/test/compare_test.dart new file mode 100644 index 0000000..133942e --- /dev/null +++ b/hashlib/test/compare_test.dart @@ -0,0 +1,432 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore_for_file: library_annotations + +@Tags(['vm-only']) + +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:crypto/crypto.dart' as crypto; +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:hashlib/random.dart'; +import 'package:pointycastle/digests/blake2b.dart' as pc_blake2b; +import 'package:pointycastle/digests/keccak.dart' as pc_keccak; +import 'package:pointycastle/digests/md4.dart' as pc_md4; +import 'package:pointycastle/digests/sha3.dart' as pc_sha3; +import 'package:pointycastle/digests/sm3.dart' as pc_sm3; +import 'package:test/test.dart'; + +void main() { + group('blake2b512 comparison', () { + test('with pointycastle', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final out1 = blake2b512.convert(data).hex(); + final out2 = toHex( + pc_blake2b.Blake2bDigest(digestSize: 64).process(data), + ); + expect(out1, equals(out2), reason: 'size: $i'); + } + }); + + test('with pointycastle with key', () { + final key = randomBytes(16); + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final out1 = blake2b512.mac.by(key).convert(data).hex(); + final out2 = toHex( + pc_blake2b.Blake2bDigest(digestSize: 64, key: key).process(data), + ); + expect(out1, equals(out2), reason: 'size: $i'); + } + }); + + test('with pointycastle with salt', () { + final salt = randomBytes(16); + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final out1 = Blake2b(64, salt: salt).convert(data).hex(); + final out2 = toHex( + pc_blake2b.Blake2bDigest(digestSize: 64, salt: salt).process(data), + ); + expect(out1, equals(out2), reason: 'size: $i'); + } + }); + + test('with pointycastle with personalization', () { + final personalization = randomBytes(16); + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final out1 = Blake2b( + 64, + aad: personalization, + ).convert(data).hex(); + final out2 = toHex( + pc_blake2b.Blake2bDigest( + digestSize: 64, + personalization: personalization, + ).process(data), + ); + expect(out1, equals(out2), reason: 'size: $i'); + } + }); + + test('with pointycastle with salt and personalization', () { + final salt = randomBytes(16); + final personalization = randomBytes(16); + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final out1 = Blake2b( + 64, + salt: salt, + aad: personalization, + ).convert(data).hex(); + final out2 = toHex( + pc_blake2b.Blake2bDigest( + digestSize: 64, + salt: salt, + personalization: personalization, + ).process(data), + ); + expect(out1, equals(out2), reason: 'size: $i'); + } + }); + + test('with pointycastle with key, salt and personalization', () { + final key = randomBytes(16); + final salt = randomBytes(16); + final aad = randomBytes(16); + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final out1 = Blake2b(64).mac.by(key, salt: salt, aad: aad).hex(data); + final out2 = toHex( + pc_blake2b.Blake2bDigest( + digestSize: 64, + key: key, + salt: salt, + personalization: aad, + ).process(data), + ); + expect(out1, equals(out2), reason: 'size: $i'); + } + }); + }); + + group('HMAC comparison', () { + test('with crypto for MD5', () { + var key = "key"; + var msg = "The quick brown fox jumps over the lazy dog"; + var expected = "80070713463e7749b90c2dc24911e275"; + var actual = toHex( + md5.hmac.byString(key).convert(msg.codeUnits).bytes, + ); + var actual2 = toHex( + crypto.Hmac(crypto.md5, key.codeUnits).convert(msg.codeUnits).bytes, + ); + expect(actual2, expected, reason: "Key: $key | Message: $msg"); + expect(actual, expected, reason: "Key: $key | Message: $msg"); + }); + + test('with crypto', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + final key = randomBytes(i & 0x7F); + expect( + toHex(sha1.hmac.by(key).convert(data).bytes), + toHex(crypto.Hmac(crypto.sha1, key).convert(data).bytes), + reason: 'Key: "${String.fromCharCodes(key)}" [${key.length}]\n' + 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + final key = randomBytes(i & 0x7F); + expect( + toHex(sha384.hmac.by(key).convert(data).bytes), + toHex(crypto.Hmac(crypto.sha384, key).convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + + group('Keccak comparison', () { + test('with keccak256', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + var pc = pc_keccak.KeccakDigest(256); + var other = pc.process(Uint8List.fromList(data)); + expect( + keccak256.convert(data).hex(), + toHex(other), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('with sha3', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + var pc = pc_sha3.SHA3Digest(256); + var other = pc.process(Uint8List.fromList(data)); + expect( + sha3_256.convert(data).hex(), + toHex(other), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + }); + + group('MD5 comparison', () { + test('for a file async', () async { + var file = File('LICENSE'); + var hash = await crypto.md5.bind(file.openRead()).first; + var hash2 = await md5.file(file); + expect(hash2.hex(), toHex(hash.bytes)); + }, tags: 'vm-only'); + + test('for a file sync', () async { + var file = File('LICENSE'); + var hash = await crypto.md5.bind(file.openRead()).first; + var hash2 = md5.fileSync(file); + expect(hash2.hex(), toHex(hash.bytes)); + }, tags: 'vm-only'); + + test('with crypto', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(md5.convert(data).bytes), + toHex(crypto.md5.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(md5.convert(data).bytes), + toHex(crypto.md5.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + + group('MD4 comparison', () { + test('with pointy-castle', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(md4.convert(data).bytes), + toHex(pc_md4.MD4Digest().process(data)), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('for a file sync', () { + var file = File('LICENSE'); + var hash = pc_md4.MD4Digest().process(file.readAsBytesSync()); + var hash2 = md4.fileSync(file); + expect(hash2.hex(), toHex(hash)); + }, tags: 'vm-only'); + }); + + group('SM3 comparison', () { + test('with pointy-castle', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + sm3.convert(data).hex(), + toHex(pc_sm3.SM3Digest().process(data)), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('for a file sync', () { + var file = File('LICENSE'); + var hash = pc_sm3.SM3Digest().process(file.readAsBytesSync()); + var hash2 = sm3.fileSync(file); + expect(hash2.hex(), toHex(hash)); + }, tags: 'vm-only'); + }); + + group('SHA1 comparison', () { + test('against known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha1.convert(data).bytes), + toHex(crypto.sha1.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha1.convert(data).bytes), + toHex(crypto.sha1.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + + group('SHA-224 comparison', () { + test('against known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha224.convert(data).bytes), + toHex(crypto.sha224.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha224.convert(data).bytes), + toHex(crypto.sha224.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + + group('SHA-256 comparison', () { + test('against known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha256.convert(data).bytes), + toHex(crypto.sha256.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha256.convert(data).bytes), + toHex(crypto.sha256.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + }); + + group('SHA-384 comparison', () { + test('against known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha384.convert(data).bytes), + toHex(crypto.sha384.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha384.convert(data).bytes), + toHex(crypto.sha384.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + + group('SHA-512/224 comparison', () { + test('with known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha512t224.convert(data).bytes), + toHex(crypto.sha512224.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha512t224.convert(data).bytes), + toHex(crypto.sha512224.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + + group('SHA-512/256 comparison', () { + test('with known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha512t256.convert(data).bytes), + toHex(crypto.sha512256.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha512t256.convert(data).bytes), + toHex(crypto.sha512256.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); + + group('SHA-512 comparison', () { + test('with known implementations', () { + for (int i = 0; i < 100; ++i) { + final data = randomBytes(i); + expect( + toHex(sha512.convert(data).bytes), + toHex(crypto.sha512.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + } + }); + + test('run in parallel', () async { + await Future.wait(List.generate(10, (i) => i).map((i) async { + final data = randomBytes(i); + expect( + toHex(sha512.convert(data).bytes), + toHex(crypto.sha512.convert(data).bytes), + reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]', + ); + })); + }); + }); +} diff --git a/hashlib/test/core/block_hash_test.dart b/hashlib/test/core/block_hash_test.dart new file mode 100644 index 0000000..ed29969 --- /dev/null +++ b/hashlib/test/core/block_hash_test.dart @@ -0,0 +1,102 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; +import 'package:test/test.dart'; +import 'package:hashlib/hashlib.dart'; + +// Concrete implementation for testing purposes +class TestBlockHashSink extends BlockHashSink { + TestBlockHashSink(super.blockLength, [int? bufferLength]) + : super(bufferLength: bufferLength); + + @override + int hashLength = 8; + + @override + void $update(List block, [int offset = 0, bool last = false]) { + // + } + + @override + Uint8List $finalize() { + return buffer; + } +} + +void main() { + group('BlockHashSink', () { + test('Invalid block size', () { + expect( + () => TestBlockHashSink(0), + throwsA(isA()), + ); + expect( + () => TestBlockHashSink(-1), + throwsA(isA()), + ); + expect( + () => TestBlockHashSink(-10), + throwsA(isA()), + ); + }); + + test('Invalid buffer size', () { + TestBlockHashSink(1, 0); + expect( + () => TestBlockHashSink(10, -1), + throwsA(isA()), + ); + expect( + () => TestBlockHashSink(10, -100), + throwsA(isA()), + ); + }); + + test('Initial state', () { + final sink = TestBlockHashSink(16); + expect(sink.closed, isFalse); + expect(sink.messageLength, equals(0)); + expect(sink.pos, equals(0)); + }); + + test('Reset method', () { + final sink = TestBlockHashSink(16); + sink.add([1, 2, 3]); + sink.reset(); + expect(sink.closed, isFalse); + expect(sink.messageLength, equals(0)); + expect(sink.pos, equals(0)); + }); + + test('Add and process data', () { + final sink = TestBlockHashSink(16); + sink.add([1, 2, 3, 4, 5]); + expect(sink.messageLength, equals(5)); + expect(sink.pos, equals(5)); + }); + + test('Digest after close', () { + final sink = TestBlockHashSink(16); + sink.add([1, 2, 3, 4, 5]); + final digest = sink.digest(); + expect(sink.closed, isTrue); + expect(digest.bytes.isNotEmpty, isTrue); + }); + + test('Throws error if adding data after close', () { + final sink = TestBlockHashSink(16); + sink.add([1, 2, 3, 4, 5]); + sink.close(); + expect(() => sink.add([6, 7, 8]), throwsA(isA())); + }); + + test('Buffer processing', () { + final sink = TestBlockHashSink(16); + final data = List.filled(32, 1); // Two full blocks + sink.add(data); + expect(sink.messageLength, equals(32)); + expect(sink.pos, equals(0)); // Should be 0 after processing full blocks + }); + }); +} diff --git a/hashlib/test/core/hash_base_file_test.dart b/hashlib/test/core/hash_base_file_test.dart new file mode 100644 index 0000000..af85f65 --- /dev/null +++ b/hashlib/test/core/hash_base_file_test.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore_for_file: library_annotations +// ignore_for_file: always_declare_return_types + +@Tags(['skip-vm']) + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +class MockHashBase extends HashBase { + @override + final String name = "mock"; + + @override + createSink() { + throw UnimplementedError(); + } +} + +void main() { + group('HashBaseFileSupport', () { + test('UnsupportedError for asynchronous file operation', () { + final mock = MockHashBase(); + expect(() => mock.file('dummy_file.txt'), throwsUnsupportedError); + }); + + test('throws UnsupportedError for synchronous file operation', () { + final mock = MockHashBase(); + expect(() => mock.fileSync('dummy_file.txt'), throwsUnsupportedError); + }); + + test('UnsupportedError for asynchronous file with parameters', () { + final mock = MockHashBase(); + expect( + () => mock.file('dummy_file.txt', 10, 100), + throwsUnsupportedError, + ); + }); + + test('UnsupportedError for synchronous file with parameters', () { + final mock = MockHashBase(); + expect( + () => mock.fileSync('dummy_file.txt', + start: 10, end: 100, bufferSize: 4096), + throwsA(isA()), + ); + }); + }); +} diff --git a/hashlib/test/core/hash_digest_test.dart b/hashlib/test/core/hash_digest_test.dart new file mode 100644 index 0000000..32bab28 --- /dev/null +++ b/hashlib/test/core/hash_digest_test.dart @@ -0,0 +1,166 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('HashDigest', () { + late Uint8List bytes; + late HashDigest digest; + + setUp(() { + bytes = Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8]); + digest = HashDigest(bytes); + }); + + test('toString returns correct hex representation', () { + expect(digest.toString(), equals('0102030405060708')); + }); + + test('binary returns correct binary representation', () { + final matcher = equals( + '00000001000000100000001100000100' + '00000101000001100000011100001000', + ); + expect(digest.binary(), matcher); + expect(digest.binary(), matcher); + }); + + test('octal returns correct octal representation', () { + expect(digest.octal(), equals('0004020060200501403410')); + }); + + test('hex returns correct hexadecimal representation', () { + expect(digest.hex(), equals('0102030405060708')); + var digest2 = HashDigest(Uint8List.fromList([9, 10, 11, 12])); + expect(digest2.hex(), equals('090a0b0c')); + expect(digest2.hex(true), equals('090A0B0C')); + }); + + test('base32 returns correct Base-32 representation', () { + expect(digest.base32(), equals('AEBAGBAFAYDQQ===')); + expect(digest.base32(upper: false), equals('aebagbafaydqq===')); + expect(digest.base32(padding: false), equals('AEBAGBAFAYDQQ')); + }); + + test('base64 returns correct Base-64 representation', () { + expect(digest.base64(), equals('AQIDBAUGBwg=')); + expect(digest.base64(padding: false), + equals('AQIDBAUGBwg')); // Without padding + expect(digest.base64(urlSafe: true), + equals('AQIDBAUGBwg=')); // URL-safe base64 + }); + + test('bigInt returns correct BigInt representation', () { + expect(digest.bigInt(), + equals(BigInt.parse('0807060504030201', radix: 16))); // Little-endian + expect(digest.bigInt(endian: Endian.big), + equals(BigInt.parse('0102030405060708', radix: 16))); // Big-endian + }); + + test('number returns correct integer representation', () { + expect(digest.number(8), equals(8)); + expect(digest.number(16), equals(0x0708)); + expect(digest.number(16, Endian.little), equals(0x0201)); + expect(digest.number(32), equals(0x05060708)); + expect(digest.number(32, Endian.little), equals(0x04030201)); + }); + + test('number does not accept invalid bit length', () { + expect(() => digest.number(-8), throwsArgumentError); + expect(() => digest.number(0), throwsArgumentError); + expect(() => digest.number(4), throwsArgumentError); + expect(() => digest.number(7), throwsArgumentError); + expect(() => digest.number(9), throwsArgumentError); + expect(() => digest.number(26), throwsArgumentError); + expect(() => digest.number(63), throwsArgumentError); + expect(() => digest.number(65), throwsArgumentError); + expect(() => digest.number(96), throwsArgumentError); + expect(() => digest.number(128), throwsArgumentError); + }); + + test('ascii returns correct ASCII representation', () { + final asciiBytes = Uint8List.fromList('ABCDEFGH'.codeUnits); + final asciiDigest = HashDigest(asciiBytes); + expect(asciiDigest.ascii(), equals('ABCDEFGH')); + }); + + test('utf8 returns correct UTF-8 representation', () { + final utf8Bytes = Uint8List.fromList(utf8.encode('Hello, World!')); + final utf8Digest = HashDigest(utf8Bytes); + expect(utf8Digest.utf8(), equals('Hello, World!')); + }); + + test('to(encoding) returns correct encoded string', () { + final utf16Bytes = Uint8List.fromList(ascii.encode('Hello, World!')); + final utf16Digest = HashDigest(utf16Bytes); + expect(utf16Digest.to(ascii), equals('Hello, World!')); + }); + + test('hashCode returns correct hash code', () { + expect(digest.hashCode, equals(bytes.hashCode)); + }); + + test('equality check compares correctly', () { + expect(digest == digest, isTrue); + expect(digest == HashDigest(bytes), isTrue); + expect(digest == HashDigest(Uint8List.fromList([...bytes])), isFalse); + }); + + test('isEqual returns true for equal digests', () { + final otherDigest = + HashDigest(Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8])); + expect(digest.isEqual(otherDigest), isTrue); + }); + + test('isEqual returns true for equal byte arrays', () { + final byteArray = [1, 2, 3, 4, 5, 6, 7, 8]; + expect(digest.isEqual(byteArray), isTrue); + }); + + test('isEqual returns true for equal byte iterables', () { + final byteIterables = {1, 2, 3, 4, 5, 6, 7, 8}; + expect(digest.isEqual(byteIterables), isTrue); + }); + + test('isEqual returns true for equal ByteBuffer', () { + final buffer = bytes.buffer; + expect(digest.isEqual(buffer), isTrue); + }); + + test('isEqual returns true for equal hexadecimal string', () { + final hexString = '0102030405060708'; + expect(digest.isEqual(hexString), isTrue); + }); + + test('isEqual returns false for unequal digests', () { + final otherDigest = + HashDigest(Uint8List.fromList([8, 7, 6, 5, 4, 3, 2, 1])); + expect(digest.isEqual(otherDigest), isFalse); + }); + + test('isEqual returns true with other buffer type', () { + final data = Uint32List.fromList([0x04030201, 0x08070605]); + expect(digest.isEqual(data), isTrue); + }); + + test('isEqual returns false for unequal byte arrays', () { + final byteArray = [8, 7, 6, 5, 4, 3, 2, 1]; + expect(digest.isEqual(byteArray), isFalse); + }); + + test('isEqual returns false for different length', () { + final otherDigest = HashDigest(Uint8List.fromList([1, 2, 3])); + expect(digest.isEqual(otherDigest), isFalse); + }); + + test('isEqual returns false for unsupported types', () { + expect(digest.isEqual(12345), isFalse); + expect(digest.isEqual(null), isFalse); + }); + }); +} diff --git a/hashlib/test/core/hash_sink_test.dart b/hashlib/test/core/hash_sink_test.dart new file mode 100644 index 0000000..01ac7a4 --- /dev/null +++ b/hashlib/test/core/hash_sink_test.dart @@ -0,0 +1,102 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +// Concrete implementation for testing purposes +class TestHashDigestSink extends HashDigestSink { + final List _data = []; + + @override + int get hashLength => 16; + + @override + void $process(List data, int start, int end) { + _data.addAll(data.sublist(start, end)); + } + + @override + Uint8List $finalize() { + int hash = _data.fold(0, (prev, elem) => prev ^ elem); + final result = List.filled(hashLength, hash); + return Uint8List.fromList(result); + } +} + +class TestHashBase extends HashBase { + @override + String get name => 'TestHash'; + + @override + HashDigestSink createSink() => TestHashDigestSink(); +} + +void main() { + group('HashBase', () { + test('convert method', () { + final hashBase = TestHashBase(); + final digest = hashBase.convert([1, 2, 3, 4]); + expect(digest.bytes, equals(List.filled(16, 1 ^ 2 ^ 3 ^ 4))); + }); + test('string method with default encoding', () { + final hash = TestHashBase(); + final digest = hash.string('test'); + expect(digest.bytes, + equals(List.filled(16, 'test'.codeUnits.reduce((a, b) => a ^ b)))); + }); + + test('string method with custom encoding', () { + final hash = TestHashBase(); + final digest = hash.string('test', utf8); + expect(digest.bytes, + equals(List.filled(16, utf8.encode('test').reduce((a, b) => a ^ b)))); + }); + + test('bind method', () async { + final hash = TestHashBase(); + final stream = Stream.fromIterable([ + [1, 2, 3], + [4, 5, 6] + ]); + final digest = await hash.bind(stream).first; + expect(digest.bytes, equals(List.filled(16, 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6))); + }); + + test('byteStream method', () async { + final hash = TestHashBase(); + final stream = Stream.fromIterable([1, 2, 3, 4, 5, 6]); + final digest = await hash.byteStream(stream, 4); + expect(digest.bytes, equals(List.filled(16, 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6))); + }); + + test('stringStream method with default encoding', () async { + final hash = TestHashBase(); + final stream = Stream.fromIterable(['hello', 'world']); + final digest = await hash.stringStraem(stream); + expect( + digest.bytes, + equals( + List.filled(16, 'helloworld'.codeUnits.reduce((a, b) => a ^ b)))); + }); + + test('stringStream method with custom encoding', () async { + final hash = TestHashBase(); + final stream = Stream.fromIterable(['hello', 'world']); + final digest = await hash.stringStraem(stream, utf8); + expect( + digest.bytes, + equals(List.filled( + 16, utf8.encode('helloworld').reduce((a, b) => a ^ b)))); + }); + + test('cast throws error', () { + final hashBase = TestHashBase(); + expect(() => hashBase.cast(), throwsUnsupportedError); + }); + }); +} diff --git a/hashlib/test/core/kdf_base_test.dart b/hashlib/test/core/kdf_base_test.dart new file mode 100644 index 0000000..98e9e78 --- /dev/null +++ b/hashlib/test/core/kdf_base_test.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +class TestKDF extends KeyDerivatorBase { + @override + String get name => 'TestKDF'; + + @override + final int derivedKeyLength = 3; + + @override + HashDigest convert(List password) { + password = List.filled(derivedKeyLength, password.length); + return HashDigest(Uint8List.fromList(password)); + } +} + +void main() { + group('KeyDerivatorBase', () { + test('TestKDF is defined properly', () { + final algo = TestKDF(); + expect(algo.name, 'TestKDF'); + expect(algo.derivedKeyLength, 3); + expect(algo.convert([1, 2]).bytes, equals([2, 2, 2])); + }); + + test('hex method works correctly', () { + expect(TestKDF().hex([]), equals('000000')); + expect(TestKDF().hex([1, 2, 3, 4, 5]), equals('050505')); + }); + + test('string method works correctly', () { + expect(TestKDF().string('').bytes, equals([0, 0, 0])); + expect(TestKDF().string('abcd').bytes, equals([4, 4, 4])); + }); + + test('string method works correctly with encoding', () { + expect(TestKDF().string('', utf8).bytes, equals([0, 0, 0])); + expect(TestKDF().string('abcd', utf8).bytes, equals([4, 4, 4])); + }); + + test('verify method works correctly', () { + expect(TestKDF().verify([2, 2, 2], [8, 4]), isTrue); + }); + }); +} diff --git a/hashlib/test/core/mac_base_test.dart b/hashlib/test/core/mac_base_test.dart new file mode 100644 index 0000000..9d603da --- /dev/null +++ b/hashlib/test/core/mac_base_test.dart @@ -0,0 +1,82 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('MACSinkBase', () { + test('derivedKeyLength should be defined', () { + final algo = md5.hmac.by([]); + final sink = algo.createSink(); + expect(sink.derivedKeyLength, sink.hashLength); + }); + + test('should initialize with the provided key', () { + final key = [1, 2, 3, 4, 5]; + final sink1 = md5.hmac.by(key).createSink(); + final sink2 = md5.hmac.by([1]).createSink(); + expect(sink1.innerKey, isNot(equals(sink2.innerKey))); + expect(sink1.outerKey, isNot(equals(sink2.outerKey))); + final sink3 = md5.hmac.by([1]).createSink(); + expect(sink2.innerKey, (equals(sink3.innerKey))); + expect(sink2.outerKey, (equals(sink3.outerKey))); + }); + }); + + group('MACHash', () { + test('createSink should create a MACSinkBase', () { + expect(sha256.hmac.by([2]).createSink(), isA()); + }); + + test('sign should return a HashDigest', () { + final key = [10]; + final message = [1, 2, 3, 4, 5]; + final result = md5.hmac.by(key).sign(message); + expect(result, isA()); + expect(result.bytes.length, equals(16)); + }); + + test('verify should return true if the tag matches the message', () { + final key = [10]; + final message = [1, 2, 3, 4, 5]; + final tag = md5.hmac.by(key).sign(message).bytes; + expect(md5.hmac.by(key).verify(tag, message), isTrue); + }); + + test('verify should return false if the tag does not match', () { + final key = [10]; + final message = [1, 2, 3, 4, 5]; + final tag = [1, 2, 3]; + expect(md5.hmac.by(key).verify(tag, message), isFalse); + }); + }); + + group('MACHashBase', () { + test('by create a MACHash', () { + expect(sha1.hmac.by([2]), isA()); + }); + + test('sign should return a HashDigest', () { + final key = [10]; + final message = [1, 2, 3, 4, 5]; + final result = md5.hmac.sign(key, message); + expect(result, isA()); + expect(result.bytes.length, equals(16)); + }); + + test('verify should return true if the tag matches the message', () { + final key = [10]; + final message = [1, 2, 3, 4, 5]; + final tag = md5.hmac.sign(key, message).bytes; + expect(md5.hmac.verify(key, tag, message), isTrue); + }); + + test('verify should return false if the tag does not match', () { + final key = [10]; + final message = [1, 2, 3, 4, 5]; + final tag = [1, 2, 3]; + expect(md5.hmac.verify(key, tag, message), isFalse); + }); + }); +} diff --git a/hashlib/test/crc16_test.dart b/hashlib/test/crc16_test.dart new file mode 100644 index 0000000..826515f --- /dev/null +++ b/hashlib/test/crc16_test.dart @@ -0,0 +1,103 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +/// CRC-16 code for "123456789" +var known = { + CRC16Params.ibm: 0xBB3D, + CRC16Params.ccitt: 0x2189, + CRC16Params.arinc: 0xEBA4, + CRC16Params.cms: 0xAEE7, + CRC16Params.dds110: 0x9ECF, + CRC16Params.maximDow: 0x44C2, + CRC16Params.modbus: 0x4B37, + CRC16Params.umts: 0xFEE8, + CRC16Params.usb: 0xB4C8, + CRC16Params.genibus: 0xD64E, + CRC16Params.gsm: 0xCE3C, + CRC16Params.ibm3740: 0x29B1, + CRC16Params.ccittFalse: 0x29B1, + CRC16Params.ibmSdlc: 0x906E, + CRC16Params.x25: 0x906E, + CRC16Params.iso: 0xBF05, + CRC16Params.mcrf4xx: 0x6F91, + CRC16Params.riello: 0x63D0, + CRC16Params.augCcitt: 0xE5CC, + CRC16Params.spiFujitsu: 0xE5CC, + CRC16Params.tms37157: 0x26B1, + CRC16Params.xmodem: 0x31C3, + CRC16Params.cdma2000: 0x4C06, + CRC16Params.dectR: 0x007E, + CRC16Params.dectX: 0x007F, + CRC16Params.dnp: 0xEA82, + CRC16Params.en13757: 0xC2B7, + CRC16Params.lj1200: 0xBDF4, + CRC16Params.nrsc5: 0xA066, + CRC16Params.m17: 0x772B, + CRC16Params.opensafetyA: 0x5D38, + CRC16Params.opensafetyB: 0x20FE, + CRC16Params.profibus: 0xA819, + CRC16Params.t10Dif: 0xD0DB, + CRC16Params.teledisk: 0x0FB3, +}; + +void main() { + group('CRC test', () { + test("name", () { + expect(crc16.name, 'CRC-16/ARC'); + }); + test("name for defined polynomial", () { + expect(CRC16(CRC16Params.arinc).name, 'CRC-16/ARINC'); + }); + test("name for custom polynomial", () { + expect(CRC16(CRC16Params(0x1919)).name, 'CRC-16/1919'); + }); + + test('code with an empty string', () { + expect(crc16code(""), 0); + }); + test('with a string', () { + expect(crc16.string("Wikipedia").hex(), "ee3e"); + }); + test('code with a string', () { + expect(crc16.code("Wikipedia", utf8), 0xee3e); + }); + + test('createSink produces same result for same input', () { + final sink1 = crc16.createSink(); + sink1.add(utf8.encode("TestString")); + final result1 = sink1.digest().hex(); + + final sink2 = crc16.createSink(); + sink2.add(utf8.encode("TestString")); + final result2 = sink2.digest().hex(); + + expect(result1, equals(result2)); + }); + + test('sink test', () { + final sink = crc16.createSink(); + expect(sink.closed, isFalse); + sink.add([10, 20]); + expect(sink.closed, isFalse); + sink.close(); + expect(sink.closed, isTrue); + expect(() => sink.add([10]), throwsStateError); + sink.reset(); + expect(sink.closed, isFalse); + sink.add([10, 20, 30]); + expect(sink.digest().length, 2); + expect(sink.closed, isTrue); + }); + + for (var e in known.entries) { + test('check "${e.key.name}"', () { + expect(crc16code("123456789", params: e.key), e.value); + }); + } + }); +} diff --git a/hashlib/test/crc32_test.dart b/hashlib/test/crc32_test.dart new file mode 100644 index 0000000..1607204 --- /dev/null +++ b/hashlib/test/crc32_test.dart @@ -0,0 +1,79 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +/// CRC-32 code for "123456789" +var known = { + CRC32Params.ieee: 0xCBF43926, + CRC32Params.bzip2: 0xFC891918, + CRC32Params.cksum: 0x765E7680, + CRC32Params.jamcrc: 0x340BC6D9, + CRC32Params.mpeg2: 0x0376E6E7, + CRC32Params.aixm: 0x3010BF7F, + CRC32Params.autosar: 0x1697D06A, + CRC32Params.base91D: 0x87315576, + CRC32Params.cdRomEdc: 0x6EC2EDC4, + CRC32Params.castagnoli: 0xE3069283, + CRC32Params.koopman: 0xD2C22F51, + CRC32Params.xfer: 0xBD0BE338, +}; + +void main() { + group('CRC-32 test', () { + test("name", () { + expect(crc32.name, 'CRC-32/IEEE'); + }); + test("name for defined polynomial", () { + expect(CRC32(CRC32Params.aixm).name, 'CRC-32/AIXM'); + }); + test("name for custom polynomial", () { + expect(CRC32(CRC32Params(0x1919)).name, 'CRC-32/1919'); + }); + test('code with an empty string', () { + expect(crc32code(""), 0); + }); + test('with a string', () { + expect(crc32.string("Wikipedia").hex(), "adaac02e"); + }); + test('code with a string', () { + expect(crc32.code("Wikipedia", utf8), 0xadaac02e); + }); + + test('createSink produces same result for same input', () { + final sink1 = crc32.createSink(); + sink1.add(utf8.encode("TestString")); + final result1 = sink1.digest().hex(); + + final sink2 = crc32.createSink(); + sink2.add(utf8.encode("TestString")); + final result2 = sink2.digest().hex(); + + expect(result1, equals(result2)); + }); + + test('sink test', () { + final sink = crc32.createSink(); + expect(sink.closed, isFalse); + sink.add([10, 20]); + expect(sink.closed, isFalse); + sink.close(); + expect(sink.closed, isTrue); + expect(() => sink.add([10]), throwsStateError); + sink.reset(); + expect(sink.closed, isFalse); + sink.add([10, 20, 30]); + expect(sink.digest().length, 4); + expect(sink.closed, isTrue); + }); + + for (var e in known.entries) { + test('check "${e.key.name}"', () { + expect(crc32code("123456789", params: e.key), e.value); + }); + } + }); +} diff --git a/hashlib/test/crc64_test.dart b/hashlib/test/crc64_test.dart new file mode 100644 index 0000000..e9c305c --- /dev/null +++ b/hashlib/test/crc64_test.dart @@ -0,0 +1,95 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +/// CRC-64 code for "123456789" +var known = { + CRC64Params.iso: '46a5a9388a5beffe', + CRC64Params.ecma: '6c40df5f0b497347', + CRC64Params.goIso: 'b90956c775a41001', + CRC64Params.ms: '75d4b74f024eceea', + CRC64Params.we: '62ec59e3f1a4f00a', + CRC64Params.jones: 'caa717168609f281', + CRC64Params.goEcma: '995dc9bbdf1939fa', + CRC64Params.xz: '995dc9bbdf1939fa', + CRC64Params.redis: 'e9c6d914c4b8d9ca', + CRC64Params.nvme: 'ae8b14860a799888', +}; + +void main() { + group('CRC-64 test', () { + test("name", () { + expect(crc64.name, 'CRC-64/ISO-HDLC'); + }); + test("name for defined polynomial", () { + expect(CRC64(CRC64Params.ecma).name, 'CRC-64/ECMA-182'); + }); + test("name for custom polynomial", () { + expect(CRC64(CRC64Params(0x1919)).name, 'CRC-64/1919'); + }); + + test('code with an empty string', () { + expect(crc64code(""), 0); + }); + test('with a string', () { + expect(crc64.string("Wikipedia").hex(), "352d6c9d31566506"); + }); + test('code with a string', () { + expect(crc64code("Wikipedia"), (0x352d6c9d << 32) | 0x31566506); + }, tags: ['vm-only']); + test('hex output', () { + expect(crc64sum("Wikipedia"), "352d6c9d31566506"); + }); + + test('createSink produces same result for same input', () { + final sink1 = crc64.createSink(); + sink1.add(utf8.encode("TestString")); + final result1 = sink1.digest().hex(); + + final sink2 = crc64.createSink(); + sink2.add(utf8.encode("TestString")); + final result2 = sink2.digest().hex(); + + expect(result1, equals(result2)); + }); + + test('sink test', () { + final sink = crc64.createSink(); + expect(sink.closed, isFalse); + sink.add([10, 20]); + expect(sink.closed, isFalse); + sink.close(); + expect(sink.closed, isTrue); + expect(() => sink.add([10]), throwsStateError); + sink.reset(); + expect(sink.closed, isFalse); + sink.add([10, 20, 30]); + expect(sink.digest().length, 8); + expect(sink.closed, isTrue); + }); + + test('CRC64Params.hex', () { + var params = CRC64Params.hex( + poly: '42F0E1EBA9EA3693', + seed: 'FFFFFFFFFFFFFFFF', + xorOut: 'FFFFFFFFFFFFFFFF', + ); + expect(params.high, 0x42F0E1EB); + expect(params.low, 0xA9EA3693); + expect(params.seedHigh, 0xFFFFFFFF); + expect(params.seedLow, 0xFFFFFFFF); + expect(params.xorOutHigh, 0xFFFFFFFF); + expect(params.xorOutLow, 0xFFFFFFFF); + }); + + for (var e in known.entries) { + test('check "${e.key.name}"', () { + expect(crc64sum("123456789", params: e.key), e.value); + }); + } + }); +} diff --git a/hashlib/test/fixures/long.txt b/hashlib/test/fixures/long.txt new file mode 100644 index 0000000..978e956 --- /dev/null +++ b/hashlib/test/fixures/long.txt @@ -0,0 +1,27 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacinia quis vel eros donec ac. Nisi vitae suscipit tellus mauris a diam maecenas sed enim. Enim neque volutpat ac tincidunt vitae semper. Vel fringilla est ullamcorper eget nulla facilisi etiam dignissim diam. Ultrices eros in cursus turpis massa tincidunt dui ut. Lorem donec massa sapien faucibus et. Nunc vel risus commodo viverra maecenas accumsan lacus vel facilisis. Cursus turpis massa tincidunt dui ut. Malesuada fames ac turpis egestas integer eget. Non odio euismod lacinia at quis risus. Risus in hendrerit gravida rutrum quisque non. + +Id ornare arcu odio ut sem nulla. Tristique sollicitudin nibh sit amet. Elit ut aliquam purus sit. Amet justo donec enim diam. Et netus et malesuada fames ac turpis egestas. Non arcu risus quis varius quam quisque id diam vel. Tellus integer feugiat scelerisque varius morbi enim nunc faucibus a. Tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Vulputate eu scelerisque felis imperdiet proin fermentum leo vel. Sed odio morbi quis commodo odio aenean sed. Mauris sit amet massa vitae tortor condimentum lacinia. Proin sagittis nisl rhoncus mattis rhoncus. Egestas pretium aenean pharetra magna ac placerat. Condimentum lacinia quis vel eros. At tempor commodo ullamcorper a lacus vestibulum. Pretium aenean pharetra magna ac placerat. Cursus vitae congue mauris rhoncus aenean vel elit scelerisque mauris. A pellentesque sit amet porttitor eget. Tristique magna sit amet purus gravida quis. + +Mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien et. Condimentum vitae sapien pellentesque habitant. Consectetur purus ut faucibus pulvinar elementum integer. Mattis enim ut tellus elementum. Pretium quam vulputate dignissim suspendisse. Nulla facilisi morbi tempus iaculis urna. Pretium fusce id velit ut tortor pretium. Ac tortor dignissim convallis aenean et tortor. Non blandit massa enim nec dui nunc mattis enim. Diam donec adipiscing tristique risus nec. Tellus at urna condimentum mattis pellentesque id nibh. Eu non diam phasellus vestibulum lorem. Aliquet nibh praesent tristique magna sit amet purus. At volutpat diam ut venenatis. + +Aliquam faucibus purus in massa tempor. Nec nam aliquam sem et tortor consequat. Ullamcorper morbi tincidunt ornare massa. Vulputate enim nulla aliquet porttitor lacus. Non pulvinar neque laoreet suspendisse. Nam libero justo laoreet sit amet cursus. Tristique nulla aliquet enim tortor at auctor urna nunc. Facilisi morbi tempus iaculis urna id volutpat lacus laoreet. Ut etiam sit amet nisl purus in mollis. Egestas purus viverra accumsan in nisl nisi scelerisque eu ultrices. Amet nisl suscipit adipiscing bibendum est ultricies integer. Sed pulvinar proin gravida hendrerit lectus. Sem integer vitae justo eget magna fermentum iaculis eu. Ipsum a arcu cursus vitae congue mauris rhoncus aenean. Sed tempus urna et pharetra pharetra. Auctor elit sed vulputate mi sit amet mauris commodo. Fusce id velit ut tortor pretium viverra suspendisse potenti. + +Eget nunc lobortis mattis aliquam faucibus purus in massa tempor. Gravida rutrum quisque non tellus. In mollis nunc sed id semper. Feugiat nibh sed pulvinar proin gravida hendrerit lectus. Id ornare arcu odio ut sem. Tellus in metus vulputate eu scelerisque felis. Pretium quam vulputate dignissim suspendisse in est ante in. Aliquet lectus proin nibh nisl condimentum. Sit amet consectetur adipiscing elit ut aliquam purus sit. Sed odio morbi quis commodo odio aenean sed adipiscing diam. Et pharetra pharetra massa massa ultricies mi quis. Nunc aliquet bibendum enim facilisis gravida. Vivamus arcu felis bibendum ut tristique et egestas. Et malesuada fames ac turpis egestas integer eget aliquet nibh. Amet risus nullam eget felis. Amet mattis vulputate enim nulla aliquet porttitor lacus luctus accumsan. Euismod elementum nisi quis eleifend quam. Felis imperdiet proin fermentum leo. + +Sit amet risus nullam eget. Urna nec tincidunt praesent semper feugiat nibh sed. Neque gravida in fermentum et sollicitudin ac orci phasellus egestas. Nulla facilisi nullam vehicula ipsum a arcu. Quis blandit turpis cursus in hac habitasse platea. Id porta nibh venenatis cras sed felis. Eget mi proin sed libero enim sed faucibus turpis in. Facilisi cras fermentum odio eu feugiat pretium nibh. Imperdiet massa tincidunt nunc pulvinar. Libero justo laoreet sit amet cursus sit amet dictum sit. Orci a scelerisque purus semper eget duis at tellus at. Consectetur purus ut faucibus pulvinar elementum. Dolor sit amet consectetur adipiscing elit ut aliquam purus sit. Semper eget duis at tellus. Pellentesque elit eget gravida cum sociis natoque penatibus et magnis. Dolor sit amet consectetur adipiscing elit duis tristique sollicitudin nibh. + +Viverra justo nec ultrices dui sapien eget mi. Cras tincidunt lobortis feugiat vivamus. Lectus proin nibh nisl condimentum id. Quam nulla porttitor massa id neque aliquam vestibulum. Ultrices eros in cursus turpis massa. Neque viverra justo nec ultrices dui sapien eget. Dui ut ornare lectus sit. Neque vitae tempus quam pellentesque nec nam. Nibh venenatis cras sed felis eget velit aliquet. Tincidunt lobortis feugiat vivamus at augue eget arcu dictum. + +Turpis cursus in hac habitasse platea dictumst quisque sagittis. Scelerisque felis imperdiet proin fermentum leo. Id faucibus nisl tincidunt eget nullam non nisi est sit. Facilisis sed odio morbi quis commodo odio aenean sed. Nulla porttitor massa id neque aliquam. Eros in cursus turpis massa tincidunt dui ut ornare lectus. Turpis cursus in hac habitasse platea dictumst. Eros in cursus turpis massa tincidunt dui ut ornare lectus. Diam quam nulla porttitor massa id neque. Tristique senectus et netus et malesuada fames ac. Nibh ipsum consequat nisl vel pretium lectus quam id. Tellus mauris a diam maecenas sed. + +Mi sit amet mauris commodo quis imperdiet massa tincidunt. Sit amet consectetur adipiscing elit ut aliquam purus sit. Lobortis mattis aliquam faucibus purus in massa tempor. Sem viverra aliquet eget sit. Sit amet luctus venenatis lectus. Aliquam vestibulum morbi blandit cursus risus at ultrices. Neque convallis a cras semper auctor neque vitae tempus quam. Pellentesque diam volutpat commodo sed egestas egestas fringilla phasellus. Eros donec ac odio tempor orci dapibus. Vel pretium lectus quam id leo in vitae turpis. Nulla malesuada pellentesque elit eget gravida. Ridiculus mus mauris vitae ultricies leo. Vel turpis nunc eget lorem. Pharetra pharetra massa massa ultricies mi quis hendrerit dolor magna. At lectus urna duis convallis convallis tellus. Nibh tellus molestie nunc non blandit massa enim nec. Vulputate ut pharetra sit amet aliquam id diam maecenas ultricies. Ultricies tristique nulla aliquet enim tortor at auctor urna. + +Quis varius quam quisque id. Felis donec et odio pellentesque diam volutpat commodo sed. Adipiscing elit pellentesque habitant morbi tristique senectus. Sit amet cursus sit amet dictum sit. Ut venenatis tellus in metus vulputate eu scelerisque felis imperdiet. Sagittis purus sit amet volutpat consequat mauris nunc. Ut tellus elementum sagittis vitae et. Interdum consectetur libero id faucibus nisl. Leo integer malesuada nunc vel risus commodo viverra. Suscipit tellus mauris a diam. Tortor condimentum lacinia quis vel eros donec. Donec massa sapien faucibus et. A scelerisque purus semper eget duis at. Sed viverra ipsum nunc aliquet. Nec sagittis aliquam malesuada bibendum arcu vitae elementum curabitur vitae. Enim eu turpis egestas pretium aenean pharetra magna ac placerat. Neque viverra justo nec ultrices dui sapien eget. Tempus egestas sed sed risus pretium quam vulputate dignissim. Lectus nulla at volutpat diam ut. Nibh sed pulvinar proin gravida hendrerit lectus. + +Quis hendrerit dolor magna eget est. Varius vel pharetra vel turpis nunc. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Arcu vitae elementum curabitur vitae nunc sed. Dui accumsan sit amet nulla. Purus sit amet luctus venenatis lectus magna fringilla. Egestas tellus rutrum tellus pellentesque. Sed tempus urna et pharetra pharetra massa massa ultricies mi. Nullam eget felis eget nunc. Integer malesuada nunc vel risus commodo. Pellentesque adipiscing commodo elit at imperdiet dui accumsan sit amet. + +Hac habitasse platea dictumst vestibulum rhoncus est pellentesque elit. Bibendum enim facilisis gravida neque convallis a cras. Scelerisque in dictum non consectetur a erat nam. Metus vulputate eu scelerisque felis. Vestibulum sed arcu non odio euismod lacinia at quis risus. Nisi est sit amet facilisis. Sed risus ultricies tristique nulla aliquet enim tortor at. Bibendum arcu vitae elementum curabitur vitae. Eu ultrices vitae auctor eu augue. Est pellentesque elit ullamcorper dignissim cras tincidunt. Neque volutpat ac tincidunt vitae semper quis lectus. Pretium fusce id velit ut tortor pretium. Turpis egestas maecenas pharetra convallis. Donec pretium vulputate sapien nec. Ante metus dictum at tempor commodo ullamcorper. Augue ut lectus arcu bibendum at varius vel pharetra vel. Consequat semper viverra nam libero justo. + +Aliquet porttitor lacus luctus accumsan tortor. Faucibus a pellentesque sit amet porttitor eget. Risus sed vulputate odio ut enim blandit volutpat maecenas. Enim ut sem viverra aliquet eget sit amet. Ac turpis egestas maecenas pharetra convallis. Enim neque volutpat ac tincidunt vitae. Urna et pharetra pharetra massa massa ultricies mi quis hendrerit. Facilisis mauris sit amet massa. Pretium nibh ipsum consequat nisl vel pretium lectus. Enim nunc faucibus a pellentesque sit amet. Donec ac odio tempor orci dapibus ultrices in iaculis nunc. Condimentum mattis pellentesque id nibh. Cursus euismod quis viverra nibh cras pulvinar mattis nunc. Arcu non odio euismod lacinia at quis risus. Mauris ultrices eros in cursus. Faucibus turpis in eu mi bibendum neque egestas congue quisque. + +Morbi tristique senectus et netus et malesuada fames ac turpis. Laoreet suspendisse interdum consectetur libero id faucibus. Tempor nec feugiat nisl pretium fusce id velit. Pellentesque nec nam aliquam sem et tortor consequat id. Est lorem ipsum dolor sit amet consectetur adipiscing elit pellentesque. Sit amet facilisis magna etiam tempor orci eu. Malesuada fames ac turpis egestas integer. Sagittis aliquam malesuada bibendum arcu vitae elementum curabitur. Senectus et netus et malesuada fames ac turpis egestas sed. Mi sit amet mauris commodo. Feugiat in ante metus dictum at tempor commodo ullamcorper. Cras tincidunt lobortis feugiat vivamus at. Ut tortor pretium viverra suspendisse potenti nullam. diff --git a/hashlib/test/fixures/xxh32.csv b/hashlib/test/fixures/xxh32.csv new file mode 100644 index 0000000..9650096 --- /dev/null +++ b/hashlib/test/fixures/xxh32.csv @@ -0,0 +1,10240 @@ +0,02cc5d05 +1,bd0f6f71 +2,c3bfcd7f +3,b872db1f +4,0df3e9ea +5,07f39c9b +6,c9943929 +7,1f92202c +8,c27c8a68 +9,07116278 +10,6c5d250a +11,2f858de0 +12,8c0a9c9c +13,5d5a79a4 +14,ec0eba1e +15,6f0374d7 +16,63001dca +17,e6d859c8 +18,e037f5c2 +19,a16d98c0 +20,fd348260 +21,b47a9e54 +22,8515180d +23,5afcc41e +24,db7fe300 +25,48da266f +26,96d6d2c2 +27,57cc808f +28,d4d98208 +29,43bb2a24 +30,f92b5bab +31,f6b608e8 +32,6ade9e85 +33,d2c37bc3 +34,1f195fa0 +35,0aaf796d +36,3bc45ee4 +37,16e43ff2 +38,68baadd5 +39,17839fff +40,dbb1cd2b +41,12bdd7d0 +42,d022cab7 +43,dc76bf3d +44,c2bdcf67 +45,2bde972a +46,fbe89ea0 +47,6d0a8532 +48,24242815 +49,6dc1939b +50,fdd11877 +51,54112f9a +52,341e977f +53,f7b9bfe9 +54,138cf461 +55,1ad841dc +56,9ce0b0e9 +57,e73ccb73 +58,12c880a0 +59,8b4bf63a +60,11e7607d +61,e0f6a057 +62,73d2a53f +63,a3928c9c +64,cd4f8467 +65,3975e32e +66,48ab4f28 +67,2fc5e761 +68,fd3c13db +69,cdf2d703 +70,48d15996 +71,d8b3c7a2 +72,bbf9fda8 +73,c026d1b3 +74,09efe994 +75,3d9656f9 +76,b1dc4667 +77,fa531c6a +78,431be963 +79,f28a674b +80,96a23763 +81,79f6e3ac +82,c0b41962 +83,635ecaa8 +84,8790b54b +85,77011fb2 +86,7173912f +87,d1202d36 +88,c485bbd4 +89,4411d7e5 +90,46fa2c51 +91,bdb2ee13 +92,4fb7515e +93,3ef804be +94,9c192bd3 +95,66e32993 +96,2b6bab83 +97,b012a103 +98,00063a8b +99,040f41dc +100,612d81ee +101,8bda846e +102,ef4a2a50 +103,e2195320 +104,d0643c48 +105,d5474c49 +106,d48cd64c +107,5d5f3703 +108,c05833bb +109,2f237d03 +110,cb51e8b7 +111,77971c7e +112,0a4ea068 +113,96c0eaa9 +114,778de8de +115,562e38d5 +116,cac09434 +117,c2126743 +118,55281888 +119,227d5ec2 +120,fd1778e7 +121,f2794b06 +122,e4f673e7 +123,d2fbd629 +124,62e86f88 +125,60b288ed +126,c56b7914 +127,379e48b8 +128,229177f4 +129,23b5cca4 +130,297bec3a +131,1c64660b +132,fb168e7f +133,dc46d46e +134,96d08663 +135,21c92163 +136,3305d22c +137,1c868e05 +138,13d6aba7 +139,8d0438a4 +140,990d2db0 +141,5efb7a15 +142,72deffc0 +143,7b66b3fb +144,0ba42669 +145,c8d0c5c6 +146,536a7373 +147,0a7293a2 +148,3379e15c +149,d9d014f2 +150,18a179ed +151,a5fc5cb8 +152,5132e628 +153,378fde7b +154,dc44db3b +155,b0346493 +156,a116e713 +157,bbb40e58 +158,35254e2d +159,791524a2 +160,2a10be19 +161,38ac81bb +162,90258a5f +163,6adcc7db +164,0dad0292 +165,c893220d +166,bec0e1d7 +167,5c6fbf6a +168,6b94315a +169,47dab30b +170,8e4abaf9 +171,2a17df41 +172,f842be6d +173,154ee7f7 +174,97da6aa1 +175,0195beab +176,acc032d2 +177,38456f54 +178,4a450855 +179,c02551d8 +180,a0d7b81c +181,307642d5 +182,fb50e475 +183,b1c1081c +184,5ffc4e9c +185,041f1dbb +186,21f66a8a +187,f4fb4260 +188,4ec19bdb +189,c912c29e +190,5fc87853 +191,62b1f311 +192,5e680d06 +193,897126b6 +194,02eccd4d +195,60bc3a1d +196,6017b5b1 +197,ed8f5458 +198,e718b098 +199,68931a6b +200,9d35c45b +201,95b0f056 +202,b47428f4 +203,843f8a65 +204,0cb7dc20 +205,cce0943e +206,3ee910d3 +207,94023a44 +208,ba276693 +209,16ef2ccf +210,9df26998 +211,0174a9d8 +212,ff69012a +213,d960f479 +214,52841136 +215,484f6bc0 +216,75839848 +217,f4b71759 +218,4df90e6a +219,118f7ab0 +220,174a6b92 +221,61568c93 +222,06566919 +223,5062c56d +224,09894395 +225,da465e12 +226,6e3ce7f6 +227,dd679003 +228,42ed8d1e +229,ef055eec +230,71f92baa +231,865987a5 +232,4764aabc +233,ce7ffc6f +234,e90e9582 +235,9c5461b6 +236,64586c71 +237,00d8e1d8 +238,b6968fa1 +239,269c2920 +240,18b72134 +241,37c9e884 +242,f5b79d8a +243,73ee2be5 +244,0e7a1355 +245,dc3c5491 +246,e621159d +247,39fd98bc +248,08425efe +249,17afa568 +250,18f06b6d +251,ab6fc98e +252,2d5dc0a3 +253,e9c57b00 +254,cc4f34ef +255,24a18590 +256,4a695586 +257,f60b6d64 +258,1e720705 +259,acb57f4c +260,b48a1efe +261,9e02ea6f +262,93edd103 +263,88ecd7b1 +264,f6258994 +265,ba269597 +266,cfb44a09 +267,19d57e28 +268,7762d8ce +269,b679f57e +270,bbda2aa9 +271,5bde0106 +272,90ee74ce +273,6d71d3ec +274,ed414f81 +275,1cee8656 +276,ccdc10d1 +277,e2bee942 +278,752e95a2 +279,18c30b88 +280,80aabb12 +281,7c30f75a +282,77ec3499 +283,c8dfc2c9 +284,8148c96b +285,8e3f29cf +286,9ac37ec2 +287,0570188d +288,c325b705 +289,9691df6b +290,9b0f159f +291,5a2528ed +292,2e8e1ec9 +293,2ca2f363 +294,60e01bc9 +295,fbd0b96e +296,934f7781 +297,f7a396f8 +298,02aecad6 +299,19b57969 +300,69b6ead5 +301,743344b8 +302,aec52eae +303,bf7d11c4 +304,b729e552 +305,73afa0d5 +306,ff5b0214 +307,976eb7d9 +308,1ab5aa86 +309,b278e2ff +310,a8dfec2b +311,7adff269 +312,bf5540ca +313,e8ff5977 +314,d8c866e9 +315,69599867 +316,43dd9e80 +317,c7f3c04f +318,8792b6d0 +319,01720a92 +320,60b0e641 +321,45403d58 +322,620e1ab6 +323,9357b19d +324,4c643c36 +325,6a632d6d +326,53d352c1 +327,a7b6a926 +328,48dd66fe +329,e44c2b0e +330,e8da2a8d +331,8fb35ab4 +332,21ce373c +333,17c53be3 +334,81cc53ad +335,43d705f7 +336,ae0701d2 +337,87c357e6 +338,b9a0538a +339,228f0c9b +340,62abf341 +341,af805b1c +342,26a72255 +343,5626779d +344,329e84e0 +345,e7e1ceea +346,64dfaa14 +347,8b0c0710 +348,42d7c0a9 +349,9fd4bef4 +350,ae7dc40c +351,0c00e966 +352,e0fe4094 +353,4df01cfb +354,9b1f65b3 +355,fe1572b6 +356,a98d722f +357,ad27746a +358,2678b9b4 +359,8692416c +360,b26ebf97 +361,49303233 +362,2e84e787 +363,efa89b3a +364,3a5c1e50 +365,71386890 +366,c0e7aa49 +367,332e59bf +368,5a7aa619 +369,95289d3c +370,5d45ebe1 +371,cf20782d +372,92f66751 +373,4bb54b36 +374,810aaadd +375,0f053f90 +376,14c61dbd +377,04e97dd0 +378,1d8dbc13 +379,7152d721 +380,6050deb5 +381,0e1f1707 +382,e58369c7 +383,51888b70 +384,6d25aea6 +385,6f54a7fe +386,3448bc4c +387,b7ec3dc3 +388,e946dda4 +389,a8dbed9c +390,ea4ae3dd +391,6d7ae1fb +392,cc1610ca +393,60a66d27 +394,0021a050 +395,f61c04cb +396,97e3d017 +397,ab1cb02c +398,7dc10502 +399,ed553366 +400,81280afd +401,41887830 +402,6b3173ac +403,60fbd4ed +404,2be4360e +405,b19d796a +406,3f9e217a +407,92644c98 +408,885a28ca +409,9a7c5a83 +410,3310ce9c +411,8f647e49 +412,406b0478 +413,459b5adb +414,6c073515 +415,54d6f20f +416,dd85eec6 +417,b9e42a33 +418,e8bd622c +419,561d2c6a +420,8f31e887 +421,56d35d73 +422,fa5db6d5 +423,ffcdc9c0 +424,35b7f0f4 +425,931e2fe3 +426,10948372 +427,3fda5439 +428,f25ffbb5 +429,2143cf56 +430,510842a7 +431,f49cf470 +432,e66e0138 +433,d85d5745 +434,ebd65c26 +435,3c21b3a4 +436,a056556b +437,10e8352b +438,16ab7c29 +439,65242f89 +440,605c6969 +441,d6db1f9e +442,94c81b67 +443,319d62a5 +444,de18ddc3 +445,8f59cc00 +446,fa07d744 +447,a8b65f3a +448,dd7c0b4c +449,b4f66448 +450,1ebee589 +451,bf7e2197 +452,ed6a9364 +453,afb539f2 +454,0e1cf791 +455,737049a9 +456,acecc90e +457,ec6dac27 +458,07d3ec87 +459,d8e277b9 +460,b3c5b17c +461,8c17da7a +462,47acc588 +463,68401252 +464,ad1cb1c4 +465,82d6254e +466,a360db79 +467,5e32d3c2 +468,247649e3 +469,b194c76f +470,9c4678e8 +471,0c74a4a6 +472,5d1c1d65 +473,15b6ce0c +474,aa987d51 +475,92b0e224 +476,5154a398 +477,2e2d36f3 +478,8c5cb57d +479,e70df8aa +480,c6e0fbe5 +481,bd78e9b1 +482,5392deb4 +483,4f5491ef +484,4511f358 +485,039d50fc +486,be811784 +487,c56b2f4e +488,d320d555 +489,e47f1475 +490,b795cdc7 +491,3cb0b59c +492,ca86b1fe +493,28ab373f +494,cc8b70b8 +495,13da11ed +496,6c3ae50a +497,50399f5f +498,13b08214 +499,4d96eb40 +500,a0ab276d +501,bfba9485 +502,8318425b +503,500cfe95 +504,0e4af8e5 +505,773df1c4 +506,6763d3c3 +507,d105baa2 +508,acc6d182 +509,1f3de2cc +510,64303669 +511,ef01bc04 +512,1acd005b +513,dd10d855 +514,ef6fda05 +515,2280250c +516,6fc5537a +517,232d0ca8 +518,de78aa9e +519,877b55a3 +520,fe3f1a6e +521,a16c281f +522,54931c5d +523,ab0800f0 +524,0f935fa5 +525,172122cb +526,0c6a415d +527,8844a501 +528,787c9423 +529,34681262 +530,8a3897c7 +531,60afe409 +532,fe5f2795 +533,44c3bc8a +534,12a78c52 +535,2e6754e7 +536,6ac5b942 +537,9d83d1b4 +538,a6c43685 +539,c919ba5a +540,e1797e15 +541,a825b0d9 +542,91c6edfa +543,868fb2fe +544,ccf3c8ec +545,b0258ef5 +546,d73554ba +547,955fd585 +548,f2e19340 +549,b76df586 +550,46593514 +551,a8554ba9 +552,43855589 +553,fc2adadd +554,fd571fb6 +555,6dbd50ff +556,5d25c1cb +557,0d30d8fb +558,eef46f40 +559,d5319691 +560,dff453b3 +561,e473ca94 +562,d69f47aa +563,902633c7 +564,1fd9732a +565,7db10b4b +566,00be41fb +567,11737c8a +568,8fb5a6d5 +569,bad57631 +570,36bcdbce +571,6ae91d51 +572,ec39ad46 +573,7db9d758 +574,fb6b6007 +575,630bbde8 +576,168e9db5 +577,6566d7ec +578,69aa2e7e +579,040de2d6 +580,e815e6a9 +581,8bfad80a +582,4773fa7c +583,1aad04d5 +584,2c91e617 +585,9dffc14b +586,aa1c0bac +587,80e6cdad +588,7b33aa96 +589,10493744 +590,23a00450 +591,ea4a9000 +592,5fa14701 +593,eac82f2d +594,e09305ba +595,348cb9e0 +596,7da1a290 +597,502ef491 +598,5ea5449b +599,5ff303d8 +600,48be3e2d +601,24d9bb11 +602,b3322d14 +603,b92f413e +604,bab55031 +605,0c854afe +606,090e888a +607,d2653e3b +608,c0e823df +609,cff2413a +610,8e2ca887 +611,834c0976 +612,9684624d +613,9fa709ac +614,d635e49b +615,f7ebdb8b +616,afec8d0c +617,355f68d1 +618,008596fa +619,2cc2a12e +620,14d3332c +621,fa3dd385 +622,20c82fec +623,c4dda2ba +624,66144a73 +625,c91b6c4a +626,0ea36b0c +627,ffd1692a +628,1bba7e95 +629,0465be87 +630,a3855ddd +631,574f814e +632,24d2d7a7 +633,2448bf94 +634,16cd0f69 +635,51ef4a1d +636,0fae3c87 +637,1e564274 +638,f88cad8b +639,cbd60c5c +640,dbf1f1d3 +641,0811102f +642,6f20df66 +643,a3b18688 +644,93bfe756 +645,178c449e +646,9029dde9 +647,e8769b3a +648,271a6a8f +649,22dcdb68 +650,649c2d1d +651,30b5694c +652,5adb4698 +653,609f83c7 +654,c1e29d43 +655,b000f551 +656,82dad8a1 +657,f26608f2 +658,29582cba +659,0749d7a3 +660,09563fe3 +661,aea8b71c +662,79ad66c9 +663,b23a0f91 +664,f6fc4231 +665,b40c3c3d +666,86b746ec +667,be0e7fa6 +668,e66e4792 +669,219f7814 +670,f9a53fea +671,f114257a +672,ddf66880 +673,bc1e8221 +674,d3731c71 +675,a6ba1be7 +676,b559eb78 +677,4658574c +678,9c7fe9ef +679,4f9b8254 +680,5c1f65f5 +681,b771b052 +682,fa0e5e15 +683,3adac332 +684,272cf6c0 +685,0ec8cbdb +686,d72890f3 +687,f8dd076d +688,3928a1ba +689,dbbaef68 +690,ceb6601b +691,38a56aa0 +692,c3c0ff47 +693,db639585 +694,e4032569 +695,1b981e39 +696,ca1fcfa9 +697,c79ed5eb +698,c45db9c8 +699,299cd299 +700,fbdf2c41 +701,e10859e1 +702,0fb171f0 +703,50c9f268 +704,51507b72 +705,438a40e6 +706,68ed143d +707,8759f884 +708,f321d557 +709,08e78177 +710,052d475f +711,b3425f23 +712,21b7e756 +713,e82b4097 +714,3d7e25e5 +715,85f71e58 +716,51fc5e2d +717,e53a7cc3 +718,04f60598 +719,b6718890 +720,b181b86c +721,e605c72b +722,48b9af08 +723,e2a3cb44 +724,0377deac +725,0c4b1e9e +726,86b5798a +727,b514f216 +728,f16a13eb +729,0ed08c1d +730,bdc090fa +731,5ffed383 +732,c3716570 +733,468d8553 +734,94483253 +735,bcf7b6bd +736,2878172f +737,bbe7dc82 +738,9d2dc2e0 +739,972ad6e9 +740,90d981df +741,f22fbab8 +742,b0a34663 +743,a8334c43 +744,74efd3dd +745,903f2983 +746,afd54f8a +747,84ae50b7 +748,f1aff2eb +749,108d4237 +750,eaacc752 +751,675edc5d +752,304dc122 +753,f7f55fa1 +754,026016b7 +755,5b7e53ba +756,ee2dbc19 +757,c7dce83d +758,e6c26cc6 +759,0d41fffe +760,53ad8cd2 +761,12e02fba +762,bf609cc0 +763,53113984 +764,ea87e94b +765,a6907225 +766,16d14699 +767,5047c415 +768,785f7ca7 +769,9b14f4ec +770,4075b235 +771,5580ce5f +772,96dfce82 +773,73d008e6 +774,811f3cd7 +775,e787b491 +776,f9127f35 +777,7f28d9f3 +778,2aae4a7d +779,594f17cf +780,37de931f +781,93fd3f05 +782,fd656d7e +783,104127d3 +784,aa0fd75f +785,5eb91fa1 +786,f1d0b937 +787,e9fb6737 +788,58169891 +789,b48ec2ed +790,ed1c5f0c +791,dba96475 +792,2246707b +793,cea5b8b4 +794,f3bee338 +795,4aafc790 +796,2b8390fd +797,685a145c +798,2d496f39 +799,9367d633 +800,44ffc03b +801,c607407e +802,7e3ae111 +803,47b47bc2 +804,261b6c02 +805,1ccecffb +806,a249293d +807,099f0514 +808,9bb4d412 +809,0110cc97 +810,96588bdc +811,0d75df7d +812,c307545d +813,899f4bf9 +814,79ac283f +815,ffe6feca +816,1fb3907e +817,1f126b58 +818,026e0f91 +819,29686785 +820,33da1c21 +821,9cc8a101 +822,0b5fab60 +823,c3cc5873 +824,7e6ac2cc +825,f41880c3 +826,e7c4c343 +827,434eb267 +828,562da9c5 +829,b8be1609 +830,7ce9b6e6 +831,6c52bbb6 +832,6641002f +833,b92c5f33 +834,14b802c6 +835,caaeabe8 +836,05b15562 +837,f799684a +838,13645b7b +839,b8f8490e +840,bac8d326 +841,f90bb6bf +842,5b7d7d9e +843,0cf58238 +844,ac08a75d +845,e9b28f40 +846,19a058a4 +847,7c1bfdce +848,43a971f5 +849,81e9773a +850,8b9c8779 +851,6e2f14f8 +852,48bbd4c4 +853,2586c597 +854,530b2f99 +855,4825ea5d +856,e188770a +857,3cfb384a +858,9c8348c6 +859,258d2a6d +860,096ee594 +861,3cd4090c +862,10352596 +863,33e0295d +864,2ef14246 +865,95957ef6 +866,bc1f5581 +867,d51d60d5 +868,b431e5ad +869,c3f81c72 +870,e45c3e24 +871,fdaa22f3 +872,e83e802b +873,3685a78a +874,26cc23ed +875,d72307c1 +876,1ffe4892 +877,c85cda0c +878,c3d39028 +879,99d4e123 +880,c3b9bae6 +881,1265d95d +882,01a70845 +883,032de0bf +884,bc003e96 +885,c1f6bb5d +886,58bbe475 +887,049f5f4f +888,358db367 +889,ad657e49 +890,b7f26ce4 +891,43582165 +892,e87c7023 +893,d4b1a1c2 +894,9fc251c6 +895,f530e24f +896,20a2490d +897,5835f64b +898,6805dbee +899,9ea79c6e +900,9c315626 +901,016c5909 +902,c0062262 +903,a1394a81 +904,d549d2d5 +905,f692f9bd +906,e9098404 +907,6283a3ee +908,c7392143 +909,39998aca +910,87a7a29a +911,2a7f70fe +912,cd48f790 +913,d996bfde +914,4558a886 +915,198048ae +916,38ba18c5 +917,01ef2bfb +918,85079bff +919,b89453e1 +920,f07fd215 +921,95bc9819 +922,63f0a60e +923,c52eb1f9 +924,0deba6b3 +925,7a7d3757 +926,a2c86d2e +927,343052d4 +928,46fee238 +929,768c4720 +930,d45c322f +931,b005e84e +932,dd78095d +933,4af8a4bd +934,071a0303 +935,c95b7edc +936,2893dd80 +937,f4d84a5f +938,a46424a5 +939,2d2fefbd +940,faaaaca9 +941,3356dd8d +942,d8b2fd7e +943,76989056 +944,7b84a9e1 +945,b46f8772 +946,117a6860 +947,2ff913ea +948,cf1b907f +949,5dbda40a +950,90f5b03d +951,aa6e0347 +952,b2d96aa4 +953,daa344ff +954,275cbfad +955,8b40c6d3 +956,9fa00d08 +957,ed2e80b6 +958,533f33b1 +959,b9987fc2 +960,22aefa9e +961,ab8ecb74 +962,19226d7b +963,9fe03ffa +964,92941026 +965,fb0ece70 +966,de9d716a +967,9f9bde9d +968,76c893d6 +969,88cf3551 +970,65462844 +971,bbd27244 +972,27ac3115 +973,c32258a7 +974,13e67ea9 +975,54293ba9 +976,06177aa3 +977,98eb7035 +978,d94d07fb +979,2687a969 +980,28b3a17f +981,f57f12dd +982,82c3b2a7 +983,2d44c726 +984,19d30ba0 +985,96910f30 +986,47344456 +987,36af196c +988,c958be9d +989,68712853 +990,95dcb848 +991,8124e68a +992,102763be +993,374c4390 +994,cb7a270d +995,2565c23f +996,b38c72d0 +997,b5d0921d +998,dcf18fed +999,2dc477fd +1000,408e0443 +1001,f41d5bc2 +1002,b06941eb +1003,86f3acfe +1004,874a012f +1005,bd9c3a2a +1006,f4f96001 +1007,d9e73dc2 +1008,4486488e +1009,288f2520 +1010,3264d15a +1011,bacfe29c +1012,5c284435 +1013,4af4a858 +1014,9e50fbf2 +1015,c22a33b9 +1016,6ae6813c +1017,b560598e +1018,268cc57d +1019,8964440c +1020,6f9b09f8 +1021,a17130b7 +1022,fa5f9def +1023,3e3d4db5 +1024,485ea2a1 +1025,8074b062 +1026,94323045 +1027,4b8018f6 +1028,6cc81deb +1029,62915d8a +1030,6bf375a4 +1031,3bfadfef +1032,59c167c1 +1033,0e25337e +1034,ad2ee21a +1035,ca20b58f +1036,ce49c75f +1037,c2acbbf4 +1038,a47410c4 +1039,c85f2f5a +1040,87af52f9 +1041,00105891 +1042,d3466f8e +1043,98c22e48 +1044,e6a39394 +1045,8ab30c30 +1046,7a12078c +1047,b4ec56e4 +1048,9d27a5e9 +1049,93d5e446 +1050,acbefa89 +1051,2fb6eee2 +1052,73d414c6 +1053,e46d301e +1054,88064ee1 +1055,75c71fdf +1056,805fb058 +1057,bf5279a8 +1058,64cb510a +1059,9b0bedb9 +1060,97b49d2f +1061,45436e56 +1062,f01a6e01 +1063,1df68156 +1064,fa46689b +1065,e6fae616 +1066,b22d9b66 +1067,34e83663 +1068,1885bc2e +1069,02648d46 +1070,8ccc1690 +1071,f27621da +1072,5c03d59b +1073,77aa5a8a +1074,747fa5b5 +1075,5c242e92 +1076,6d305e3e +1077,16cd11fb +1078,830ae0ac +1079,0e17ca94 +1080,0fe4c809 +1081,58b4639e +1082,386df645 +1083,6a910286 +1084,71a36299 +1085,3bbeb93e +1086,602023f2 +1087,af3a0866 +1088,151f4f7d +1089,127823e6 +1090,63f87535 +1091,630facea +1092,d4bb8b66 +1093,7ab7498a +1094,fdf8b46c +1095,85d13534 +1096,3d58b0a6 +1097,c0db7eae +1098,c69866f3 +1099,64256e0c +1100,24f302fb +1101,535ca958 +1102,4321bf45 +1103,cbc8a1f8 +1104,2e98b553 +1105,11fa425d +1106,c907640b +1107,d8798632 +1108,310172a6 +1109,80b76eac +1110,9aa4e55a +1111,fc5b234d +1112,ff329b8d +1113,0b13d651 +1114,fcd6e73c +1115,1fd74f5e +1116,5e43eaf1 +1117,0416ce4a +1118,e73f0079 +1119,82c86f27 +1120,4a185d00 +1121,4e38cd6f +1122,15d7f893 +1123,8c577909 +1124,7ebb0e92 +1125,9b156bcc +1126,0a8f1dd6 +1127,d84bcabe +1128,a7663781 +1129,e6980745 +1130,79795819 +1131,49e3156a +1132,39d4bef4 +1133,02271761 +1134,55a4f718 +1135,379f547b +1136,9468e8ac +1137,a98a017a +1138,57f22f37 +1139,83fe52dd +1140,55f40b11 +1141,1b409773 +1142,6a0a78fd +1143,268b7c7e +1144,b96b193d +1145,7bbcd50b +1146,284eb0fe +1147,17caa411 +1148,479d6dd3 +1149,0bbca53c +1150,ad083341 +1151,b99cff38 +1152,ea532ce5 +1153,1b06037e +1154,69563e31 +1155,ddda6fae +1156,3a06ec36 +1157,93e9aeab +1158,fb11fb14 +1159,2bc16f21 +1160,dea7a7c3 +1161,a5e00c80 +1162,f54970fd +1163,12670d74 +1164,e09ae40d +1165,bb67f368 +1166,ea7cda74 +1167,0ab31e42 +1168,d7dd57ee +1169,ac400cf9 +1170,85cfbe6b +1171,56d63814 +1172,b75bf210 +1173,8db9336f +1174,d35d7ec7 +1175,6e0355b9 +1176,78e3fbe2 +1177,3ad9cd33 +1178,bc77c836 +1179,15d4eed1 +1180,932d55a0 +1181,dce512b5 +1182,84be2abe +1183,07ebe3ba +1184,8805b4d9 +1185,d041d0dd +1186,688fd28c +1187,5b7185a5 +1188,7e8cbeea +1189,356299bf +1190,09063656 +1191,5b66e39e +1192,ac03372f +1193,58539a3d +1194,09c01889 +1195,e9e9ce54 +1196,2c7971d5 +1197,c967f5cf +1198,cebbb259 +1199,b8b91685 +1200,07fad1b9 +1201,52654049 +1202,8ed1044c +1203,00d4ab46 +1204,9bdaec61 +1205,d9e531b4 +1206,2a7d612c +1207,780611ab +1208,8927bb51 +1209,fe51e4a6 +1210,5aa0542f +1211,a7cf698d +1212,7d57972c +1213,473fad1c +1214,ddc3d8d6 +1215,a067a82a +1216,180da36c +1217,b5b8909c +1218,9ca350d0 +1219,d33e9ec8 +1220,41348d67 +1221,23052ea1 +1222,72eb34da +1223,0b1ea2b4 +1224,32bf737d +1225,fd348b03 +1226,c6f3416b +1227,4e435046 +1228,6188b3f7 +1229,f83dc13f +1230,fcb3e092 +1231,6ec0024f +1232,e6f2fdbd +1233,a788612f +1234,c15947e6 +1235,ea0890df +1236,d2f69968 +1237,c3914fb0 +1238,fc50f5fb +1239,91fff895 +1240,0d7784d4 +1241,a1a18ac7 +1242,9eee2b18 +1243,811ef486 +1244,ab26f02e +1245,baa98936 +1246,2cb69c56 +1247,97cda697 +1248,b4459286 +1249,c9f7c87d +1250,0570e3b3 +1251,253da08e +1252,a4ebeb37 +1253,aa9163f7 +1254,29852494 +1255,c68f8b84 +1256,0d46344b +1257,002ce6b5 +1258,05c0ac6e +1259,e128343e +1260,0d6af4bf +1261,08e0522b +1262,181940b7 +1263,2c301a02 +1264,4269a40e +1265,5765d4c6 +1266,34e0f562 +1267,1b1ff923 +1268,6828ddae +1269,991be08d +1270,cc564183 +1271,42ddde09 +1272,8a153bba +1273,23d593a0 +1274,8119ba57 +1275,b997b58b +1276,a865c944 +1277,efa0645d +1278,e3ca55f2 +1279,40afd4b1 +1280,a0712dfc +1281,7ef66a4c +1282,ba1630eb +1283,355b1d47 +1284,390adecd +1285,32f2d976 +1286,3c78a7f8 +1287,93153ff0 +1288,f9026cf6 +1289,2eab02cb +1290,adb7bb3a +1291,5cd7a3b8 +1292,83e98317 +1293,8dc9bb0a +1294,2e40f352 +1295,1c890b50 +1296,5426cc68 +1297,ebab61e2 +1298,c342369d +1299,e267bf28 +1300,1d90996a +1301,ea7c2a27 +1302,d78fe144 +1303,11d1c945 +1304,f1dcafe4 +1305,d8bdb34e +1306,80ed427e +1307,6fc5c5b7 +1308,ce610b90 +1309,99985e45 +1310,8e6d6dea +1311,2bf349d9 +1312,e917cc0f +1313,34c91c7f +1314,ae548aa9 +1315,1fe4d3b5 +1316,b6f2b0e4 +1317,ad47c826 +1318,e52aa4da +1319,d300f4c0 +1320,3afedb62 +1321,46081c15 +1322,94f24c6a +1323,04ce9d0b +1324,cea8afe0 +1325,d4d7e596 +1326,8431b1a9 +1327,fbd531e4 +1328,5fdbe956 +1329,c2a79a51 +1330,f7047c15 +1331,8b29b6d5 +1332,0536f7da +1333,c44175f2 +1334,d57a4b95 +1335,fb4d52d7 +1336,d02bd3f5 +1337,bfe64b3e +1338,8c1c08d3 +1339,0d78bbaf +1340,ae125056 +1341,13943695 +1342,6b4d676e +1343,f9164417 +1344,918620ae +1345,a9cd180d +1346,440710d2 +1347,ed96ebd4 +1348,05aecce2 +1349,9d0173a8 +1350,35952eba +1351,66c3ddf4 +1352,c2db12b8 +1353,acfb1a9e +1354,bc1415b2 +1355,de3115ca +1356,765e2528 +1357,26b1f5e2 +1358,9f7576a4 +1359,eb05a2ed +1360,f212623c +1361,6966482b +1362,e03fb916 +1363,7af1194d +1364,449238ac +1365,14ebf429 +1366,36ef16a1 +1367,11c71c9e +1368,222d8c54 +1369,4d0e117e +1370,3b506427 +1371,ee861c11 +1372,3a8d1725 +1373,38f916d6 +1374,35c00746 +1375,2a2e9228 +1376,5a7379c1 +1377,0dda66aa +1378,8641665a +1379,85f51f90 +1380,c90ef3f6 +1381,8207d5fe +1382,e9da8e64 +1383,6a245b37 +1384,1baf3d35 +1385,5c8d3417 +1386,c681ea6a +1387,c558a5cf +1388,5b3df141 +1389,433da007 +1390,bc53e774 +1391,84e43256 +1392,fca912d3 +1393,8263ad44 +1394,68e1d04a +1395,4d8dccca +1396,03101c60 +1397,b24e4aed +1398,202a533f +1399,091eeecf +1400,7f0dd925 +1401,613192aa +1402,1d5ce20b +1403,9bdd3aef +1404,65951b38 +1405,6ce48a79 +1406,56a58d8b +1407,a88f6fce +1408,4c31a46f +1409,87edb889 +1410,d35ca6da +1411,6048634c +1412,3e15fc5c +1413,2b3dc491 +1414,6115b5bd +1415,98c526c2 +1416,89ed40aa +1417,91374da5 +1418,826e75b9 +1419,3e780dae +1420,ed653ad0 +1421,f0940a80 +1422,bbe0bab9 +1423,925c763f +1424,3ffaa104 +1425,5982f511 +1426,119169d6 +1427,976720ce +1428,191745c7 +1429,38ee5741 +1430,2fc4c248 +1431,68c88a9a +1432,fac2a079 +1433,86c2cd4c +1434,cb65e6f6 +1435,e0fee648 +1436,fcd3c42c +1437,2e917f5a +1438,0bb5565b +1439,6c92466a +1440,c08e6f73 +1441,427cb2f3 +1442,11cba553 +1443,11eaff89 +1444,36bc88a3 +1445,0b6fc746 +1446,5be3b08a +1447,9f691033 +1448,57ac42c6 +1449,3b41cdb4 +1450,9d7c2c33 +1451,28a981fa +1452,37a10f1c +1453,3b98ad46 +1454,b86d17b6 +1455,69cc84e1 +1456,dbdef471 +1457,2bf9f46d +1458,c8daaf58 +1459,70502b65 +1460,6f8e70d2 +1461,3dcf4b91 +1462,84825ef4 +1463,fa939150 +1464,641d7bcf +1465,6e80250f +1466,56da0728 +1467,5d2dafe2 +1468,d9fc8ba4 +1469,02c0a1be +1470,16117e2b +1471,e77f42ff +1472,00582768 +1473,61211d67 +1474,8d678d17 +1475,afdcc242 +1476,f0cb275c +1477,0dc53a4a +1478,7b660ea8 +1479,82c2c871 +1480,4146ee07 +1481,c448df51 +1482,355a4b1c +1483,93a0a2fd +1484,0aa2151a +1485,0cfdb160 +1486,b438dd31 +1487,fec0cf19 +1488,583c495e +1489,7adb07d2 +1490,f002235e +1491,cb882caf +1492,538f59f0 +1493,19aa246a +1494,33485acd +1495,b5793cd0 +1496,d36effdc +1497,f4de731c +1498,138060d5 +1499,f7178b78 +1500,96fa9094 +1501,7bde7e80 +1502,16656015 +1503,eafc4cb3 +1504,a877be19 +1505,f8083981 +1506,d56a6fcb +1507,a2186da9 +1508,f81dd26d +1509,d7bdefbe +1510,8622e2db +1511,8b4d4cda +1512,082f3988 +1513,b656ffe1 +1514,f406a51e +1515,dee62c8a +1516,f5f76ae3 +1517,5420fff3 +1518,5821ac77 +1519,a9246445 +1520,c02c137b +1521,e594909a +1522,e7966d70 +1523,2ef25e9a +1524,783ddcdb +1525,187a511b +1526,fe8c4de8 +1527,1db3fe7d +1528,3b2a9b3c +1529,ffdaf5d0 +1530,077daf48 +1531,7aae5f98 +1532,aaf00c20 +1533,c3e83ced +1534,2f2cb135 +1535,e4bdd20e +1536,d3b28ea0 +1537,1d866d23 +1538,f2199608 +1539,4aeaa33c +1540,0e90d41d +1541,e51d3bd0 +1542,124cf012 +1543,3a11d375 +1544,94e8497b +1545,d5f32fbd +1546,78d0950b +1547,3f675687 +1548,05a43f7e +1549,58dfe2c1 +1550,99500aaf +1551,56a75ea5 +1552,3aaac71e +1553,5b8e15e6 +1554,c0465281 +1555,0a9ded5c +1556,5b7f6533 +1557,b3786a06 +1558,1109fe26 +1559,d1fa5a17 +1560,5223a4ba +1561,cfe3a75c +1562,b9105568 +1563,e5d9b061 +1564,e7e46742 +1565,c9943e0b +1566,89b959c0 +1567,f4683114 +1568,e8ff4f4c +1569,e0c8341e +1570,a5a0db62 +1571,c021bdc3 +1572,7556a939 +1573,84a684d2 +1574,dd70f158 +1575,ece8c92a +1576,6815fa1b +1577,9d5830b5 +1578,9550d114 +1579,60263f11 +1580,a11dc6f7 +1581,31a9831e +1582,df11d5ad +1583,14df6c2e +1584,3e6202df +1585,7d3f307b +1586,4484758c +1587,d99b0db7 +1588,bb1d3105 +1589,a0bfa936 +1590,c2455ee1 +1591,f440959d +1592,5547425c +1593,4dea06a7 +1594,60cd7dc8 +1595,90f4afff +1596,2b686bf6 +1597,b883b569 +1598,36bf540c +1599,f5068325 +1600,f850191a +1601,025904fd +1602,ced688e7 +1603,d7cf62fb +1604,a3cf8268 +1605,e1008733 +1606,8643a9ea +1607,69d58b86 +1608,55adcf3d +1609,65913799 +1610,d2465c03 +1611,a830f2d2 +1612,793f02eb +1613,1e2cece1 +1614,09889a0a +1615,812dc1f4 +1616,899ee344 +1617,31f76286 +1618,3d22b4df +1619,684a823a +1620,e0f55a8a +1621,c99daefa +1622,7b1f0b5a +1623,e0a8fc1a +1624,ac1ccbbe +1625,2a853d9e +1626,a56d56ef +1627,756348fb +1628,09ffaa1e +1629,14b3f359 +1630,ca5317c9 +1631,71c72c9d +1632,bf912626 +1633,1661f002 +1634,aac8fccc +1635,3a154dc3 +1636,11b70af3 +1637,761f26b0 +1638,9f2885dc +1639,de6f647d +1640,8ad535c8 +1641,b6038508 +1642,8c8d65f8 +1643,830a7053 +1644,d3914e1d +1645,ecdd1d6e +1646,f992a3c0 +1647,ac416992 +1648,8d0397ac +1649,83109f3c +1650,a99ca0d3 +1651,80bfab29 +1652,936d14c4 +1653,af8643da +1654,ab42c29c +1655,2a252c19 +1656,7a3e1afd +1657,068ff650 +1658,ebf92c9d +1659,dca7b40d +1660,0ddabc90 +1661,ee4525a2 +1662,5aebd4da +1663,464853e6 +1664,73143ceb +1665,eb00f482 +1666,a2f756c7 +1667,d8ae7e99 +1668,cd8314e7 +1669,780ac064 +1670,a66269a1 +1671,e262cbf4 +1672,c3d71a1b +1673,4da112dd +1674,5009e56d +1675,6e59f95d +1676,b7a4c897 +1677,eef51a63 +1678,1371623a +1679,2c63cb22 +1680,38c17c20 +1681,dfd81d57 +1682,b181ce91 +1683,347446fe +1684,a797f4fd +1685,1c1c7a3b +1686,daa18d51 +1687,a3936774 +1688,19a64678 +1689,35d2f5b7 +1690,f4610d2e +1691,0c3877a8 +1692,6bf77826 +1693,006ba82b +1694,c20c66ee +1695,35f0ded8 +1696,0530a355 +1697,ae7e9226 +1698,596320b6 +1699,9cf873b2 +1700,f528886c +1701,888bd28b +1702,f012a8e8 +1703,2af25dfa +1704,94880430 +1705,fa8c9ed9 +1706,2459e1a2 +1707,5c3b7989 +1708,0551de95 +1709,09f6ff20 +1710,9aa04e3d +1711,b33e48bb +1712,dfc78b6b +1713,2688f134 +1714,dd771d27 +1715,3d6a661f +1716,3974586d +1717,0c8aef88 +1718,43b21234 +1719,10d41be7 +1720,abdebc9e +1721,f667d98c +1722,c9a14e22 +1723,d0381e3b +1724,55c47898 +1725,6e217dd8 +1726,1d610ee7 +1727,a92fff93 +1728,6cd88da4 +1729,90984e46 +1730,b4d5cece +1731,46a580cd +1732,d6ebbd63 +1733,8ebf544e +1734,75f7cfdc +1735,76cac2e2 +1736,ed0b5d01 +1737,9ac306cb +1738,c713f394 +1739,031b9857 +1740,cb62847c +1741,590c97be +1742,cd25b088 +1743,8499748a +1744,48b60ba0 +1745,9fe96784 +1746,1b0bcca9 +1747,be4f6714 +1748,2634f61b +1749,4a0f9512 +1750,810d04e0 +1751,747002d0 +1752,56e1b79f +1753,d89d5f65 +1754,e01374cf +1755,184a53cb +1756,06c65df1 +1757,1caa2391 +1758,69ccee2b +1759,0c5fe183 +1760,5a934173 +1761,cdb3d571 +1762,70faf17b +1763,3fcacf09 +1764,4951f883 +1765,d7923314 +1766,fae97ca6 +1767,89baf52c +1768,41fb7702 +1769,7aa68e3b +1770,e62886be +1771,a14d187d +1772,43f41de3 +1773,91c7b7e4 +1774,68139935 +1775,25d22e84 +1776,f0d238a9 +1777,4d84cf50 +1778,edcc9f48 +1779,8f6ba96b +1780,9743d47a +1781,f25b6ac1 +1782,95c357ba +1783,1d08b6c8 +1784,f2b4765f +1785,72cf2b42 +1786,87aa9249 +1787,95f8f304 +1788,ce115cba +1789,68320c15 +1790,317f8770 +1791,54cd203e +1792,990ccb08 +1793,5f78ee6a +1794,ede45895 +1795,b517fb4f +1796,8da2e78b +1797,f071f56c +1798,7ef0776a +1799,bb8a8c96 +1800,3f9fcb2f +1801,2517f9da +1802,7077fe83 +1803,7ef670c1 +1804,872366c5 +1805,89f30ce5 +1806,404a2824 +1807,a3177396 +1808,bfdb71ab +1809,375385d2 +1810,a757709c +1811,d1255586 +1812,9de96536 +1813,751e0a45 +1814,7213a5ed +1815,f3cbe5df +1816,a088b7bd +1817,f4a0be77 +1818,cad101fb +1819,2769ef8a +1820,0b7487a9 +1821,09fca74a +1822,00a02341 +1823,3e7a9d1d +1824,07a25234 +1825,9ca33e3a +1826,ec40425d +1827,e733b0a3 +1828,b140631f +1829,05daa9af +1830,711a9e95 +1831,59aa290b +1832,8fc3002e +1833,7127dc29 +1834,97c3b663 +1835,43fddb37 +1836,3ccaec4a +1837,8a43f963 +1838,976caee8 +1839,322c84ad +1840,6fe8e592 +1841,703cf887 +1842,78e597d5 +1843,5cb51ccd +1844,59ab68e7 +1845,92365750 +1846,56542f7b +1847,f38c2c83 +1848,e0784bb1 +1849,a5613ea9 +1850,dee0ceb4 +1851,be17dc42 +1852,1dab781c +1853,96f940c8 +1854,e4135218 +1855,38878e3a +1856,4a1268a8 +1857,61e49437 +1858,39498e9c +1859,d6d6dc4a +1860,ee477a3b +1861,68de189d +1862,479f86a6 +1863,43b53adc +1864,1da01c0c +1865,2003df5f +1866,a16fc6de +1867,82b0867f +1868,b10db2bc +1869,552965d9 +1870,9ffd9c78 +1871,38207dca +1872,4df285ce +1873,89ab5eb2 +1874,360cc68b +1875,a6d6956e +1876,ef0a0645 +1877,33509e21 +1878,6702c7aa +1879,f8fdb215 +1880,e5313883 +1881,ce518ae6 +1882,58adc092 +1883,4169db7c +1884,3b4e2f8e +1885,62d71047 +1886,2a3e445d +1887,f590fea0 +1888,93a05658 +1889,b19a9c20 +1890,1e6f621c +1891,b3deaf05 +1892,65df7bf1 +1893,3057c871 +1894,68aab1e8 +1895,f650f192 +1896,2e51c844 +1897,019a7b23 +1898,54954463 +1899,57b0141d +1900,b340b6f2 +1901,76aad1ba +1902,4942d2ca +1903,5d1da04e +1904,557a26c4 +1905,191437fd +1906,d567a839 +1907,80476a4d +1908,31e3b50e +1909,887d35fd +1910,efce647b +1911,41a4bf4e +1912,272a2a8f +1913,4aee96db +1914,eee54cd3 +1915,6ea2d3d5 +1916,08c7aeaf +1917,86f292ce +1918,52646cb3 +1919,2f997ec8 +1920,876fcb05 +1921,14b5389a +1922,4a1992cd +1923,ed052052 +1924,6c74d2e9 +1925,12888478 +1926,6d8c5204 +1927,25bcdd88 +1928,adb744fc +1929,989f024a +1930,6cc05682 +1931,67f70e2a +1932,7f4b6148 +1933,0f9f0ebc +1934,bc293692 +1935,a7638b08 +1936,0a76b8ec +1937,1de81739 +1938,e272803b +1939,8ece1803 +1940,597c542a +1941,f39509df +1942,baca3ac7 +1943,d5519671 +1944,8d9c20d1 +1945,7a0d43f0 +1946,76910ef8 +1947,768d81f1 +1948,a6fdbeca +1949,fe86ab51 +1950,e58dd896 +1951,014a9b03 +1952,56c63326 +1953,fc1c5825 +1954,bac89ef7 +1955,d2dcc8fd +1956,6fdc41da +1957,19b14fe0 +1958,660e17e2 +1959,c08d0a60 +1960,1a5137b0 +1961,9dcc3a9e +1962,6d068390 +1963,551e4619 +1964,32979186 +1965,d6ccc558 +1966,0821a7ab +1967,db61d288 +1968,20460b61 +1969,43eedf7f +1970,79e8385d +1971,0d05fccd +1972,dbc97e71 +1973,5dcd29ae +1974,fac17532 +1975,c4449980 +1976,cb11daa1 +1977,1764d9b8 +1978,9218da34 +1979,27ad8020 +1980,48f62e37 +1981,95ee0aea +1982,2f11d53f +1983,589a7eda +1984,1724621d +1985,b643e1f0 +1986,e41f78d5 +1987,8cdce972 +1988,37ca46b2 +1989,e36b0b9a +1990,6f91ad46 +1991,8528d536 +1992,4f438ae8 +1993,1f9a4d89 +1994,ac66b375 +1995,0ab49ecd +1996,a5314fdf +1997,c7b8df44 +1998,6dc65821 +1999,9578392d +2000,e306bfe7 +2001,e73677e1 +2002,4f663791 +2003,7fa7ca8d +2004,522d03dc +2005,8a101c71 +2006,1b48bc86 +2007,d500b04c +2008,dc8a4f7b +2009,947ef858 +2010,9750da45 +2011,95a60a94 +2012,2cb96752 +2013,81c187ee +2014,897d6cf7 +2015,0143f50b +2016,1859a6b1 +2017,44d3974b +2018,cdc2cb94 +2019,d51c3fc6 +2020,cd6d2833 +2021,fa4e3fe7 +2022,536898ef +2023,9922370d +2024,29319624 +2025,ee915194 +2026,991b2d5a +2027,a6118c14 +2028,8831027e +2029,26479e11 +2030,db7f7ecb +2031,26c6a720 +2032,c343c280 +2033,141c3942 +2034,a00372bd +2035,4dcb14b7 +2036,254bcd4c +2037,6306eca9 +2038,bbe09892 +2039,aa6ac576 +2040,c9e863e0 +2041,6d91c3c9 +2042,aeb801e3 +2043,f55ea79e +2044,33fba799 +2045,8ba64725 +2046,30a25dce +2047,08642076 +2048,1957c855 +2049,d54f9eb0 +2050,9e580906 +2051,6df74863 +2052,e7819657 +2053,7e053e6b +2054,ce16e673 +2055,e807d015 +2056,e2aeea60 +2057,e11d2df3 +2058,9df7989f +2059,5c34b4af +2060,77974861 +2061,256503ab +2062,5342ec9f +2063,8d281a6a +2064,b921a656 +2065,d302d8c4 +2066,cc8d61c8 +2067,a39cdef5 +2068,25f3141d +2069,8dec7ae3 +2070,343dc4a3 +2071,658ca039 +2072,6bcf9eba +2073,655521a4 +2074,b00dd8b9 +2075,707d05e7 +2076,1d4daf71 +2077,56f90173 +2078,7455aaaa +2079,8b6db66d +2080,44453fbc +2081,e03102af +2082,80e6ccc3 +2083,60fa7921 +2084,2eb77848 +2085,75626c43 +2086,70c539bb +2087,481810e0 +2088,c36b6885 +2089,aa873502 +2090,0f6b0cdc +2091,d7f65998 +2092,b84fef41 +2093,8c95ec24 +2094,bbf3f88d +2095,a8bd69ef +2096,da3079c4 +2097,5a725488 +2098,640eaad1 +2099,3c18650c +2100,0255e073 +2101,f431f234 +2102,52fd2d83 +2103,41717fc9 +2104,0694037f +2105,22d36a94 +2106,d5e213b6 +2107,06873da5 +2108,61487764 +2109,1ea58672 +2110,c39e2fae +2111,08f7e3e7 +2112,967fb151 +2113,74c17b56 +2114,7b2d4f15 +2115,41fc7d6b +2116,20a32f35 +2117,a76ffc27 +2118,d5f0f6bd +2119,68087d11 +2120,099fb97d +2121,65b70956 +2122,a3ccd27a +2123,586e862c +2124,8317d1a3 +2125,4bd382f7 +2126,52b1e390 +2127,85f1db6f +2128,36332167 +2129,75678469 +2130,493757bc +2131,5adeacc7 +2132,f217a7d2 +2133,950236ae +2134,96916abc +2135,7529b77c +2136,8f7d8057 +2137,7c11de21 +2138,2c00c0c0 +2139,41823325 +2140,52b4f376 +2141,b517a30e +2142,4a0372d2 +2143,57fb81db +2144,4064f040 +2145,71768ba8 +2146,7b0b54f7 +2147,037d58a1 +2148,11650ca3 +2149,0606f687 +2150,eb103c9a +2151,ca8484e3 +2152,c7face3a +2153,5c86a19f +2154,8cf9121b +2155,970d63b5 +2156,81bd2d95 +2157,aaed217c +2158,867984f7 +2159,491164b5 +2160,51374137 +2161,17fa7f87 +2162,515059e5 +2163,4878bc01 +2164,4868149d +2165,de3b0228 +2166,e522b8c4 +2167,5aaee9be +2168,83b57b96 +2169,67031a56 +2170,fcd6e3d4 +2171,41478528 +2172,744e037c +2173,b67460ba +2174,dd4c421c +2175,e10ed78f +2176,25520517 +2177,266df8b9 +2178,74e126e7 +2179,95359373 +2180,f567c216 +2181,7002d2b9 +2182,849ddf82 +2183,17ed011a +2184,594c1b2f +2185,5c7f8e1e +2186,5ba97ace +2187,4ce92a73 +2188,25f5dd59 +2189,f2d497df +2190,3f4e0b1b +2191,0b352567 +2192,6537f37d +2193,278aaf37 +2194,4f1c7cea +2195,ede6e1f0 +2196,7e6a8fb5 +2197,1963392a +2198,4b7a0a81 +2199,c48a5b47 +2200,40f607ac +2201,8bd1fd57 +2202,f86f562f +2203,6d0a26a3 +2204,ac634b57 +2205,8ecd02eb +2206,71a73f3e +2207,3313fd58 +2208,10a8079c +2209,613776c3 +2210,095b7ee8 +2211,e454b5c0 +2212,6b7373eb +2213,446ce812 +2214,20b4e345 +2215,f7953cb9 +2216,5059f202 +2217,1c7a8b7f +2218,3a9a6e99 +2219,99597a4c +2220,470912c0 +2221,6b0b3a7e +2222,9f6aa765 +2223,b90ff928 +2224,c570cce9 +2225,1ff49b2d +2226,356219c9 +2227,22e0518d +2228,47a5735b +2229,8e7a28ec +2230,f47bc225 +2231,f7c2b7cf +2232,f2a562e2 +2233,486464d1 +2234,e063340c +2235,5a130825 +2236,845b9208 +2237,c7fee4d8 +2238,116bc47a +2239,3dc0b935 +2240,c1dea1df +2241,b4e99991 +2242,96d2cdaa +2243,3b7ddc6b +2244,9a986d7e +2245,3fe9ef49 +2246,ddd918a0 +2247,f97ecfdb +2248,05b7674e +2249,80531213 +2250,42b89163 +2251,216b1af8 +2252,5c8e33b9 +2253,876fefaa +2254,48734a99 +2255,95e52c78 +2256,6dd44d03 +2257,26910f50 +2258,cf1b90aa +2259,83d6318e +2260,8241eb41 +2261,26c2be5d +2262,4164be2e +2263,4beefdec +2264,a2308fc9 +2265,fafc5064 +2266,40e96da6 +2267,72c77025 +2268,b1c18729 +2269,d0cc1841 +2270,c4b53ab9 +2271,a4364568 +2272,75c27179 +2273,40eba0ad +2274,0c6982ec +2275,5da07212 +2276,0f801355 +2277,e2c126b4 +2278,cfba5f26 +2279,42cdd1b3 +2280,c2b46674 +2281,cbb70da9 +2282,5bbe6c7c +2283,9d655f89 +2284,3f4d3b12 +2285,8ab6a2f3 +2286,cd8cbcd5 +2287,843da4c2 +2288,2fa21ba9 +2289,ed5d38b3 +2290,4808665c +2291,f77d70fb +2292,d31ee5a9 +2293,79d066ff +2294,07c3ff04 +2295,f2ce0975 +2296,06e911eb +2297,465aec0c +2298,3a8c00c4 +2299,e237806c +2300,c5d2323d +2301,fdddb7fc +2302,7cf671bd +2303,6ff3045b +2304,153ad2ab +2305,6818cdc9 +2306,cc34d7dc +2307,5f14968c +2308,56422938 +2309,496a7358 +2310,218fe7f1 +2311,2b05485e +2312,c803864e +2313,b62feb06 +2314,79d398ad +2315,c5abbe64 +2316,084cf742 +2317,059250a0 +2318,69a197e7 +2319,822431a0 +2320,5155ea53 +2321,e3fcd7a8 +2322,1440e5b0 +2323,44daf3bb +2324,fb4c041b +2325,cf712744 +2326,3d873975 +2327,be408cdc +2328,8ca3842a +2329,6a4c2a0b +2330,662ef057 +2331,979e6e68 +2332,8a30f513 +2333,de0cad8a +2334,03e08b8b +2335,f1084433 +2336,38db0455 +2337,ba2da45b +2338,e6b9fdae +2339,b0563079 +2340,479d5673 +2341,9309cb1f +2342,21cbfef7 +2343,ed069233 +2344,32a57b35 +2345,36549ee6 +2346,4caf0bd7 +2347,6796aa73 +2348,a42dd685 +2349,c96d71f5 +2350,762ab419 +2351,cccd3671 +2352,f379f1ca +2353,c12db7b0 +2354,7dfacaaf +2355,507fe11b +2356,e9845918 +2357,30094a09 +2358,fdf38cdf +2359,1045ba23 +2360,eac017a2 +2361,8919a9ab +2362,bb5cf597 +2363,dd30ee0b +2364,63166e10 +2365,f2ce4c84 +2366,831a5b5f +2367,56b2273f +2368,a34e82d1 +2369,74a07ea0 +2370,21835b69 +2371,0bc6fa48 +2372,f82b15f3 +2373,49546294 +2374,b9853331 +2375,203c1b27 +2376,fc5d9a8f +2377,44d13636 +2378,1e788330 +2379,9374b518 +2380,0d2de366 +2381,6db654b5 +2382,077b9fca +2383,52562072 +2384,366743e8 +2385,272088e3 +2386,c82dea94 +2387,2f34b015 +2388,7b333607 +2389,c4039500 +2390,f186fb59 +2391,e45f7cfa +2392,b28555f4 +2393,69e7b059 +2394,d509f386 +2395,87ee74ba +2396,39339b57 +2397,5d21a074 +2398,e7d911a0 +2399,940b1652 +2400,2ab03e20 +2401,b4bc8b12 +2402,daf971f3 +2403,838b4bf3 +2404,ee593b7c +2405,5a1f111d +2406,3b7cf60e +2407,0e3e6f5f +2408,cbb7bb03 +2409,4d7e18bf +2410,715d9da0 +2411,42551c20 +2412,97acf5c7 +2413,20e397e2 +2414,825aead7 +2415,c03ee3e1 +2416,fb1fa77a +2417,7f9cb17c +2418,8cf62640 +2419,2dab6eab +2420,1ceaf6f6 +2421,fa31e7cd +2422,9b0f557a +2423,4d47a96e +2424,091e611b +2425,1a5504a1 +2426,f084968a +2427,9a5ee4a5 +2428,88385c66 +2429,b6761383 +2430,3e3d15e8 +2431,4d93a9d1 +2432,ac15be7c +2433,97b5deda +2434,ddbede3e +2435,88fe23e7 +2436,6b7163ce +2437,cc9f1103 +2438,2387f046 +2439,b07d28e8 +2440,b3e5c555 +2441,781474f0 +2442,1f870762 +2443,a26665c1 +2444,3ed1b7b7 +2445,32fc6138 +2446,3959c24b +2447,be38b198 +2448,469de4dd +2449,64d89216 +2450,0641abfb +2451,f391b6c4 +2452,0c39b3de +2453,8bc9ad6a +2454,3002e7ec +2455,f73c9780 +2456,a281bdf4 +2457,b76c85ef +2458,6f16dd2a +2459,5c7bf811 +2460,4214b4c3 +2461,e3ce9f04 +2462,2750b7a8 +2463,dbe2292a +2464,de895db2 +2465,e6ea2a1e +2466,fe2c433e +2467,a36195ab +2468,82e37475 +2469,f323df78 +2470,b71b84ee +2471,0b78c29b +2472,50bd0f47 +2473,e6efe99a +2474,273ca625 +2475,bc901c72 +2476,bee2b365 +2477,6926a1a2 +2478,e7516640 +2479,fc2dd0ba +2480,0c04b0f0 +2481,fb3669e5 +2482,54f5c9b9 +2483,e77ffb44 +2484,1ab8a540 +2485,231e8bb3 +2486,239a2fb5 +2487,8f682fb0 +2488,710a249f +2489,5857d92e +2490,6cc5b4ef +2491,fff09016 +2492,e732211a +2493,d0112fb6 +2494,03e6936f +2495,f25a530d +2496,017d762c +2497,559a91e2 +2498,980cd9a1 +2499,668d29a8 +2500,42ab866a +2501,bae1e5f3 +2502,cda2ff3f +2503,20f50ab7 +2504,2adf231f +2505,9d993af0 +2506,ad14e881 +2507,a1a4995e +2508,516e9da7 +2509,3612f407 +2510,e91079ba +2511,56b39616 +2512,742894c8 +2513,6ec92339 +2514,96f2445f +2515,7f59ae4c +2516,bee2da1e +2517,43a2c3aa +2518,0465ad54 +2519,521924a4 +2520,51c80079 +2521,aa0a4afb +2522,52a31d18 +2523,d5ae5109 +2524,f7c19663 +2525,d38e9d8e +2526,9d7c27eb +2527,28121473 +2528,e4f75d35 +2529,4b66ba0c +2530,d93b1836 +2531,dc213f32 +2532,403e8da8 +2533,a2789e31 +2534,c578533b +2535,2bb31c63 +2536,180e7c47 +2537,793b4e61 +2538,9d69a353 +2539,720738ab +2540,d48cfee3 +2541,dd1700a3 +2542,32edf6a9 +2543,4de6d2dd +2544,1408c231 +2545,0382e28a +2546,a6e54622 +2547,b5580267 +2548,ac9b7744 +2549,7858fe45 +2550,14d9c72c +2551,fc2727da +2552,b340c1ba +2553,c7a3a8d3 +2554,912ffb79 +2555,1889f5f5 +2556,305556fa +2557,b7f6a4ac +2558,106aa41e +2559,7a9cfb81 +2560,3495a818 +2561,0eb2e400 +2562,37fd3c83 +2563,3ac82573 +2564,e7b639ce +2565,7dac635e +2566,faf28f25 +2567,4db73157 +2568,d98b5d86 +2569,0dbbada9 +2570,02f5640d +2571,696bba4a +2572,a8cb42dd +2573,7e14894b +2574,3e372aea +2575,afe8a085 +2576,1caa7178 +2577,bfee87e6 +2578,6bc13d1d +2579,e9b2ddd8 +2580,d4014972 +2581,050d637a +2582,a2f66d46 +2583,3b3dc1ba +2584,a4f8b252 +2585,9129bd39 +2586,1b47bec1 +2587,a0f4c103 +2588,fa2e5a86 +2589,2932ec54 +2590,93526a80 +2591,0b429308 +2592,b4ec2fe1 +2593,7a18fc76 +2594,e0922d09 +2595,63a506c3 +2596,5128c19c +2597,71d2f90b +2598,ee82c6ea +2599,905eaa1f +2600,0b0876b5 +2601,e3818071 +2602,89035391 +2603,c2a73873 +2604,0432f7dd +2605,9c6b19c9 +2606,2e99dc5e +2607,fdb1901b +2608,94746a90 +2609,15c5589e +2610,39a37f5f +2611,dac34265 +2612,18574e07 +2613,7b158b96 +2614,2f0562cf +2615,31a3cc22 +2616,a5c00f77 +2617,05877a78 +2618,f755e97d +2619,1d9e10b6 +2620,9baff810 +2621,6096453e +2622,e1c9e188 +2623,2b47ab44 +2624,fbda8592 +2625,3e15f859 +2626,fb746bbf +2627,abe3c786 +2628,cc2ca560 +2629,3a43800e +2630,bb297a17 +2631,83ebbfc1 +2632,ccfcd541 +2633,ce3512bb +2634,7ff77987 +2635,905b9da5 +2636,5ace78c0 +2637,0171791a +2638,f7eb2287 +2639,a3d0fc50 +2640,56fda7bb +2641,8164a004 +2642,8c23106b +2643,55696083 +2644,d594ed7b +2645,1d14df56 +2646,7bfa0de1 +2647,44e3de36 +2648,74cf2efe +2649,3ebd1e68 +2650,8165f77a +2651,5209e72c +2652,63000202 +2653,5b3fa38f +2654,489b6fb6 +2655,225f5134 +2656,18edc7bd +2657,25d8d9c4 +2658,ff904e32 +2659,903fc22a +2660,767efccd +2661,fb2cc208 +2662,8ec41b7b +2663,895856dd +2664,6183f6bf +2665,8aae3109 +2666,c60243ab +2667,f46b83bc +2668,5005b2f8 +2669,55d96247 +2670,efa477a9 +2671,dfde6150 +2672,d6525cdc +2673,23e51584 +2674,fa6c8f9f +2675,9eef959f +2676,5ba4376f +2677,1a22177a +2678,f0542134 +2679,b555c5c6 +2680,e2ad66bf +2681,6f6b11ef +2682,d2beb699 +2683,36f58795 +2684,3a4023ef +2685,ec633403 +2686,bcb0c4e2 +2687,9a601f36 +2688,a803bf0a +2689,dda60e5f +2690,a1661db7 +2691,f8405865 +2692,6c3b68be +2693,4b45d664 +2694,6d6d1505 +2695,27c3024b +2696,19f14c65 +2697,65e56dad +2698,f022e5db +2699,2b2c5a4e +2700,9cc8e0ac +2701,f4b23963 +2702,d94972b9 +2703,9aee9e84 +2704,7f214392 +2705,334edb68 +2706,d5a6bfc4 +2707,2cbf5ddd +2708,85a9bd18 +2709,a293aa32 +2710,877a45a7 +2711,fad190b1 +2712,13c97ccf +2713,a5aabcdc +2714,7b4c8a70 +2715,966be2c8 +2716,f62e97fd +2717,65e93d6e +2718,f724f9cc +2719,82f93dd7 +2720,bda0beaa +2721,71613ea2 +2722,15b27104 +2723,f78fbf2f +2724,7e9d54ae +2725,b70ec1ab +2726,4499b540 +2727,ee7ff81b +2728,d9dd2761 +2729,7968acbb +2730,1af4c7f2 +2731,0b1a5a2a +2732,3997521a +2733,fbfe9a92 +2734,86168055 +2735,74bc3ef5 +2736,09a55e85 +2737,2a1cbac2 +2738,ed082e5f +2739,2857825b +2740,028bfe47 +2741,b2896e58 +2742,ee121f27 +2743,6b3d454b +2744,45ed21d9 +2745,8540013e +2746,c63f2691 +2747,658e6567 +2748,04bc91cb +2749,c2ec97c4 +2750,14d82738 +2751,0fb15cdd +2752,a8deeef4 +2753,99b524a9 +2754,349e2124 +2755,8185e41c +2756,866eb17b +2757,3438b912 +2758,d806c246 +2759,8fd2a5cf +2760,a6fa76ff +2761,eebf7a94 +2762,92cee1b7 +2763,2734bce3 +2764,aec56113 +2765,b711c333 +2766,980eb6b2 +2767,9f3f32e6 +2768,9d6aec98 +2769,01269a30 +2770,1bfa8d13 +2771,5906dac7 +2772,0cbd52bf +2773,3700ed5b +2774,0e3c3ec8 +2775,3ab74a74 +2776,6db25284 +2777,c44b358a +2778,0ab4257c +2779,4590b714 +2780,fc764813 +2781,2417ccd2 +2782,5b8b55dc +2783,0d13f869 +2784,5e03cc5a +2785,2b60f21e +2786,985f84e3 +2787,946c23ba +2788,ed429c8d +2789,67a382e6 +2790,c643cbb9 +2791,65ebaafb +2792,acb56d54 +2793,295933eb +2794,db69ae2a +2795,d17caa92 +2796,e6765da2 +2797,9df53f61 +2798,2181466c +2799,fb2a1067 +2800,686f0cc1 +2801,3702f424 +2802,83658dfa +2803,a933af21 +2804,df8b2121 +2805,c7f8740f +2806,5b23ab84 +2807,6a8b57ec +2808,14aed66f +2809,312b3f28 +2810,3159ac67 +2811,056a1a19 +2812,2b52d5a1 +2813,be4aa665 +2814,0d5bf27d +2815,05194dc2 +2816,7f7806a6 +2817,47e4e44e +2818,ff6c2e63 +2819,1caa7d57 +2820,6cae50a3 +2821,75afad0a +2822,76be4f33 +2823,82ea2608 +2824,d4ac2213 +2825,434ace1d +2826,99d9e87f +2827,23751a93 +2828,d3f3a958 +2829,c680c7bb +2830,c55296ad +2831,7f9a0b27 +2832,517ca160 +2833,68a3d292 +2834,01d11cae +2835,368b10c7 +2836,d60955cc +2837,ab51b442 +2838,5a1b2fa7 +2839,4e88d093 +2840,d8601006 +2841,88b19996 +2842,4b32c98d +2843,7407022e +2844,3365b483 +2845,a25bcd48 +2846,c87a7fdf +2847,3840820b +2848,e1402de3 +2849,485c581e +2850,e5d468b6 +2851,1e042416 +2852,35793022 +2853,45490032 +2854,fc42f6e1 +2855,e523a120 +2856,7073d0eb +2857,07f8ce8d +2858,f2f341dd +2859,c1e65af3 +2860,92842229 +2861,dd38acf7 +2862,b05d7c65 +2863,2981dda2 +2864,055fb4a8 +2865,03335ac5 +2866,a3a34b2f +2867,446354ee +2868,42a14f7c +2869,4a38c2b9 +2870,4de38e2a +2871,263976ee +2872,2682443b +2873,062be978 +2874,4791e490 +2875,8c64d6af +2876,2cce4f21 +2877,6e321936 +2878,d0b06b35 +2879,d5857fc8 +2880,148f3092 +2881,893929a9 +2882,c2821051 +2883,24c7ee28 +2884,b7712ffd +2885,8a88ab0d +2886,caf53b8c +2887,225243d8 +2888,8429c6cb +2889,0723b9b8 +2890,664e1ca4 +2891,ebd883dc +2892,b66e0234 +2893,67bb8160 +2894,58baef62 +2895,25b82a04 +2896,b6e9ffaf +2897,0b9da628 +2898,ed654a3a +2899,b2f22588 +2900,56c549c6 +2901,4ad4af5a +2902,7013ad6a +2903,ff12cc1d +2904,d58c1fd8 +2905,610f78d3 +2906,159b5e3d +2907,eaabc04b +2908,ca681392 +2909,876d418f +2910,8dff5c7a +2911,e580c5c6 +2912,35a57695 +2913,21b221b2 +2914,aedd753d +2915,13a880d0 +2916,a0e8cf19 +2917,1a1438c8 +2918,d83bcbff +2919,b816d9a4 +2920,dd531d68 +2921,c97cd27f +2922,1b1650a6 +2923,5263e072 +2924,96360ef6 +2925,e6844b0c +2926,e2e30fc0 +2927,cc0c9202 +2928,e1c837c7 +2929,f5fe3035 +2930,7265d933 +2931,e720e368 +2932,11f9c72b +2933,f19ad855 +2934,5fe8b4d5 +2935,43c8a5d5 +2936,d3379246 +2937,d097c6a0 +2938,2b961096 +2939,095ab1fe +2940,efae3b45 +2941,339bb20e +2942,d7a457ae +2943,6490a94b +2944,35317f4a +2945,5aaf6db1 +2946,38aa17b0 +2947,90fcfab3 +2948,c946114e +2949,89d371ec +2950,3bdeb332 +2951,c8a3987c +2952,bee2127f +2953,5735fa6c +2954,0ef29a9c +2955,776bd346 +2956,884b141c +2957,0fe13a3a +2958,0ee46cba +2959,12221815 +2960,78a74881 +2961,fe5b9651 +2962,4001455d +2963,4a7adc84 +2964,e8029e87 +2965,fbdfdf1b +2966,67f27102 +2967,fc2eef71 +2968,db8a1707 +2969,706c2fbc +2970,1b89d5d3 +2971,29a4d2aa +2972,75ad4a1f +2973,554cd770 +2974,1e81e48f +2975,4f8f426a +2976,1900dc83 +2977,22824ee5 +2978,b9311184 +2979,4e570209 +2980,9d8414e5 +2981,f49fd699 +2982,7dde6501 +2983,3603a784 +2984,ece1a3db +2985,3a113f6c +2986,63ef0120 +2987,cd6910de +2988,f3a94cff +2989,b5533783 +2990,5acd5ff0 +2991,54399a3c +2992,7469ddbf +2993,788bdb96 +2994,df7c12bd +2995,7d8f35f3 +2996,1fab8111 +2997,34c9e15c +2998,15b7090f +2999,763a048c +3000,d414f3a3 +3001,42454b25 +3002,e8e6e12d +3003,2794435f +3004,d17d9cc1 +3005,4a1b0f42 +3006,9b3313d8 +3007,dbf0bccb +3008,1e7a7603 +3009,b789e26e +3010,6409574e +3011,e1b56a26 +3012,84f5da45 +3013,632d7656 +3014,ea075251 +3015,029b6de5 +3016,cdaac894 +3017,fc8e07d0 +3018,eb381a16 +3019,b15aa2e7 +3020,80f60335 +3021,1f2306ee +3022,0df8c9d5 +3023,700b6928 +3024,03ab270a +3025,d5a6cc1c +3026,ff42f7e6 +3027,e0d2c49b +3028,8b00b1ab +3029,01e00d87 +3030,6dcd47d0 +3031,37cbd669 +3032,4d667190 +3033,c4b2be2d +3034,3b15db4c +3035,a07654e5 +3036,e9a54b4f +3037,9341e9b2 +3038,f645517f +3039,48215e17 +3040,1509dc14 +3041,0abd2c93 +3042,c1f23ea8 +3043,fa01e0be +3044,dea71c10 +3045,f2a93b9b +3046,93342dfe +3047,a745ff39 +3048,27600fdf +3049,6704bffe +3050,e7c108a6 +3051,ffaaa7f2 +3052,69edc6e4 +3053,bc5b5e98 +3054,6f746456 +3055,622f506c +3056,03fb29f6 +3057,bfe4fc6b +3058,09e20982 +3059,83e13172 +3060,e4abbc2f +3061,1baceb21 +3062,895478bb +3063,dd64ab18 +3064,af2e04a6 +3065,0094d24e +3066,cd7cd1b7 +3067,c22ee2f8 +3068,d5106245 +3069,cb282caa +3070,faa3a12f +3071,61cb3e49 +3072,752afbb3 +3073,47e47c5d +3074,74935ad5 +3075,26b72614 +3076,dc38f2c2 +3077,60a0eafb +3078,7af864df +3079,5590c186 +3080,568a8b6d +3081,175f9d0b +3082,bde04a5e +3083,e5034ee5 +3084,c42db04d +3085,111a0d92 +3086,eb38714e +3087,86ae6175 +3088,6b41b2c9 +3089,36cdee9c +3090,49561a90 +3091,88f835ae +3092,496754d9 +3093,e92f9905 +3094,8e473574 +3095,0bd322a7 +3096,d3ea4d32 +3097,e90f4065 +3098,48c67086 +3099,105c44bb +3100,efbd6285 +3101,c7ff6845 +3102,d9fa8160 +3103,91ec644f +3104,aa5d0d9a +3105,0d6f5059 +3106,10dac571 +3107,eba2120d +3108,161f5ad6 +3109,704d0d5b +3110,8f73fe55 +3111,f01ea3aa +3112,dee09c12 +3113,960f5ee8 +3114,87079079 +3115,93719156 +3116,219febd5 +3117,2f50db00 +3118,c8c3d642 +3119,d73c529f +3120,d7ad9ba1 +3121,231a9cbb +3122,ce600a25 +3123,1c474fc7 +3124,da0f1dcf +3125,c6775507 +3126,14314ab7 +3127,cb169c9c +3128,0b6af129 +3129,98c541a2 +3130,00e52b50 +3131,58095779 +3132,4195533a +3133,40329ab7 +3134,ee65ef86 +3135,dca30adc +3136,14269e8d +3137,48e1500d +3138,fc9bc03f +3139,42d8d39b +3140,ae0ccb2f +3141,c7a641fb +3142,bffb2c97 +3143,fcb68234 +3144,d29afa77 +3145,3aba9ea5 +3146,7412970e +3147,a655f1bb +3148,784fe30d +3149,0c3be5d8 +3150,7eedf6bf +3151,576e7a66 +3152,cf43a528 +3153,79ba8afa +3154,bfd7a273 +3155,40209e33 +3156,95244732 +3157,7343fdd6 +3158,8ae7d6af +3159,28b368fd +3160,0669583d +3161,7ebeab87 +3162,a33fba07 +3163,845aa2f7 +3164,3cfca74e +3165,b35c51ac +3166,f1537191 +3167,986a8c49 +3168,a704d4ec +3169,febe0fdd +3170,bb50bfa8 +3171,e05d520f +3172,26c07dab +3173,2d21aecc +3174,21ea16c9 +3175,c2f91047 +3176,ddc7e46f +3177,01818502 +3178,a9bdc088 +3179,f08efad8 +3180,23317577 +3181,c0ee9ef6 +3182,7299d672 +3183,108dc4fc +3184,627a24c3 +3185,f598c726 +3186,14d5011c +3187,715de21e +3188,3b646658 +3189,a83e861a +3190,6ecd7efe +3191,bbcd0697 +3192,0290a18a +3193,2c368c5f +3194,739f33d9 +3195,8b828ae6 +3196,0c476103 +3197,2be65081 +3198,0800767c +3199,d8d694d4 +3200,0e1a8744 +3201,73e53d61 +3202,cb41b8c6 +3203,d57277ac +3204,256fd29d +3205,6c0bb2e5 +3206,9b576d87 +3207,d1a4522d +3208,1968a2a2 +3209,de67dd1e +3210,682dd913 +3211,ee81abaa +3212,095e559f +3213,48e45e28 +3214,b7b70df4 +3215,f554cb67 +3216,b3dfb6da +3217,79c40ed0 +3218,8f08b4d0 +3219,4e347314 +3220,583d6510 +3221,b95943fd +3222,d10eaf27 +3223,5129f521 +3224,51889fc8 +3225,76d4d27a +3226,0de5e15c +3227,6facbfb3 +3228,e4f827ab +3229,cdae2c09 +3230,aac03d36 +3231,76807397 +3232,63b8c624 +3233,2df498fe +3234,3fd33c22 +3235,496cbb43 +3236,b3efccdc +3237,7df3e453 +3238,a0399e30 +3239,88e4ac8b +3240,179ff083 +3241,39952db0 +3242,56ea032d +3243,6a3690ec +3244,5e0c97b0 +3245,4a492ec5 +3246,2e4f975d +3247,6dd4eb68 +3248,408e172c +3249,040aeaa9 +3250,013132d1 +3251,a0806d1e +3252,3fb60b06 +3253,a516afa4 +3254,50c9d608 +3255,750bf1fb +3256,b070ff33 +3257,64a2b313 +3258,4f4a6248 +3259,c6dcda81 +3260,ebb84a96 +3261,1597307d +3262,2ebe4a39 +3263,9b1ea13d +3264,4f76e90f +3265,17e84630 +3266,61b1a05c +3267,66a89ceb +3268,fd81f902 +3269,f4e22174 +3270,ebad2291 +3271,df5f5b1c +3272,b6be3be7 +3273,d0e312d1 +3274,07f74cdc +3275,116e3262 +3276,21e10c51 +3277,f63a4643 +3278,4771eda9 +3279,6e56512b +3280,41f27d5f +3281,810eba1d +3282,1d4bf448 +3283,7715e83b +3284,75edb0c2 +3285,23a4ad26 +3286,47aad19d +3287,c8be0855 +3288,8fbc2356 +3289,827bb14c +3290,9b64f909 +3291,bd1677fc +3292,161475b7 +3293,a02cd377 +3294,9b90e47a +3295,8a3d1252 +3296,4bf07d85 +3297,acd65ee8 +3298,e9c70946 +3299,6c3671d5 +3300,f1d5770e +3301,a648c517 +3302,8e9d9f6c +3303,3e87b803 +3304,cb802e02 +3305,5344acdb +3306,dc02f208 +3307,e22139e3 +3308,0557aa53 +3309,867f9f9d +3310,b43771be +3311,8bb79d7b +3312,696a4fee +3313,bd042c52 +3314,228ff71d +3315,8f23be98 +3316,700f28d7 +3317,612b53d5 +3318,a50e50f6 +3319,63502465 +3320,ee17ac2c +3321,ada37154 +3322,586ed464 +3323,9c5ab59b +3324,384aa933 +3325,1c40eb1d +3326,1bf68711 +3327,9fca3868 +3328,ff14f28e +3329,ffafa0f3 +3330,d3dc7b09 +3331,c98acfd9 +3332,525e21a5 +3333,4ae07ad1 +3334,ff0c2eae +3335,07f1095a +3336,06f8d8e6 +3337,88378047 +3338,30069669 +3339,669c93b6 +3340,85b6aceb +3341,a72a0d97 +3342,9fe481f3 +3343,08e45372 +3344,0aff218a +3345,03727974 +3346,edd97fda +3347,9153ebbb +3348,f5c24a7c +3349,0e53bbb1 +3350,6fa3b05a +3351,24a8e33c +3352,e68fd9c6 +3353,a12b854a +3354,3b2c3ddf +3355,1bb1ac04 +3356,522bd1db +3357,9035a938 +3358,35d20fbd +3359,e2528c4d +3360,218af416 +3361,afd27385 +3362,b754bebc +3363,14d05228 +3364,e0246e01 +3365,a33eef90 +3366,4ae401da +3367,fa1e4f18 +3368,2ddfc9c4 +3369,8e045c08 +3370,9f4d39be +3371,84ded7c2 +3372,3629c355 +3373,71a8790e +3374,0e350265 +3375,ba40c509 +3376,268d0e69 +3377,ef0b3ace +3378,2eeb2628 +3379,eac76ece +3380,c74c01f9 +3381,0e5f0717 +3382,d4f696b4 +3383,461b1ecf +3384,34dcd8dc +3385,23023152 +3386,8407cd3f +3387,ffb16e20 +3388,aefe4cf2 +3389,fb2286a0 +3390,038e0049 +3391,bed6bfb3 +3392,30e36298 +3393,e0f59845 +3394,2e799cbd +3395,fcbf4831 +3396,fad732e6 +3397,62353ab3 +3398,63e8c158 +3399,4bd382be +3400,c3eaf6a2 +3401,d098a821 +3402,a54571e5 +3403,15157939 +3404,b8880867 +3405,a31ceb4a +3406,5e16abbb +3407,415221cb +3408,7c8ccfcd +3409,7eea0a0b +3410,c0b7e0ba +3411,c1ca3582 +3412,309751d3 +3413,caeeebe9 +3414,4261b6e9 +3415,526c9b82 +3416,62214808 +3417,f26887d8 +3418,983127dc +3419,26b22913 +3420,2228cb3c +3421,643f6438 +3422,3b6b7d57 +3423,2bdbeb1e +3424,8ce1bcbc +3425,aeaf18a2 +3426,1cc44191 +3427,bf53ccc5 +3428,839f4de6 +3429,59457429 +3430,21c8a2be +3431,81d400dd +3432,9030de49 +3433,1cb8ffc0 +3434,44dfdced +3435,ed6388ac +3436,3f9e2816 +3437,e986c962 +3438,23cc79ba +3439,105cdd8a +3440,075683a0 +3441,8676ef28 +3442,231299f4 +3443,d476ea4d +3444,904b4d4d +3445,4525fe62 +3446,dcae7829 +3447,c7d70d20 +3448,d2ed6701 +3449,f2301e71 +3450,ec2b7f00 +3451,ec852246 +3452,6e5c2068 +3453,f4d4c816 +3454,af0e3939 +3455,a9832e5c +3456,cacb579f +3457,06eb9da7 +3458,2cdf7b94 +3459,790d4603 +3460,81eba329 +3461,ecaf0a28 +3462,09422276 +3463,b21ac61e +3464,53b11c36 +3465,d1ff3b22 +3466,08f26833 +3467,dd1fe350 +3468,6eaced2c +3469,fecd46db +3470,f083252e +3471,6b113db6 +3472,a0f0f52c +3473,d199b645 +3474,2111ed95 +3475,ae72299a +3476,e2e08db2 +3477,f2b6d31a +3478,22eca8a0 +3479,c0e11d6b +3480,260673e6 +3481,36c72e2c +3482,70d219b6 +3483,7f6be4a7 +3484,aef91293 +3485,ed937204 +3486,bccedf83 +3487,1f2703a2 +3488,57f03c2b +3489,12309191 +3490,5a065310 +3491,ce3634ab +3492,bd882f62 +3493,e190685b +3494,00a7e67c +3495,9a60e2cd +3496,b8b820d3 +3497,76d2f8f5 +3498,421887e9 +3499,50c06264 +3500,50656a2c +3501,5abedd38 +3502,7a4ab0d2 +3503,791ea0e8 +3504,e5b897a5 +3505,a81fea36 +3506,48a68f72 +3507,063e9b6b +3508,e62bfdbd +3509,cb9b87b1 +3510,d0da6427 +3511,93c2dc06 +3512,1c88f616 +3513,b0c35cb7 +3514,f40b87a7 +3515,8f3b88fe +3516,b26047d0 +3517,107990d0 +3518,0399ddad +3519,afe7d435 +3520,d704c8f8 +3521,4dd8e9fb +3522,337ad098 +3523,66d246c8 +3524,095d8769 +3525,bb008ed1 +3526,f3a4adad +3527,e752e489 +3528,489274df +3529,68153a73 +3530,e976e0d8 +3531,a611c565 +3532,f023e72c +3533,4dba38ed +3534,85735d6a +3535,90a59d71 +3536,3e095b46 +3537,2fa1b49b +3538,3e91b2cd +3539,2ce3e167 +3540,dc3f549c +3541,6c8bfb25 +3542,7948fe10 +3543,8369cf8e +3544,7e309a12 +3545,3247c65a +3546,01201154 +3547,d3eb669b +3548,3ccc4627 +3549,6aba888c +3550,7776ca85 +3551,d1f1d2e1 +3552,7e5c3d00 +3553,a9186963 +3554,befdcd27 +3555,bef4f999 +3556,365694ca +3557,bf6d1dd1 +3558,d51f7356 +3559,36b3c929 +3560,a023c9ea +3561,8cb57f34 +3562,75a2a319 +3563,8558fdf0 +3564,a2375cba +3565,dc985a96 +3566,c6e3ce63 +3567,7e90b9e2 +3568,5f66a910 +3569,02d05cb0 +3570,728a9090 +3571,72bf6a39 +3572,14b6c6bc +3573,a17253a7 +3574,b6e78f22 +3575,4f29ca33 +3576,9f705bbe +3577,ad8c06db +3578,36c9d920 +3579,f5d4c1c2 +3580,596dd7a9 +3581,3ab2be77 +3582,bf11fefb +3583,9df7b84e +3584,c18be106 +3585,4057562b +3586,c7522b9e +3587,69bed74f +3588,3f41632e +3589,d7b3e2c8 +3590,e6412ba6 +3591,309eba99 +3592,ed578c53 +3593,51d1f27c +3594,dfbbf6ba +3595,89c48d44 +3596,50a99f58 +3597,ff2e1c76 +3598,633e27d2 +3599,1d77a836 +3600,92792146 +3601,a7e673b9 +3602,7b2f59ab +3603,e278e9e4 +3604,5b2d71c9 +3605,2d5a3f08 +3606,daca2e0f +3607,f27aa3b3 +3608,81c953dd +3609,f0848e8f +3610,6e8366dd +3611,dc0ae886 +3612,1335737d +3613,e60b7406 +3614,9dbaf3ad +3615,7f7d0010 +3616,272e9616 +3617,0ba96ce7 +3618,d6e464a0 +3619,98a51205 +3620,2ecc3a03 +3621,2eafcc4e +3622,1fb74b2a +3623,b11969ca +3624,9c2459d9 +3625,906bf314 +3626,db997007 +3627,8e474556 +3628,7410a308 +3629,257ff1fe +3630,50aeb6b2 +3631,465fcaf5 +3632,1f8a0b0a +3633,6d599979 +3634,e33157ff +3635,9e7548c8 +3636,d62b904e +3637,8d7cd627 +3638,9662ac2d +3639,b4e939a4 +3640,840c6433 +3641,5102260b +3642,6edc48ca +3643,4ff366f9 +3644,2ee8e867 +3645,2dd6d9a6 +3646,79f9a1a2 +3647,19124051 +3648,f4457c34 +3649,b3479e30 +3650,25cb44ce +3651,247604bd +3652,7d441db7 +3653,b17d2df7 +3654,64bd2ebb +3655,35013941 +3656,4b341490 +3657,5b93395b +3658,d2523e9c +3659,0b1980dc +3660,b109fd56 +3661,a64848b4 +3662,64888401 +3663,f5c1522c +3664,0c198e44 +3665,58be7823 +3666,c03da411 +3667,fdd4661b +3668,5f22ecb0 +3669,e7ac5e98 +3670,09f3c669 +3671,878b6885 +3672,e609b9b1 +3673,ca9ce922 +3674,513cc5fd +3675,49c340bd +3676,a98aa9b1 +3677,626e3e96 +3678,592d9ab4 +3679,782d9446 +3680,db0f2e00 +3681,1f34412a +3682,35823cb7 +3683,00faac1f +3684,78fa9304 +3685,406b1d21 +3686,cdb60ceb +3687,f6c905ea +3688,833e182a +3689,2ba69f2a +3690,811623d3 +3691,e1567e32 +3692,79b2c58d +3693,19328d9d +3694,fa4c98be +3695,2398f44e +3696,2b0db6c6 +3697,bff15bf4 +3698,b8c42e88 +3699,cd065b70 +3700,86bb8aca +3701,b492b822 +3702,2c2a29b6 +3703,44db500f +3704,21ac0d21 +3705,7d01e7e6 +3706,fe7e0d35 +3707,d225c1fc +3708,a7028b54 +3709,0258559b +3710,f33f9e53 +3711,a9f4eddb +3712,a025b94f +3713,729dd6f1 +3714,3bd14652 +3715,4aa61eaa +3716,2f69775f +3717,b6417ae5 +3718,6ca1c63c +3719,8f7b004e +3720,4ab31916 +3721,c3e258b5 +3722,25308c4f +3723,8d451572 +3724,3660ccb3 +3725,885ec88b +3726,c3bc9e1e +3727,fea651f9 +3728,ce97ca4a +3729,68a2ff31 +3730,85d13d78 +3731,1f6e48a9 +3732,76e81a97 +3733,d0809215 +3734,8e32845a +3735,90878d13 +3736,d73c5fed +3737,bfc89ea8 +3738,2f590c38 +3739,aafeb4b3 +3740,a45e942e +3741,11eee8c3 +3742,904b2724 +3743,bd3892ae +3744,d428df24 +3745,4e5ec4fc +3746,33b7bdc4 +3747,42681329 +3748,4ecd8170 +3749,440ab9d0 +3750,b3176dba +3751,33d96b43 +3752,2880cce8 +3753,d3921e38 +3754,6bf718fc +3755,54c28e16 +3756,7f575e33 +3757,23816040 +3758,7618e230 +3759,609b8baa +3760,1b57dfef +3761,41f73aeb +3762,2d0ecd69 +3763,fd0cd526 +3764,35bb2ced +3765,372869ce +3766,d1501edd +3767,f2d9a880 +3768,628fc934 +3769,c854d742 +3770,90ebd72e +3771,fd767f9e +3772,eeebf7fc +3773,0bef7740 +3774,4dd9f9c6 +3775,b346a62c +3776,46f0c543 +3777,6262c145 +3778,20ee2404 +3779,ddf4b8f8 +3780,4fe7a18b +3781,52c51281 +3782,7e5a9bd8 +3783,f3351685 +3784,afc3db35 +3785,d6d86d4d +3786,fb8682f6 +3787,9c3e8078 +3788,2d59ce71 +3789,80540f70 +3790,28d7d664 +3791,e42cde9f +3792,39abe439 +3793,2378a34c +3794,7fa55615 +3795,a7c625e6 +3796,2ce17cc1 +3797,c86bc14a +3798,d8e963b9 +3799,f491a07e +3800,dbd9de41 +3801,e2d79db1 +3802,91144577 +3803,9de1cdc3 +3804,bbbffe25 +3805,56b53d9c +3806,c1beb429 +3807,2507b7ce +3808,c24f758e +3809,fc34f8dd +3810,3a4253fa +3811,6a848021 +3812,f1a0c959 +3813,cce76453 +3814,dbef40fa +3815,00fee1a5 +3816,f9c9473f +3817,f408ed44 +3818,450934f7 +3819,3475ba93 +3820,0f60a8dd +3821,77b8f4bd +3822,c6e40688 +3823,93bd54d7 +3824,4fa4f610 +3825,abc76de7 +3826,2988b0e5 +3827,884f762d +3828,57f91cd4 +3829,7f1b082d +3830,d102bb54 +3831,f1acbf8e +3832,a2ac7b95 +3833,afc4ce44 +3834,b126049f +3835,ef6b1f3b +3836,aac8673a +3837,457b9d7c +3838,c5efe506 +3839,9ea161ea +3840,081acfcc +3841,12629464 +3842,2d763cae +3843,2a176f48 +3844,44364be4 +3845,1c29003b +3846,8d13fb0d +3847,a92a3ea1 +3848,1760a719 +3849,7a5da507 +3850,0fcd8f44 +3851,2c50cd30 +3852,c386ec01 +3853,629c6c86 +3854,6b532a91 +3855,76d3fbbb +3856,c58c631a +3857,bde36f27 +3858,9ee74ae9 +3859,db596676 +3860,b9ca2cdc +3861,add1de70 +3862,f793c387 +3863,0200b3ed +3864,99fed5d3 +3865,d843ae4a +3866,e11a9ab7 +3867,29900e0e +3868,c3b9c4a5 +3869,ff1e11c4 +3870,35d7481f +3871,f67e301e +3872,a67563df +3873,da35c8c0 +3874,f684f68b +3875,7e3487c7 +3876,1dddb202 +3877,adc27c5b +3878,8115a112 +3879,18682969 +3880,bbc41089 +3881,afe97fe8 +3882,51fd4319 +3883,4b5364d6 +3884,81e0e24c +3885,824889ce +3886,c732c739 +3887,ffd8a385 +3888,f06f763c +3889,9f26812e +3890,21c8cd8c +3891,94a8d216 +3892,c40bf383 +3893,45bf2cb9 +3894,c797b7fc +3895,b14cdef2 +3896,fc3c6f07 +3897,0f10718e +3898,83f84f1e +3899,74d2054a +3900,280c34d7 +3901,a5980063 +3902,d414c2e3 +3903,b3f209a9 +3904,a70cccb1 +3905,4990da73 +3906,ef6eb600 +3907,19608f63 +3908,c0c8f4f9 +3909,ff908b0b +3910,24dccc65 +3911,e6fae2d7 +3912,7bb107f0 +3913,2ccb2685 +3914,a3a9eedf +3915,f7992f0d +3916,8c323811 +3917,643f0e43 +3918,aec1f0a1 +3919,c2da24dc +3920,027c02e0 +3921,bf5b7276 +3922,da582eba +3923,0478a079 +3924,1d4b93ee +3925,41e3c594 +3926,ccb3a49b +3927,8ba8d75b +3928,3d0bd20a +3929,847671cc +3930,3275b0e7 +3931,ebe209bc +3932,37137859 +3933,ab6d725c +3934,06197045 +3935,16f03189 +3936,9451fd71 +3937,510df556 +3938,ac192b38 +3939,96cf5d97 +3940,5429541f +3941,4ccaa6e6 +3942,216df4e0 +3943,059c5b99 +3944,987fa868 +3945,09b405a0 +3946,78635ca6 +3947,65f23f12 +3948,6ff8bea6 +3949,8fea2d73 +3950,7bc7bb0d +3951,83217042 +3952,9ea1de92 +3953,baaa7547 +3954,1303db53 +3955,8bba1013 +3956,bcb280b5 +3957,22cb14f2 +3958,589a8869 +3959,67da8b23 +3960,a0038115 +3961,61fb5639 +3962,bf5b418d +3963,4b4a050a +3964,e1b17aba +3965,d4aa41aa +3966,7944b3bc +3967,2216516e +3968,c04d85f0 +3969,96fc3fa0 +3970,6633fd8d +3971,aa8862f9 +3972,034970c8 +3973,9871e60e +3974,d2b7a973 +3975,c3f419fe +3976,4fd44296 +3977,5214bdac +3978,18f19821 +3979,4fde19a2 +3980,5c0a11f2 +3981,38c8b3b6 +3982,b0c6ec3b +3983,2ba553ac +3984,cd7e521f +3985,628bf931 +3986,a8c92f46 +3987,e3ed7154 +3988,85fc6c32 +3989,c71eae81 +3990,38bf99ee +3991,20c68d44 +3992,348e2a59 +3993,9ca9fafb +3994,5c2ef998 +3995,6e20cedd +3996,b1836497 +3997,e44f6efa +3998,e95d3916 +3999,6f6fbcb8 +4000,3cec1864 +4001,56cf2432 +4002,276de3fc +4003,94b788d9 +4004,45ba1696 +4005,955ce046 +4006,12396edd +4007,efdb9a34 +4008,61dc019f +4009,ed038955 +4010,d1466ce1 +4011,74fbce25 +4012,85d45b4c +4013,e507ec58 +4014,fa1996e7 +4015,3dca9154 +4016,abe14b30 +4017,b7f8b280 +4018,d2930168 +4019,239ef539 +4020,1fafafed +4021,f642f1ab +4022,22eee23b +4023,a4e7179e +4024,7ae03078 +4025,fca99a60 +4026,c431fefa +4027,977b40e1 +4028,61389a5f +4029,e7c3b567 +4030,8b2317e8 +4031,71c026a8 +4032,82575d12 +4033,dc7c69f7 +4034,aa5481f2 +4035,fdfa8bbc +4036,19eb3fb2 +4037,3ee7f6a3 +4038,8aa00e18 +4039,9701965e +4040,3badf50e +4041,2bdab9d3 +4042,3fff8505 +4043,f67bfb0f +4044,b1946397 +4045,d19af82a +4046,3c921ddb +4047,a69b983c +4048,b99c8b98 +4049,3ee44a10 +4050,fd0eb417 +4051,5d4980f1 +4052,2f652c5d +4053,5e672a47 +4054,fd065238 +4055,a3dfdec1 +4056,787728b4 +4057,784cae06 +4058,3b187644 +4059,1e74f224 +4060,b9253940 +4061,89817a8c +4062,05ade2a1 +4063,6c7a3bda +4064,d3b36644 +4065,b1312318 +4066,a2f0cc8d +4067,aaee30ed +4068,a83a5de7 +4069,74c0c9cf +4070,64acf076 +4071,971c084a +4072,6b85d08f +4073,045daaf1 +4074,5236daa9 +4075,201c3b4b +4076,2dfd70f1 +4077,d0cc77d1 +4078,78025b9a +4079,99d0086b +4080,ad257959 +4081,6e8651bf +4082,c5f2033b +4083,98b28863 +4084,b9a83bbb +4085,45a30c95 +4086,22b7ab1b +4087,42d8cacd +4088,c03cec31 +4089,772faa23 +4090,10dbdec9 +4091,ee3376ad +4092,ac9d05df +4093,eceb3069 +4094,6cfcfdc1 +4095,57f5f6a4 +4096,f45a4e21 +4097,3081a765 +4098,b76899c1 +4099,39b6cb60 +4100,f74fe9bb +4101,35a9a44a +4102,185154d4 +4103,baadc4b7 +4104,8faa88d9 +4105,2f907da4 +4106,c302af54 +4107,60bbd834 +4108,8b1c6518 +4109,cc15ae68 +4110,b16b2f8d +4111,68a4d4a4 +4112,20dd510a +4113,4a624765 +4114,469b70a2 +4115,07e10e9a +4116,887f1a04 +4117,246eda11 +4118,58c46581 +4119,e1c34c79 +4120,f481e793 +4121,2a6c05b7 +4122,cb613203 +4123,c6816fd9 +4124,8f3f7064 +4125,cc7e7d35 +4126,7698dddf +4127,88e94b28 +4128,2c43069d +4129,1281f0a4 +4130,5888d04a +4131,48c85772 +4132,77e4df57 +4133,b1ee9c6f +4134,e0794446 +4135,6df0598d +4136,a1833bef +4137,23311f10 +4138,5e0b171a +4139,3bffabbd +4140,fe0dd972 +4141,eba25700 +4142,b7d2f78d +4143,38acedc2 +4144,74798b03 +4145,5a9d349c +4146,425e0c4f +4147,b91b2a28 +4148,8b85e338 +4149,17a829bb +4150,0d885664 +4151,69b0068d +4152,6b0f80ec +4153,a370e849 +4154,0049e1f4 +4155,539fa924 +4156,273203f2 +4157,0df59e98 +4158,58036d83 +4159,2d99e30e +4160,d7303776 +4161,af5cc2e4 +4162,df206e3d +4163,4d12a22d +4164,5e3bb270 +4165,286ef5e3 +4166,22b3b1f0 +4167,3df431b4 +4168,82c5c9cd +4169,d4da1134 +4170,10d11bcf +4171,c1b581ba +4172,1b7c1046 +4173,992211e7 +4174,30358bc9 +4175,ababc891 +4176,c9c4c5e6 +4177,ff8182be +4178,a3cc40f7 +4179,4a3ff05b +4180,15e2b09b +4181,f2d1d8ff +4182,14168778 +4183,8e576bdf +4184,92b78a03 +4185,776216c3 +4186,a35e696e +4187,fa68462c +4188,c2368c37 +4189,cd036cb8 +4190,0ac7a87b +4191,a3cfedf0 +4192,23c7759e +4193,54ff78dc +4194,8996024c +4195,796f2183 +4196,33c6310f +4197,471e0bfe +4198,c16195ec +4199,90d99c6e +4200,5f13d733 +4201,b8334c34 +4202,b1d0bf07 +4203,dd9306d3 +4204,44b91b36 +4205,942ffcb1 +4206,597fd2c8 +4207,d9b6b5b0 +4208,e9d49ad7 +4209,a8c0655b +4210,c92e5e35 +4211,31f850a3 +4212,dc3ec430 +4213,6f5ca462 +4214,7894077d +4215,a09f12b5 +4216,42aee836 +4217,e06036aa +4218,54e42fb8 +4219,7a9da435 +4220,27f25ca3 +4221,e06f1ff7 +4222,0cdbd69d +4223,2b410863 +4224,70ef0919 +4225,f84bb843 +4226,1bcd7d89 +4227,c219fb6b +4228,d2436682 +4229,059b90c2 +4230,61ebd505 +4231,7d72947f +4232,39597e64 +4233,07c5b8d3 +4234,45af6af6 +4235,03c74011 +4236,6f740277 +4237,9681bdbd +4238,54ede1ee +4239,eebfb1c1 +4240,20ba8184 +4241,bbb88f96 +4242,89eb002b +4243,06453dca +4244,14257507 +4245,193c9b82 +4246,93594e60 +4247,c3929923 +4248,c1e1a8f8 +4249,e7dbf8f7 +4250,9eb8f96a +4251,3a689389 +4252,8a972490 +4253,84cdd196 +4254,e7f1c61d +4255,05106984 +4256,3780641a +4257,e5bf02f7 +4258,2c34742a +4259,8ffc9ee5 +4260,f3369ab4 +4261,1af3837c +4262,fd3dc534 +4263,f688cfaa +4264,54ea2c62 +4265,e871eaeb +4266,e2fbb436 +4267,8982ca7b +4268,74969ed0 +4269,945c14f5 +4270,b8e1ad0e +4271,d84be4fb +4272,e1a2e7bf +4273,eaf5db13 +4274,76adb67f +4275,900839a7 +4276,10d0fd72 +4277,6a3bd664 +4278,c8cacb80 +4279,3d35b710 +4280,e7e33bab +4281,ec31ee9e +4282,716b9f52 +4283,980395b9 +4284,7df71608 +4285,815b2995 +4286,b38b22ce +4287,8021f039 +4288,4b4beead +4289,fe899f3b +4290,bd8f2172 +4291,1d93c3a5 +4292,76987b57 +4293,e0e69191 +4294,00e6f7a5 +4295,d2401520 +4296,06ebae02 +4297,8630c54a +4298,c194dce5 +4299,6156e994 +4300,d0a6784c +4301,e950cf70 +4302,cf750c22 +4303,e553140c +4304,e7e445f5 +4305,cfbbe635 +4306,3bc7ee16 +4307,6b56e636 +4308,27857d06 +4309,ab1a356f +4310,d3ae4265 +4311,9729ab1d +4312,ea1888be +4313,906c54fe +4314,7b6c85aa +4315,ec66b4f0 +4316,11609112 +4317,62432c5c +4318,a58a3eea +4319,de8ddcc5 +4320,b1dbaf4e +4321,fb30ae76 +4322,7f98df0a +4323,60d51706 +4324,409121ef +4325,d1e87525 +4326,1e2d3762 +4327,6e685e4c +4328,5353f1e6 +4329,f8a22ec9 +4330,8b27aa6c +4331,1988012e +4332,de6d24dc +4333,9f6b9f34 +4334,3d18cd8f +4335,fc78c5e6 +4336,98ee682d +4337,e584c47d +4338,5bde96f2 +4339,f974ad55 +4340,15abb928 +4341,4c8d5d98 +4342,63942e57 +4343,a6352804 +4344,87c03989 +4345,15fd34a6 +4346,a118fa39 +4347,f108323f +4348,378e7563 +4349,9f2e922f +4350,1ca1be5f +4351,1dc64dd7 +4352,14b92963 +4353,5540fbf6 +4354,b889a53a +4355,3ca70e5a +4356,de798e96 +4357,85f5a19e +4358,2cb6d717 +4359,14b529b9 +4360,8d8f5686 +4361,a19f80d0 +4362,bb782162 +4363,9c8ed9d0 +4364,4cba55cc +4365,6d963c56 +4366,059ec23b +4367,b34847fd +4368,364493b0 +4369,74b91b40 +4370,2749ac0c +4371,807c2ad2 +4372,7044f69b +4373,6edc44d3 +4374,74a8c4a6 +4375,c72b11ef +4376,9dc87d54 +4377,be758399 +4378,3e561ce3 +4379,6f22f8d2 +4380,1a218f63 +4381,fc58a90a +4382,22e4810e +4383,7f829461 +4384,b2d49d08 +4385,df98cd16 +4386,d155234e +4387,a87dc51c +4388,16dbbf34 +4389,1b4ceadb +4390,2396e7bc +4391,eab40a85 +4392,bd6f926e +4393,278b225b +4394,a9d615fb +4395,221ee939 +4396,11f94681 +4397,723c0690 +4398,89c1ae4c +4399,47e6cb7c +4400,63b829b4 +4401,6cffe32b +4402,d8ead1a7 +4403,54b92d9f +4404,c05ec628 +4405,d2c22fd1 +4406,bd7da539 +4407,20088bba +4408,0e25c71c +4409,865b4987 +4410,d7a6262d +4411,f1977bb2 +4412,41b4265d +4413,39cb49db +4414,f8cc6725 +4415,72eaecf0 +4416,b114ce91 +4417,788c888e +4418,9759efb4 +4419,0078440c +4420,d154645d +4421,779998d8 +4422,29291392 +4423,632e4d33 +4424,fa9997e8 +4425,44edc09d +4426,b40ea9a2 +4427,2af261f9 +4428,c2e3c48e +4429,652b9b98 +4430,cc7255df +4431,eb9229cb +4432,3126eb6a +4433,55a3a057 +4434,969cd899 +4435,3ff95bce +4436,7db20a58 +4437,ecb609dc +4438,7d9bf138 +4439,02ebff77 +4440,c5d76b08 +4441,adeef511 +4442,095b3e7d +4443,7d08e634 +4444,30b84816 +4445,ff887fb5 +4446,e2b39e5c +4447,4d583e43 +4448,d281aabb +4449,df23d1dc +4450,515b6c66 +4451,6c87d62e +4452,0b277454 +4453,15126382 +4454,5545ddb6 +4455,f6096b4d +4456,36c21ad5 +4457,18cf763a +4458,1958bd87 +4459,49609048 +4460,5217e05f +4461,dd3a92d2 +4462,8d6f2b67 +4463,e3cc6e2e +4464,17f72407 +4465,d56e59a8 +4466,316e453f +4467,f6cf2a06 +4468,fa24723d +4469,f05cfe1e +4470,6f3f026c +4471,56ca201c +4472,ca08f900 +4473,55c471d4 +4474,42c7c5e5 +4475,4f3a3f88 +4476,e0e8c1d3 +4477,3858172e +4478,f0a63a4d +4479,b83859dd +4480,1c91c29b +4481,817c4bdc +4482,00989399 +4483,53a3f30b +4484,26db8ca3 +4485,fbe24f2c +4486,843a6041 +4487,c3576f64 +4488,1150777e +4489,ed2da41f +4490,c57be2b5 +4491,0a4e4878 +4492,dd0e7861 +4493,18b26d8a +4494,7ad1f0a9 +4495,93816741 +4496,e9648ebb +4497,13b9151d +4498,bc12414a +4499,059c44f8 +4500,db713424 +4501,6fe2561f +4502,cc703a1b +4503,6fde5e3f +4504,910f71a2 +4505,c8343e4a +4506,94a5159a +4507,e1a71d45 +4508,438df2b1 +4509,1495d4be +4510,bb0af172 +4511,9a86bd80 +4512,a2957361 +4513,fe5b1efc +4514,f02d9ebb +4515,6956fad2 +4516,8a0f67f9 +4517,fc6b41e2 +4518,13c64f2d +4519,a6cb30e9 +4520,d8ed6757 +4521,e1c006bf +4522,cd205a88 +4523,ab41c765 +4524,89e3721e +4525,128559fd +4526,1f331650 +4527,1b8ece3e +4528,89db5ac3 +4529,b844c38e +4530,51fda4ba +4531,4d293f11 +4532,f3afb20a +4533,6d3fff67 +4534,a9f11b4b +4535,747cf067 +4536,515b47cb +4537,87fb3d1b +4538,c05ed4a1 +4539,05257e28 +4540,b3dbf3e4 +4541,e99b98cb +4542,c0643e47 +4543,7a2a4b54 +4544,cdec9f94 +4545,3fb8c11b +4546,53c93cc6 +4547,552d566b +4548,cf184948 +4549,622585a0 +4550,963e8a54 +4551,e22cf611 +4552,ebf9ae00 +4553,8d332642 +4554,49cb613b +4555,7ac8c690 +4556,f1877287 +4557,e7700d8d +4558,9c0e00eb +4559,c7682bb0 +4560,34af96e7 +4561,1e3bed61 +4562,be35b836 +4563,9d620ae2 +4564,b3f4a8a1 +4565,b9b97a33 +4566,ee050cde +4567,8a4df3e1 +4568,17827043 +4569,ee9ed591 +4570,b7c8e635 +4571,a0e329c5 +4572,49c3f64d +4573,299423d5 +4574,0b86c7b4 +4575,d0fe1db3 +4576,4bebb689 +4577,4453a168 +4578,ff4c2a40 +4579,6fbc57f1 +4580,ec537f27 +4581,649e9f4e +4582,0bd49fd1 +4583,e166b0a2 +4584,9e8f676e +4585,21934d38 +4586,3bbc2a97 +4587,c0f46f40 +4588,8bdd3dba +4589,9608923c +4590,29911d9c +4591,83b490c5 +4592,1c489502 +4593,83932676 +4594,f22131f8 +4595,e6f914a9 +4596,ec72e501 +4597,b69e3e50 +4598,d41c4004 +4599,73f19eb5 +4600,d067fe33 +4601,cc6530d6 +4602,f25b3782 +4603,184f3140 +4604,c953f14a +4605,5a32cebf +4606,427d902d +4607,2f2055bc +4608,0a09c9e6 +4609,684fe5a2 +4610,720e5fa4 +4611,2ad77d6d +4612,72b62663 +4613,8cb387fe +4614,fabdf014 +4615,eae3a451 +4616,95db7da5 +4617,3ed1fafb +4618,fcd5b43b +4619,aef48578 +4620,81842d32 +4621,a13bdb44 +4622,94e7ecd4 +4623,adada6db +4624,92cc7bed +4625,0ed1dcc0 +4626,8f00fdce +4627,6615fcb0 +4628,d7d67bc1 +4629,96615842 +4630,cb9ca7d2 +4631,db2b89bb +4632,778bdc62 +4633,bacaf8db +4634,47190abf +4635,3daa667b +4636,8cea1fa7 +4637,9ed1b8ab +4638,64409438 +4639,3b32afbe +4640,68d6841c +4641,a34a4c60 +4642,7645e5d4 +4643,605a53fb +4644,22527486 +4645,d934e160 +4646,0753bb85 +4647,1af4980f +4648,883de230 +4649,5026ef7e +4650,be5e5191 +4651,19aa4a09 +4652,8a0cd3f1 +4653,6e7232db +4654,f02209a0 +4655,6c03c356 +4656,d9eef37d +4657,57b8d875 +4658,b79972e2 +4659,f9226e94 +4660,0790b9b3 +4661,8d57d5c3 +4662,586029bc +4663,666fc032 +4664,cbeb85cc +4665,7ca82f7b +4666,f0ca7ab5 +4667,48306131 +4668,ac31c399 +4669,6780e747 +4670,71dbb470 +4671,aa00a2d5 +4672,3389c19f +4673,e0460fa7 +4674,ee91e29a +4675,be20a9fb +4676,57602a0d +4677,c96b5f3c +4678,ee924170 +4679,348bc601 +4680,7a53c9c6 +4681,d0989cce +4682,ac04d86b +4683,5d63d2a0 +4684,64be0440 +4685,ebbf426d +4686,db353278 +4687,de0df3a3 +4688,3bf3c2d1 +4689,2d473109 +4690,29dd4b06 +4691,f8be3eff +4692,eb815bbe +4693,d6e9b08f +4694,b0d39aff +4695,21a8ff11 +4696,d0e4314d +4697,9c796c42 +4698,cde63aec +4699,5364952f +4700,962cad4f +4701,99ff3a36 +4702,2132bf7e +4703,c89b7694 +4704,6803b07c +4705,64014ef5 +4706,071ed56f +4707,028d1c1f +4708,d6aea1f9 +4709,16217d80 +4710,466a3c8c +4711,8f2bdd15 +4712,8a32fefd +4713,1752be2e +4714,0ed30c25 +4715,a44ddedb +4716,d8e08afa +4717,436b96ee +4718,9ec310a1 +4719,d7b80bb5 +4720,36f55d6c +4721,6da30b51 +4722,5e948acd +4723,32a388ab +4724,2e97562f +4725,03a87e27 +4726,f744e448 +4727,55ef6774 +4728,ea4945e7 +4729,9b61bb62 +4730,10a9ee03 +4731,f5b28051 +4732,f376ee85 +4733,f3274dfc +4734,76abb0b0 +4735,2aba8ccb +4736,8b810f9f +4737,c44ff730 +4738,a33cef95 +4739,fbfeba5b +4740,c45e3b04 +4741,b198648d +4742,0a498402 +4743,0b29f6f7 +4744,c890fec3 +4745,ffb4c6a4 +4746,0c4256bd +4747,6e0ac565 +4748,4f3ab79b +4749,c01c3325 +4750,8d022a3b +4751,2c014762 +4752,3fbeb53b +4753,01700361 +4754,c5612408 +4755,6449e12f +4756,63c0a641 +4757,506f1ba3 +4758,7aa494f8 +4759,98a5b60d +4760,26121434 +4761,34abf37f +4762,8dd79b1c +4763,54f2f306 +4764,9ddccdd8 +4765,7f310dad +4766,e0c0f966 +4767,3e737caa +4768,8703f392 +4769,ee3d2cd5 +4770,204a19ae +4771,e7a894a7 +4772,27d693a5 +4773,c42b6ec0 +4774,2cee952c +4775,24636baa +4776,3d977b0f +4777,c46e877b +4778,19eeae25 +4779,3835e5db +4780,38e38569 +4781,78a4e722 +4782,9c085541 +4783,3b3c0421 +4784,af30f6d0 +4785,405ce8df +4786,82c990ca +4787,654a9046 +4788,1a738e40 +4789,72207d30 +4790,f6a5e07d +4791,1ee9f84f +4792,6d925cf1 +4793,26432930 +4794,a1b6375f +4795,7b2f9e94 +4796,0a349075 +4797,42b7f952 +4798,ce6a931c +4799,4155a0a1 +4800,aad78447 +4801,abe815e8 +4802,35678b51 +4803,33f18176 +4804,ac88b819 +4805,55bd28da +4806,e5c46b22 +4807,e4ea109a +4808,840456cd +4809,01960d5c +4810,8b81281e +4811,e1005a3a +4812,6906e3d0 +4813,e969bade +4814,0a80c33b +4815,9908bf29 +4816,f5a53b17 +4817,03d913ee +4818,b06c899f +4819,2435f2f4 +4820,2e5f239e +4821,df544859 +4822,438de077 +4823,3596096b +4824,28109e02 +4825,8896d8ec +4826,e6ffee41 +4827,87fbb19f +4828,f1e688e5 +4829,74e1a2b1 +4830,b55b768d +4831,2c5bc9f4 +4832,5eb4337c +4833,735d8cce +4834,28fa4929 +4835,51c8ec77 +4836,b21dd1b9 +4837,b56bad1d +4838,97194faa +4839,ac0c651d +4840,521fb601 +4841,b0138319 +4842,fe4ca6fb +4843,2f6e6fd9 +4844,4fa81135 +4845,d8f658f0 +4846,015c31e4 +4847,e4359f30 +4848,20c61fff +4849,5a49479b +4850,9e8b21af +4851,1acb7789 +4852,860f3afe +4853,31491976 +4854,84973d65 +4855,ef5ca47f +4856,a2b9a02b +4857,dc5734e4 +4858,37552139 +4859,5824cb00 +4860,65dd4d3b +4861,054bba40 +4862,272f8d7e +4863,91026d9d +4864,721890de +4865,585a36ce +4866,63258a5b +4867,6a875b26 +4868,313a247d +4869,8b78f661 +4870,e5f8955b +4871,2a7dd236 +4872,d5addd00 +4873,0ac4a272 +4874,7d679ffd +4875,69d06090 +4876,90e8f9a6 +4877,e7dc0b77 +4878,f936e936 +4879,a3af207e +4880,b7994eee +4881,bad46d52 +4882,8328d092 +4883,9078e60e +4884,590014a8 +4885,2bbbd83c +4886,6841bbab +4887,7ce68bef +4888,61175f6b +4889,16fa4080 +4890,759df37d +4891,6df24001 +4892,836fe52b +4893,6351804f +4894,0c9a7eb9 +4895,ddb3d25b +4896,4280b60d +4897,e804b2f7 +4898,fc428b52 +4899,568949d6 +4900,ba86c331 +4901,6615bb7b +4902,29acc7a0 +4903,22b803ec +4904,fafb2c60 +4905,3247cf25 +4906,0bf1059a +4907,8e77268d +4908,791e0856 +4909,8990b4d5 +4910,3affc68b +4911,8647c008 +4912,054a2bc1 +4913,4762dea9 +4914,68481b38 +4915,baf93767 +4916,4c408dee +4917,227935c5 +4918,a8ab0c2a +4919,ffaf5c9e +4920,674ea4d8 +4921,47277205 +4922,97e8a622 +4923,a8de77df +4924,878e46ce +4925,acbde3dd +4926,50c21d8a +4927,99cb5dba +4928,840cd684 +4929,06129647 +4930,b8009717 +4931,45997758 +4932,0cbf62e4 +4933,ffa74d3f +4934,39ed70e4 +4935,a4cc84bf +4936,52756c48 +4937,24084643 +4938,1b9e549e +4939,43c2a3c1 +4940,5a7c6ac1 +4941,e44b6bc3 +4942,1e5cba8f +4943,5af608af +4944,3ef7e355 +4945,d6107c16 +4946,83d2ab36 +4947,84807710 +4948,00c74fc8 +4949,ff7021bd +4950,375a3ee8 +4951,591930f6 +4952,24060467 +4953,dc389d8e +4954,865375e4 +4955,938966de +4956,0ea1605c +4957,b306ba18 +4958,db196dea +4959,75218c73 +4960,43546555 +4961,29a26b71 +4962,689ec6f5 +4963,c87f697c +4964,2c3368cf +4965,b369c4b6 +4966,75ab3180 +4967,580b7ad5 +4968,8e4a6dbe +4969,1affefb7 +4970,ebb2e88f +4971,cd7f7779 +4972,5fdcdeea +4973,b62a5b4f +4974,c4cf5aa7 +4975,94b3c149 +4976,6f46ea41 +4977,a2f6ec38 +4978,af250b4b +4979,146437b7 +4980,9918124a +4981,b0093c9d +4982,4d678648 +4983,f3092637 +4984,1ff52753 +4985,adf906b9 +4986,1b3536a4 +4987,62af16f5 +4988,766f4729 +4989,6fe27072 +4990,700187e4 +4991,a8c05ef9 +4992,f6838c16 +4993,a3550c1c +4994,d394a5aa +4995,f7de9857 +4996,6558b35a +4997,b887f6a9 +4998,81e88314 +4999,36eb5da2 +5000,8e982b95 +5001,23606139 +5002,ddccdc4b +5003,b0c60fd1 +5004,5a837b9e +5005,5f7ed1ac +5006,1e0188ae +5007,918e07bb +5008,12d00eec +5009,66d6bfb3 +5010,e0f36316 +5011,6b4a5d22 +5012,f68dcc63 +5013,b649533f +5014,aced138c +5015,51556752 +5016,af95695d +5017,bfa5af04 +5018,841eadd6 +5019,46debc4a +5020,5c016f10 +5021,442a063b +5022,1113b653 +5023,72407358 +5024,28bd3b2e +5025,a439b74c +5026,7f8599fb +5027,ce14bf48 +5028,7cac8f52 +5029,89b1ddca +5030,5e433c64 +5031,b3656184 +5032,7fb0ec90 +5033,004e3b27 +5034,44cc9111 +5035,9e88b85e +5036,a9798aa5 +5037,642691a6 +5038,4c3c0995 +5039,71551835 +5040,9460aead +5041,3dec173b +5042,9075f34a +5043,3bf45c1d +5044,441f1888 +5045,aff89ffa +5046,b192890a +5047,957ffe34 +5048,e8c3c6fe +5049,d88ffc29 +5050,5ada9575 +5051,e7ca51e2 +5052,716d6162 +5053,9b4a81f4 +5054,10415ec8 +5055,e9253b43 +5056,e9610d88 +5057,7112dd87 +5058,9bef0707 +5059,395ffc7f +5060,3e21f4d7 +5061,f48c589c +5062,e751c04b +5063,b8bc4351 +5064,17e521c9 +5065,cb14f639 +5066,94e4d100 +5067,d80c361a +5068,bdcc8b88 +5069,79657fba +5070,38c71554 +5071,eba7bd30 +5072,e7a92c2f +5073,2e2fa916 +5074,d8367d8a +5075,994ca611 +5076,aab7f117 +5077,0a77af6f +5078,fbe0cd4e +5079,353d1529 +5080,bc1bd5d8 +5081,84df689b +5082,470983ff +5083,1bdb0288 +5084,c3396b74 +5085,e2090055 +5086,ac1cf806 +5087,daec2158 +5088,262abb27 +5089,fa3655be +5090,8f52ad69 +5091,7d817b3d +5092,90280c02 +5093,746d7fc0 +5094,a23df21a +5095,40bea67a +5096,ef4111ce +5097,3ab63a7b +5098,18c0e0fb +5099,081d0954 +5100,8a73c73a +5101,2257f5ad +5102,a97b26e4 +5103,618e71ce +5104,a52077b7 +5105,22a0681d +5106,f96a8292 +5107,f21a3dfe +5108,73b631f2 +5109,ab0a54a3 +5110,3c50cc0b +5111,48877ca2 +5112,2352babd +5113,15f2c022 +5114,a1ef540a +5115,c7dc48dc +5116,3867cfa3 +5117,d7565cdf +5118,8fea5b04 +5119,b48ae612 +5120,7901809e +5121,0a7ebdc7 +5122,82484224 +5123,823ac50b +5124,2ce38cee +5125,0cefb5c8 +5126,e4fbfacf +5127,83fd1eec +5128,fd1650af +5129,8a24cf48 +5130,03469bdb +5131,99c6bd53 +5132,55a83d82 +5133,7f329102 +5134,2dc368bf +5135,d6142a58 +5136,f4c84690 +5137,bac7a55d +5138,880e5c57 +5139,5d66e494 +5140,6d514d36 +5141,75ab7101 +5142,29577f44 +5143,cf3ae2c0 +5144,62fb9f06 +5145,b5849448 +5146,f8990be6 +5147,9c16abf8 +5148,3300add7 +5149,b7300c41 +5150,939b2d56 +5151,ebd3194e +5152,9d42ac75 +5153,25edaaa4 +5154,7b8d641b +5155,8894863b +5156,42845edc +5157,efe79e2f +5158,fa2c2212 +5159,55c41e37 +5160,699292de +5161,12067a71 +5162,a612795a +5163,61f5e92f +5164,14a656ff +5165,05c2c7b7 +5166,8a1bce62 +5167,3e5197a4 +5168,4f84320b +5169,0bbad705 +5170,53d7f415 +5171,10653d24 +5172,105f5a21 +5173,df23a4d8 +5174,f6957ab9 +5175,c5ed95e2 +5176,a74a8887 +5177,7c776470 +5178,21e7f11f +5179,c5adeddc +5180,32fdc590 +5181,43fe0eb8 +5182,ceae6b57 +5183,6e7ced2f +5184,8a4aec9d +5185,fc0fc4f1 +5186,9deac3c5 +5187,ed66ad80 +5188,d0839adc +5189,f74cbf8f +5190,f6e5f2b4 +5191,1804bfe9 +5192,1e352507 +5193,ff61ab62 +5194,f1c6f7ee +5195,22df08c8 +5196,7cfd131f +5197,ac5d9bb7 +5198,44a63cc3 +5199,df24a49f +5200,987f740f +5201,dc2ce253 +5202,b4b77bec +5203,e0b97657 +5204,1a08d20d +5205,f69a8cce +5206,7358aab9 +5207,89f1f872 +5208,5bb27aea +5209,3c527c01 +5210,a4c46948 +5211,971665ca +5212,7c35489d +5213,5eb66ea9 +5214,a9414b86 +5215,c3bd19e2 +5216,f0ddb87b +5217,8ecfbcff +5218,de61e212 +5219,1e99f8dc +5220,4743956b +5221,fd173440 +5222,2517228c +5223,641871d6 +5224,b30a37f0 +5225,ad0cbd36 +5226,9c5ee4cf +5227,ae4c4a73 +5228,c02a5e03 +5229,4f5aba4e +5230,8031dd82 +5231,0e1a5c00 +5232,e6a7848c +5233,831c42b9 +5234,0ab4caef +5235,42ec6803 +5236,d950e96b +5237,c4744148 +5238,a976f704 +5239,c6a6d7de +5240,f3501f86 +5241,077f36d7 +5242,5ce63512 +5243,6a57904b +5244,880aac3a +5245,3fca7daf +5246,56b459c4 +5247,032be8a6 +5248,cb6ea03d +5249,d52a99d6 +5250,76ac6eb8 +5251,061e7c3c +5252,0605d4d2 +5253,7819c01c +5254,aed2840e +5255,5d4e1b28 +5256,9d7cc232 +5257,e9cbf7b3 +5258,36b3cefb +5259,9469af63 +5260,d76ae54b +5261,66df6568 +5262,d727138f +5263,01b2708d +5264,f98a30a0 +5265,69b60135 +5266,67ede46e +5267,8aeb1cb0 +5268,336a14bd +5269,2014e804 +5270,9677869c +5271,c59c9c2a +5272,029869c1 +5273,e62f2aa5 +5274,5cc74c31 +5275,ac8beaa7 +5276,ae866ec0 +5277,a4a8b18e +5278,ecbbbe78 +5279,3cfebed0 +5280,18ac56aa +5281,28489448 +5282,645d51b4 +5283,1a65fb6f +5284,1071dc82 +5285,1eba2346 +5286,3f34b774 +5287,a53bf2c9 +5288,7ef20c44 +5289,d3b51cbd +5290,00fbfc97 +5291,ea5e7997 +5292,17a85869 +5293,6928a9f7 +5294,39ca057c +5295,952ebcef +5296,b6159160 +5297,f89dc269 +5298,5664da50 +5299,48bb0e87 +5300,533007f6 +5301,33af2c3f +5302,26632ad5 +5303,f68b3957 +5304,0a59eb87 +5305,e950cd58 +5306,07f90f43 +5307,759e3b2c +5308,df2827b6 +5309,cc8625e0 +5310,adc18ae7 +5311,86db6bdd +5312,09a79bb2 +5313,724cbb42 +5314,83462563 +5315,0f8d9559 +5316,991b47b6 +5317,20666e1f +5318,b7364469 +5319,68085236 +5320,d37f8a1a +5321,98124d35 +5322,c25b900c +5323,f16edced +5324,fc9fb179 +5325,1f04aa79 +5326,f79ad9e0 +5327,03a8b374 +5328,b6f42cc3 +5329,b8515d49 +5330,1de98563 +5331,4fceb8cf +5332,359e0f5e +5333,0527e132 +5334,20ce2949 +5335,8c302ed7 +5336,dfda27c3 +5337,7c68ba5c +5338,77f00687 +5339,0337ddad +5340,c8fbbe51 +5341,2a685197 +5342,26ba9b07 +5343,1bed0196 +5344,0851d795 +5345,67a682bf +5346,ca5b6d30 +5347,ff734742 +5348,83c8ac8f +5349,4fd5691c +5350,bb8369a8 +5351,11f0384a +5352,a33be8de +5353,46ea22cb +5354,cea91b0d +5355,172f976a +5356,b5652cfb +5357,713ac5e1 +5358,eb207521 +5359,b088be17 +5360,93cdf80b +5361,10c58645 +5362,df6bd525 +5363,3930bf25 +5364,10902b46 +5365,ad6fc53b +5366,633952b1 +5367,8f38594b +5368,d88e6fb5 +5369,2a9315ae +5370,6a614fc5 +5371,8d74be0f +5372,c5b61014 +5373,aee2db09 +5374,6ca861c6 +5375,6ed08366 +5376,196db70e +5377,bf16cb59 +5378,2c21bc82 +5379,37510312 +5380,9ca743ed +5381,6201548f +5382,64a452f3 +5383,7b358be7 +5384,73cfd191 +5385,8274752b +5386,269a4128 +5387,e21a5938 +5388,d8efcef6 +5389,b765ac2d +5390,5168f437 +5391,82f74d0a +5392,713ee289 +5393,a4b24b06 +5394,0264a779 +5395,17ffb183 +5396,e460dc36 +5397,bd890a3e +5398,5cec2cca +5399,df9e7148 +5400,b9320826 +5401,7490dd4e +5402,dbd61c7c +5403,f45530e6 +5404,7296c6ab +5405,f9d0c90e +5406,640ebd7b +5407,eaba2c56 +5408,78b44036 +5409,aee33468 +5410,ec8823ff +5411,5791a40a +5412,edabc3a3 +5413,82687c47 +5414,05fbe879 +5415,ecf5fd7a +5416,5a9ae327 +5417,bd54a72b +5418,84471019 +5419,9a7d1f72 +5420,cb9a3a44 +5421,1d7805b3 +5422,b075482f +5423,f90fda89 +5424,f337d1f5 +5425,fe493b55 +5426,f4918805 +5427,1a277d41 +5428,607b2613 +5429,8fd0980d +5430,dde4cae6 +5431,e1f178d7 +5432,05d2b9df +5433,99d4bb1b +5434,1e9ace18 +5435,4c46e57e +5436,3f2e645c +5437,7112626b +5438,d1d91ca2 +5439,b0781ff0 +5440,6994afa3 +5441,d19a7292 +5442,f7c43e81 +5443,7fab06d1 +5444,29e54542 +5445,0de1227a +5446,120927df +5447,4faf7a1b +5448,26938a80 +5449,6929579b +5450,afc25634 +5451,f142d6a7 +5452,aa28e11f +5453,6ed53c90 +5454,9fd54c80 +5455,29c522fa +5456,9a4740fb +5457,bc8ad7ca +5458,944aa87b +5459,86f6b9e4 +5460,0e7a7103 +5461,e09e61b8 +5462,31cadd2a +5463,72538bce +5464,e2f24170 +5465,202e566a +5466,1844515f +5467,afb552b1 +5468,f7bb758c +5469,b2394e8a +5470,f9a74318 +5471,750a0b83 +5472,74dcca26 +5473,8616dc59 +5474,a9187d2d +5475,dd759522 +5476,5651ea56 +5477,2a24f80a +5478,e3669e9f +5479,92603257 +5480,844f53a1 +5481,0bf98a04 +5482,81c833e9 +5483,af81aafd +5484,77d657df +5485,9e77ec39 +5486,1b018502 +5487,8d812af1 +5488,6e4642b2 +5489,52a2ef61 +5490,c679fab4 +5491,af70515d +5492,c894a614 +5493,619139fa +5494,ab014466 +5495,4d8102a3 +5496,4f4a8804 +5497,67b9613b +5498,a59f712a +5499,48ef6734 +5500,4e5fcd2c +5501,25eb935e +5502,6c80e0be +5503,ca07ffc3 +5504,eb5f20a9 +5505,aa0ea59e +5506,18a9b53c +5507,03a345fa +5508,c1c5b8ed +5509,1dfe7b35 +5510,af476457 +5511,75e2efa7 +5512,e1d6a2f0 +5513,5a480359 +5514,fdbb99a0 +5515,8b8a7f2c +5516,870ca09d +5517,234b5593 +5518,5429db8c +5519,4b24fb09 +5520,fdadce06 +5521,3681b6fd +5522,ee77a9f0 +5523,b1068439 +5524,4de09dfa +5525,738f028d +5526,ecfde7e8 +5527,90f0d121 +5528,f9007b70 +5529,1e65cf51 +5530,06d5b4d1 +5531,16e4f121 +5532,5062000c +5533,600ac3bc +5534,72604f98 +5535,058dafed +5536,1c660434 +5537,4872ddf0 +5538,bd5ee51c +5539,d4f140ea +5540,40b800d2 +5541,6bdb5509 +5542,191d91ee +5543,d5db39d7 +5544,6660744d +5545,eb053909 +5546,43747ce3 +5547,033606ba +5548,8e5ad413 +5549,6353ede6 +5550,bea08846 +5551,9a61d04b +5552,85518dbf +5553,0f54cab9 +5554,0b012734 +5555,f7a26640 +5556,181a82b9 +5557,d3aefce5 +5558,6ced4cea +5559,93f2e365 +5560,916d680d +5561,be972e52 +5562,ee9ba4a9 +5563,0daff4f5 +5564,07d931ee +5565,379cc2a8 +5566,3dc6f4fc +5567,4ed57b8a +5568,ded18adf +5569,5f5b5cc7 +5570,2b2de679 +5571,d3fafbb2 +5572,f5d26277 +5573,9009d612 +5574,6fd432a6 +5575,f259aa54 +5576,54e8be20 +5577,abe523c5 +5578,89c92d93 +5579,c2bc57f5 +5580,c0fcf475 +5581,a943e1d9 +5582,40b7dccd +5583,5fc8720f +5584,11ab9be9 +5585,518ee0a3 +5586,fb23f8a9 +5587,310d6dae +5588,e96961cc +5589,9e6cb250 +5590,7b8c3549 +5591,ffd398f2 +5592,45d3ce0a +5593,0d8dd286 +5594,eadaab2d +5595,c7cf65fe +5596,c28e005a +5597,32683f0d +5598,8d3a2b5e +5599,74339b8b +5600,08efed37 +5601,c4c721fd +5602,3574260b +5603,834ba4cd +5604,19631466 +5605,333068ad +5606,0e9deec0 +5607,c8fb904b +5608,72b0ec78 +5609,9231c978 +5610,167dcba2 +5611,585f607a +5612,42506d3c +5613,042f75cf +5614,239b0273 +5615,6bdbf60e +5616,d03b31c2 +5617,b853f8a4 +5618,28e4c7fa +5619,4de56296 +5620,ceed12c7 +5621,515da46f +5622,91147e61 +5623,0602a8d1 +5624,95db6f38 +5625,c1f9e1f8 +5626,e6a237dd +5627,2ede1103 +5628,b1ab09fb +5629,f1a0aba3 +5630,91c8f339 +5631,89db951e +5632,455cdb9b +5633,3139a503 +5634,5e84894f +5635,3b22b8c7 +5636,aa7b3398 +5637,747726a8 +5638,07922617 +5639,ffacc8de +5640,87264cbb +5641,673a946d +5642,59fa3069 +5643,1d765f2a +5644,9d9f88d7 +5645,6da532be +5646,35804bdb +5647,a1b46a79 +5648,40f93b8f +5649,12d852e5 +5650,39f52045 +5651,e51de352 +5652,822c8dcc +5653,36a43afd +5654,39640dfe +5655,5351573a +5656,f2432da3 +5657,c77b6315 +5658,62ee3959 +5659,1254ee58 +5660,0e099697 +5661,92ff082d +5662,6c25e474 +5663,5f1ab06b +5664,c6f3b9ca +5665,7a890627 +5666,79069f42 +5667,39d2098d +5668,59e2fc0a +5669,cd079e83 +5670,c897a420 +5671,7dbe768b +5672,f977ad49 +5673,4576d1ad +5674,3b6fb21e +5675,dd8cd151 +5676,efc072ce +5677,1e396aae +5678,29951b8c +5679,2059b8a9 +5680,91d36c99 +5681,6df7b439 +5682,114fac2d +5683,079f09e9 +5684,280f881f +5685,fbc9c633 +5686,ed324e0d +5687,5247f211 +5688,29ed01ad +5689,a4ed15d1 +5690,e1e61df1 +5691,156c746e +5692,0324b6c1 +5693,e494b16e +5694,d07a13ed +5695,3add5514 +5696,8d7ad0dc +5697,cfde6fce +5698,c826ff22 +5699,dab91d48 +5700,5b33c3e5 +5701,3a3a8e70 +5702,729b5594 +5703,b271779e +5704,83bb693a +5705,27e4333e +5706,4cbd0d17 +5707,7320872f +5708,d3fe0225 +5709,1f937df4 +5710,665b4c22 +5711,ffcdf2cb +5712,0e2a90a7 +5713,ef447da7 +5714,ff92320f +5715,6e818ba5 +5716,c03f92a5 +5717,a3597a64 +5718,974c249d +5719,f10603d3 +5720,9d69ca09 +5721,74914cfc +5722,1054bd0f +5723,4807f275 +5724,59ba49ff +5725,ec98409e +5726,b99f5e42 +5727,6482cbc9 +5728,d29b51e8 +5729,f1185c89 +5730,67c0db50 +5731,37a59fc7 +5732,1119d075 +5733,f516edfc +5734,c9e800fc +5735,6a68a384 +5736,6d3f28e1 +5737,68b03bf1 +5738,73adbed4 +5739,7e9b2b2b +5740,3cb46e20 +5741,4edb27ea +5742,eb6648e8 +5743,90d8b0b6 +5744,46d56478 +5745,693e62d5 +5746,fff6f4b0 +5747,e9c3a294 +5748,29092d31 +5749,897bc55d +5750,b39d3b30 +5751,81f218e9 +5752,0969c4db +5753,9f8df871 +5754,33ef5d21 +5755,1854a136 +5756,c4e8158c +5757,ccc3f6c3 +5758,adc1fe9b +5759,d72b720a +5760,7334d21f +5761,8fc8551d +5762,e0bce64e +5763,e7fe2efe +5764,20ff730e +5765,4f208ad2 +5766,0ce07039 +5767,9aeb4aa6 +5768,1318c8e6 +5769,9f5db4f4 +5770,cca89675 +5771,cc35ff6b +5772,c01731c8 +5773,995fe928 +5774,e1304c59 +5775,ac0819b3 +5776,2dad5f7d +5777,62573197 +5778,e8fd2c15 +5779,9a193ace +5780,871bd4a8 +5781,b13f53a0 +5782,f99f6d48 +5783,8ca6fba1 +5784,b630a9d9 +5785,4d48cb6e +5786,0c6bd000 +5787,83508498 +5788,fabfe116 +5789,ebc8018c +5790,110f139e +5791,39aa8ac2 +5792,cfdc529e +5793,fe674ac3 +5794,c3054bfb +5795,1698b2cd +5796,94cce665 +5797,778f533d +5798,34056137 +5799,63d996dd +5800,63b4d92a +5801,c3c6ff6d +5802,4ed59fcc +5803,69aad8fc +5804,4fc043b7 +5805,6064d469 +5806,5fcf7de0 +5807,b4dc3bc4 +5808,6ce9c12d +5809,550c3f94 +5810,7414e0a4 +5811,37444c5f +5812,b995e4a0 +5813,fd50b0da +5814,079b3118 +5815,a1475a9d +5816,6d715faf +5817,64d179f2 +5818,6646f61e +5819,dffba7dd +5820,c7edc148 +5821,250a20be +5822,0b472dd6 +5823,abd12956 +5824,965587e1 +5825,874bfd81 +5826,bee37d0b +5827,8dbc8b05 +5828,9b4ba4a2 +5829,de4b67ae +5830,1520d89f +5831,deacec52 +5832,e7d4b473 +5833,6bdcfc95 +5834,76d94f89 +5835,270807f5 +5836,49d0bc6f +5837,e8559b2a +5838,f6ac5511 +5839,0ef5c96d +5840,1f556d0e +5841,78d87d7b +5842,30bca194 +5843,f2ca58d7 +5844,4195b869 +5845,c91ebb7d +5846,04246d83 +5847,ed3e618d +5848,f8b80a22 +5849,10292a2b +5850,ac1a3606 +5851,bed3e7ad +5852,1ac142b8 +5853,b0a14ac2 +5854,6d62bc2c +5855,089488a4 +5856,17069798 +5857,ab6d269f +5858,79041b0e +5859,1a158df5 +5860,9e72b09d +5861,1178d566 +5862,b2c3efb8 +5863,1285adaf +5864,bd6fdc05 +5865,5f5cfcec +5866,79b3843e +5867,4e551b8a +5868,d62419df +5869,7d1fb7b6 +5870,74ba9abf +5871,201398b8 +5872,2bc37397 +5873,0c089f21 +5874,407e9716 +5875,191a1a80 +5876,7b01cdcb +5877,6d3aa57f +5878,d196b40e +5879,168c1f35 +5880,b5d888a0 +5881,9ad246b2 +5882,0d1b44a0 +5883,4102ee39 +5884,03ea2b80 +5885,74e1cf14 +5886,f8ca4790 +5887,eefa4565 +5888,84b2f8a9 +5889,8d49ec13 +5890,ca5c049e +5891,44ca571d +5892,42799ea7 +5893,d26a3955 +5894,036cb4d1 +5895,0ddafc32 +5896,bd18cdb5 +5897,fbe31e53 +5898,ed701e54 +5899,4833038d +5900,ad529489 +5901,b02b3e52 +5902,cfea3370 +5903,dd23a3c7 +5904,87f77d9f +5905,9db96296 +5906,f53db540 +5907,4bf4f44b +5908,fbfbfbf2 +5909,282365d5 +5910,eb5f733d +5911,5e31f510 +5912,3a40b1ce +5913,104c7bbb +5914,b556f275 +5915,7d46586c +5916,f7b239c7 +5917,dc99f44b +5918,64ff1ee6 +5919,4b3b4014 +5920,c2ffed68 +5921,89c5cb71 +5922,a42fe85c +5923,00448e73 +5924,414e45b7 +5925,18501ae1 +5926,5d7232cc +5927,f0cc5440 +5928,61ed7be8 +5929,6573845f +5930,2618cbc5 +5931,ea2e37a8 +5932,11a80204 +5933,bc33d45a +5934,930bc749 +5935,44f47333 +5936,aad66c20 +5937,f929df1c +5938,0cd0bd4f +5939,5ffdeac4 +5940,e5894efe +5941,77e6c839 +5942,27625582 +5943,70784ede +5944,261ff1cb +5945,f9b60c47 +5946,fcdb76d0 +5947,b425b768 +5948,bc16bc37 +5949,e00d92e0 +5950,e2420dfb +5951,9890268c +5952,589756aa +5953,221bd8bf +5954,bcaa3ee8 +5955,0d2ffe18 +5956,28d234ee +5957,bb5c9b4e +5958,1e3e312b +5959,432b8acd +5960,89099d6d +5961,878912bf +5962,afe67649 +5963,2ea0f405 +5964,a2a5007f +5965,28b698ae +5966,cb1b7bac +5967,691c96fe +5968,47d4242c +5969,a26c876c +5970,8d0bc2b7 +5971,92d6342e +5972,917a2d06 +5973,5a4cfa30 +5974,f3cbc41f +5975,83b8b91d +5976,626fc8a0 +5977,b9bdce2f +5978,639d3267 +5979,08397089 +5980,7352b897 +5981,94d9cec2 +5982,c407a75d +5983,cf727718 +5984,6e5047a1 +5985,3b9a904b +5986,b249e5bc +5987,b8535ddc +5988,97b44d8b +5989,322cbc0e +5990,7173c7e1 +5991,80e170c8 +5992,b4cfc457 +5993,ff5985ec +5994,75a4c502 +5995,40fb3373 +5996,ae9a0ecb +5997,1e795f92 +5998,bc453606 +5999,b5bd0fee +6000,02a535dc +6001,3b9abafe +6002,d4930ea5 +6003,625aaeb0 +6004,2260e4f7 +6005,ea33a3e3 +6006,864d4c0b +6007,edbf28d0 +6008,ecc05199 +6009,8e0c7f8c +6010,1bdf36c5 +6011,b693370e +6012,50963ac2 +6013,6f969ccd +6014,4c609728 +6015,3d3a2f4b +6016,1a4dc1c9 +6017,eda66ae3 +6018,b98e41c2 +6019,6d2fd3b8 +6020,38d1ee76 +6021,1ef1a073 +6022,2e0565bd +6023,0b7e3b0c +6024,f08c59b8 +6025,06b1e1b2 +6026,987d418e +6027,18f26ff3 +6028,0f05e8cc +6029,5c617279 +6030,ac789303 +6031,8a4cb39d +6032,1a30de40 +6033,ad852792 +6034,26b2eab4 +6035,97d35a59 +6036,f251d46d +6037,67a1b573 +6038,6c937942 +6039,69277dfa +6040,f2840432 +6041,ed78cdcd +6042,4dacc700 +6043,bc74769a +6044,9ecf47c2 +6045,6bac0f99 +6046,f6921ef7 +6047,8b764e20 +6048,242aafcd +6049,56f879ad +6050,36bbf034 +6051,30681ccd +6052,6f0acc8a +6053,767f623d +6054,454fbd2e +6055,c90d0db8 +6056,5bd5c69d +6057,80c7d93b +6058,1b789709 +6059,66fe7dc7 +6060,65a4879f +6061,f434b8c5 +6062,7d275e6d +6063,8850ef7a +6064,cb7109d2 +6065,2bf00165 +6066,82cf786e +6067,a2fc4354 +6068,d3a69d95 +6069,0c29fcc0 +6070,786f8419 +6071,2210d82a +6072,7b9f7fad +6073,2bb2bcdd +6074,c2bbf41f +6075,8dec98cb +6076,ecfffb44 +6077,8b06f1f8 +6078,6321ff26 +6079,d6e77928 +6080,b12574d2 +6081,3088d707 +6082,6e936086 +6083,9896fab5 +6084,c2c5ac5e +6085,a83e624b +6086,8d9dfaf7 +6087,a19efd39 +6088,ad5c070d +6089,07abb3f6 +6090,a53ec4cd +6091,6ccf8ea5 +6092,77703134 +6093,8a7d84e2 +6094,a5c45df2 +6095,1b60b542 +6096,9976b965 +6097,45f0e9fd +6098,b7809c31 +6099,86143116 +6100,ee785c9c +6101,1dd97cca +6102,58b0694d +6103,7c6012d5 +6104,6c520ac3 +6105,d291cf96 +6106,05c24544 +6107,ee9bf116 +6108,2af10f91 +6109,d7a80df7 +6110,65f55678 +6111,d16ceb28 +6112,a433ead5 +6113,e16341e4 +6114,075f3eb3 +6115,f95ceb2a +6116,c6cc2b16 +6117,1c1cdd95 +6118,57ecb4f0 +6119,306ddae8 +6120,986215e0 +6121,1fb4b569 +6122,2afd3395 +6123,25004ff8 +6124,548d9e4c +6125,b1520d27 +6126,f4981e9a +6127,3958c7af +6128,8a7e6221 +6129,bed43d54 +6130,de2305b6 +6131,1d498da5 +6132,0a4c2302 +6133,ab495241 +6134,603782e5 +6135,20929562 +6136,8573e173 +6137,64464002 +6138,3a6d6586 +6139,d9fa05fa +6140,dd1749d8 +6141,4e1258e3 +6142,4582a494 +6143,119003f8 +6144,bc9340b2 +6145,cb24b65d +6146,7b2782c2 +6147,ad86df3d +6148,d49e45d1 +6149,296f0bef +6150,727950b1 +6151,c13bdca5 +6152,98bbcd0a +6153,ae1f0fec +6154,c04e95ba +6155,d279e7d5 +6156,24cb62a4 +6157,ce805bd0 +6158,f5ffdfdd +6159,0546970d +6160,5a59d479 +6161,5f3feebb +6162,3d39a87d +6163,756495d1 +6164,6d70ab18 +6165,fe421cf4 +6166,db3ccf51 +6167,3d341b2d +6168,4fcc222a +6169,b2625ae3 +6170,14d439d1 +6171,d4299727 +6172,c65cb466 +6173,9a3edd6c +6174,f3344c63 +6175,64dddf00 +6176,13d4867d +6177,b7d929e6 +6178,43d48fe0 +6179,4d8766c0 +6180,7e238543 +6181,a8852115 +6182,bce988ab +6183,b6e2bf7f +6184,913fcd7c +6185,96418853 +6186,6fc132c2 +6187,a3adc7b6 +6188,de4a754b +6189,864424dc +6190,2a270f7d +6191,38242cfc +6192,decf458a +6193,45068edd +6194,a9ab3c3c +6195,f26c5cae +6196,9ce429a4 +6197,3194e10f +6198,de3edb96 +6199,0caec80b +6200,4a72e552 +6201,b0b170e1 +6202,19a07435 +6203,cca86f95 +6204,972dca56 +6205,9cd6c411 +6206,f8d5d2ac +6207,0f83fda2 +6208,83ce4d77 +6209,4011c0a4 +6210,1491e451 +6211,84a1bddf +6212,9d29ce5a +6213,3c07dc66 +6214,0a859302 +6215,6a73a730 +6216,cefde4e3 +6217,ad673941 +6218,04802209 +6219,275e86f9 +6220,1443ca46 +6221,33e7fbf3 +6222,738e5809 +6223,0e3e3a15 +6224,2cf96bb9 +6225,5cb1bddd +6226,4ec0a71a +6227,cb60ed09 +6228,a0b76249 +6229,9b6053ed +6230,3050d044 +6231,8ff0e1b4 +6232,63effecd +6233,ba0e7700 +6234,1bf92d60 +6235,bfbe496f +6236,87a42329 +6237,41f69e61 +6238,a4ce67f3 +6239,8216261d +6240,e3dc0708 +6241,7acf7dca +6242,60061050 +6243,8c5da68b +6244,6f38abc1 +6245,4dd356be +6246,916d7368 +6247,c02ba91c +6248,2ef84585 +6249,d2e539cd +6250,95226752 +6251,3282a25e +6252,778e2519 +6253,c3a17cbf +6254,700190e9 +6255,0b8f6b09 +6256,90df9b81 +6257,1905f94a +6258,759d6597 +6259,49bdb91b +6260,8e4e0b09 +6261,19d3116c +6262,5e3eff1a +6263,269929e7 +6264,caf92942 +6265,862caa20 +6266,e55e91b5 +6267,0f3b6af8 +6268,2854c597 +6269,289e075c +6270,be27dc55 +6271,c34e422e +6272,43432a16 +6273,18c72cff +6274,2af1f756 +6275,877bc9ce +6276,cebd0b3f +6277,99d9b748 +6278,357312b3 +6279,037b6268 +6280,817e9592 +6281,74a51d86 +6282,c7333012 +6283,b31d6337 +6284,df8ab965 +6285,59272677 +6286,87ec737d +6287,f1f14c7b +6288,fc4364a0 +6289,6b97853d +6290,b2b4607d +6291,9c146903 +6292,e31d81f4 +6293,c9d2bcb7 +6294,9594de07 +6295,5b99b19b +6296,ba2e71bf +6297,47c22337 +6298,99dc1f4b +6299,bc4161e0 +6300,43c85372 +6301,1f843fac +6302,27866581 +6303,4b8e34de +6304,349a5bb5 +6305,0c461c4b +6306,aac0e3c1 +6307,bc42cb85 +6308,28f1f2d6 +6309,727a46d8 +6310,0e90a9ad +6311,4f54ad78 +6312,0c327cba +6313,db7791e8 +6314,661dcaf6 +6315,735eccac +6316,32500a9b +6317,adbc95c4 +6318,adc1483c +6319,202ae50a +6320,b9f1af41 +6321,c267169f +6322,3de69bd3 +6323,d657a1e4 +6324,8ad4d59d +6325,b47ab20e +6326,c7510507 +6327,995fe653 +6328,bf0201e9 +6329,56614054 +6330,2892a243 +6331,de903395 +6332,84d34f30 +6333,b20afa05 +6334,c56c1822 +6335,3a8ec6d8 +6336,13e87717 +6337,e45c3690 +6338,db39dbb6 +6339,72115a1c +6340,ef69978d +6341,400bd78a +6342,6c3cb59d +6343,f8d5addb +6344,40f91853 +6345,9b49beb1 +6346,b20c396c +6347,07c21a4c +6348,24d90b5e +6349,62543de7 +6350,c4d71592 +6351,91cd478c +6352,364b8f12 +6353,b7a0e781 +6354,34070ca9 +6355,c7de05eb +6356,596772a0 +6357,9b5aebc2 +6358,de9944cf +6359,b7b81c1a +6360,632dba3c +6361,e08cbb29 +6362,a7d3353c +6363,4c0a17b4 +6364,64aa0609 +6365,ac75155c +6366,ce485b14 +6367,af2c2b99 +6368,566eb0a4 +6369,d56e7860 +6370,7f8c1c19 +6371,7f463793 +6372,61ec0f5a +6373,e5fb5f17 +6374,81038723 +6375,28a5369e +6376,75e15053 +6377,9e2aa96d +6378,286f3227 +6379,0da7fa4e +6380,47188234 +6381,b6568241 +6382,36c0bf2e +6383,6d01ad19 +6384,d66bbdbb +6385,965ad9fe +6386,4f5e5d3c +6387,83b8de87 +6388,170d33ed +6389,9231452d +6390,95cb0d65 +6391,b8006150 +6392,c92d1933 +6393,38207b0a +6394,e0d6296b +6395,8b171188 +6396,233e8a92 +6397,7a8c90be +6398,9066e116 +6399,c1ea7ca7 +6400,6492319a +6401,684053c3 +6402,d6e5904a +6403,fed55664 +6404,932d0038 +6405,17e53043 +6406,cca939ea +6407,196de92b +6408,dd0d81a3 +6409,19b0d5e3 +6410,314b4cc4 +6411,91c1fefa +6412,eeda603e +6413,55cdea8c +6414,7bf2e7e6 +6415,81ac3fae +6416,f5b44147 +6417,60410990 +6418,7c1f57df +6419,11635838 +6420,27ea897c +6421,3ea43ac1 +6422,e97b781d +6423,75f74eb6 +6424,fda9f3ac +6425,8c15ab8b +6426,ab2d4dcb +6427,78c5e07f +6428,dfa500a7 +6429,5efa11fd +6430,2eaaf1c0 +6431,42a05816 +6432,10a52ccc +6433,a8c9102d +6434,e4fcd2eb +6435,6efa823e +6436,bfa0471a +6437,8623320f +6438,56675ced +6439,ff84d331 +6440,8465cc29 +6441,d1ade7a5 +6442,7808658f +6443,fc27bc56 +6444,3c658a42 +6445,3a863788 +6446,2e730889 +6447,42a64e2f +6448,78fa0444 +6449,b4263a04 +6450,2d4b1f78 +6451,1ef1cc86 +6452,b1f1fce6 +6453,56bee16b +6454,ab85ff74 +6455,d78b4aa8 +6456,7c51935f +6457,2c773f29 +6458,3998ee11 +6459,3c47fb36 +6460,87b9e26b +6461,ef1bd4fc +6462,faecb50b +6463,a559b6e9 +6464,33712751 +6465,962bc71a +6466,e73c88c9 +6467,6b68a4e9 +6468,e55b915e +6469,0d1afcba +6470,5aeec542 +6471,0e13d305 +6472,14b090fe +6473,6e2e71d1 +6474,951c1f18 +6475,9115eb9e +6476,04036a59 +6477,60f05c04 +6478,20e130ae +6479,b13327d4 +6480,e7a4b19a +6481,cafa4811 +6482,cb0d98c9 +6483,a3b13b6d +6484,4af12cde +6485,a63e9e5b +6486,05a6cfa5 +6487,9e770f93 +6488,8090263f +6489,2f835ce7 +6490,3d7cb451 +6491,dbe8a280 +6492,27004375 +6493,1106c834 +6494,a51d8fda +6495,4ae6b1c3 +6496,25202f57 +6497,384f7365 +6498,c748e782 +6499,30a00857 +6500,718999c0 +6501,febc0fcc +6502,c6caf145 +6503,dcb71836 +6504,63c5ba35 +6505,dd8df9e8 +6506,283b106c +6507,29e38d9f +6508,d10a9d75 +6509,32c57610 +6510,13087d4f +6511,bd7181a1 +6512,5704a6c6 +6513,5f7c6c26 +6514,851ff0dd +6515,5bb0cfd0 +6516,66598d85 +6517,2004a545 +6518,9f28f7cc +6519,40cda031 +6520,1552be6b +6521,a0445e8e +6522,0ed0881d +6523,7613a14f +6524,fd8a43f3 +6525,0440ba30 +6526,734fa2ee +6527,5f765a1e +6528,d37b1fbc +6529,f666a3b2 +6530,a3ecc240 +6531,f8f6f50b +6532,c46e072d +6533,b4df8ad4 +6534,926aec00 +6535,8fb1da00 +6536,1444257b +6537,cfa44262 +6538,ff269840 +6539,a95aa213 +6540,18985df7 +6541,1b35bb3e +6542,c7f41d43 +6543,6dd24106 +6544,adefd779 +6545,ce96b816 +6546,1941d62b +6547,59ce0fb9 +6548,a7f7ab83 +6549,55ef8f55 +6550,565bc0f7 +6551,912a8a75 +6552,cabf9836 +6553,912ee915 +6554,f707c6bc +6555,1be66af8 +6556,dd9bcd37 +6557,d6b13ecd +6558,b95ded1b +6559,a359441e +6560,5fffa430 +6561,836e037b +6562,1233beb1 +6563,dee2cbac +6564,f877fa3c +6565,530f2059 +6566,70995612 +6567,8f32a507 +6568,bb621f8b +6569,a820cf31 +6570,5ef15e00 +6571,c56a0d05 +6572,40747e26 +6573,b47a5b0b +6574,22a90964 +6575,46ca5d13 +6576,5f3b0d33 +6577,7f2a6e26 +6578,b50def99 +6579,a4b0880a +6580,1200eaac +6581,6bfca140 +6582,a0e6cac8 +6583,0b0d8e17 +6584,09d76b1f +6585,204f3b41 +6586,9e6f9d4c +6587,2894f55d +6588,36efd640 +6589,344479f1 +6590,d7b97ae9 +6591,d66a3937 +6592,76aa99a1 +6593,3d2d2819 +6594,0fa2fc45 +6595,794207ee +6596,68824abc +6597,075c7094 +6598,28a48dc8 +6599,fa4a8c40 +6600,097b37c7 +6601,e0d66692 +6602,f928b380 +6603,a30e97de +6604,46d142e6 +6605,1650ec7e +6606,c15c2c7b +6607,43e1c514 +6608,4e5907e5 +6609,087de773 +6610,58755e1f +6611,efb07026 +6612,8ae47e75 +6613,ae98d319 +6614,88b545ce +6615,fbec269b +6616,5dc94fd8 +6617,874286d9 +6618,db8e9493 +6619,4a02655c +6620,57d99675 +6621,88eb1194 +6622,8b354429 +6623,bcaae66c +6624,f02a7341 +6625,e4516651 +6626,39c7e300 +6627,f8fe76a0 +6628,f4505fec +6629,75979b6c +6630,94244f9c +6631,0a85329b +6632,23cb8f2c +6633,69087269 +6634,a499dcc1 +6635,a702113d +6636,6b8c62ff +6637,089bc281 +6638,3396dbb6 +6639,ad390f4b +6640,fdfb0921 +6641,b83c2368 +6642,355cca49 +6643,0a40fcea +6644,ce325511 +6645,f6ba310a +6646,bb342d0e +6647,62cabc80 +6648,b1b634c9 +6649,864b3eb1 +6650,21f533f0 +6651,2c7317f2 +6652,7aef0695 +6653,c0de479c +6654,e221b1ac +6655,bcb23834 +6656,794f3def +6657,6818bf3d +6658,9d5c327a +6659,180476b1 +6660,7a6a3eaa +6661,8c241260 +6662,cf9c13e3 +6663,09a57b8d +6664,69c96bfa +6665,76370a3e +6666,490c2f45 +6667,3ed7d2d0 +6668,d4f9f9a0 +6669,fcb989cb +6670,d005e68c +6671,92536ea5 +6672,c1d9c57d +6673,637406ad +6674,0b6e3c77 +6675,52a47595 +6676,c89dc9e1 +6677,91f0aac2 +6678,4cbcd024 +6679,d01b7a3a +6680,a3cffb33 +6681,4a9904c2 +6682,626404f6 +6683,d551c0b6 +6684,07c43408 +6685,854fe7a1 +6686,2a95dce3 +6687,e1efad53 +6688,5c7a75a3 +6689,7336e9d7 +6690,55acb49e +6691,d1a13efc +6692,1a689f4e +6693,7a0afcd0 +6694,2a07a4bc +6695,13e58396 +6696,efa8918a +6697,15b152c3 +6698,46b0fbc0 +6699,ed67d756 +6700,4a3db216 +6701,a83782a6 +6702,b957a1eb +6703,67780703 +6704,c4ec4414 +6705,3be11028 +6706,710ca9ec +6707,b5737530 +6708,ecadfb65 +6709,749329a0 +6710,c74e2e48 +6711,0476836b +6712,99b75f7a +6713,b59238b6 +6714,3b1b309b +6715,c53308ef +6716,60f3aef3 +6717,3df932cd +6718,b29d882d +6719,89c350d6 +6720,e680442d +6721,202f919a +6722,5392adef +6723,b3d16eb9 +6724,e1b0975d +6725,684ace94 +6726,10bb4e77 +6727,60727d02 +6728,7ec3964b +6729,06b59cf1 +6730,f6135940 +6731,bc0f8cff +6732,89d0ad00 +6733,34c1e051 +6734,438f38de +6735,d65e041c +6736,addbba50 +6737,a307ab70 +6738,43acab12 +6739,1a629649 +6740,dd6a54d9 +6741,c94ffee4 +6742,c600faec +6743,acf93b0e +6744,bb937d28 +6745,808af667 +6746,4dd01f34 +6747,672260ae +6748,d24cd06e +6749,b6abea9c +6750,98b79ced +6751,9e00c4af +6752,6eb5c92a +6753,9398eac2 +6754,76432be2 +6755,a2b00bf0 +6756,7f8255eb +6757,a8570e0b +6758,525453fb +6759,fa0f7123 +6760,8ad93892 +6761,82097aa4 +6762,17289c67 +6763,73679fc8 +6764,6894b68e +6765,33487a92 +6766,82de7b48 +6767,80502ecd +6768,a71ebf6b +6769,7c11a3f7 +6770,5125e7e3 +6771,303d3033 +6772,ed767ffb +6773,76d8c2a8 +6774,b624dbe5 +6775,ee169c17 +6776,46d58f2e +6777,01dfb931 +6778,cba3bf8b +6779,878d79ee +6780,d1b43ce0 +6781,b161c095 +6782,e436cb96 +6783,05eb5e60 +6784,f600e2d8 +6785,2e8a63e0 +6786,6ea0933d +6787,7f410570 +6788,b17c11e6 +6789,f3133dac +6790,a82dfd9c +6791,61b474a6 +6792,48952a50 +6793,ef7a015a +6794,9a1f2601 +6795,c555f426 +6796,17d53322 +6797,a5c2ec00 +6798,29341572 +6799,7f74a2b7 +6800,46e4b7da +6801,f7f482db +6802,b2c08b6e +6803,4259b7af +6804,64f2d5d3 +6805,67a5c65f +6806,e0965601 +6807,2ae828a6 +6808,78a669b8 +6809,4b4b59bf +6810,307032f1 +6811,762e0b11 +6812,11ff4b26 +6813,fc8f21fb +6814,8682ef1f +6815,ffb1b463 +6816,d38b4052 +6817,c85d954b +6818,3fd614cf +6819,11d9f541 +6820,54df1a5d +6821,ef20c181 +6822,746ed098 +6823,b9bd0e01 +6824,450e3c8f +6825,d7ee67bc +6826,c8a16fac +6827,66419d21 +6828,01d3ad57 +6829,30d31e0f +6830,a0b1f605 +6831,48380242 +6832,8b6a85d5 +6833,879ea588 +6834,7cac30c9 +6835,4cf6c649 +6836,e6b91f5e +6837,46f0d907 +6838,13755fd0 +6839,30023898 +6840,9060f7c8 +6841,5b288cdb +6842,aff4e468 +6843,0b0b0f32 +6844,26ac90af +6845,7edd70b9 +6846,eae8481d +6847,4a6a32e7 +6848,4d95166f +6849,08209212 +6850,3b95f93b +6851,b8da6034 +6852,3cfc87c9 +6853,db1ec293 +6854,cc28bb54 +6855,3a90d130 +6856,29137bfd +6857,e7357173 +6858,febeff40 +6859,0a701072 +6860,86bf74eb +6861,ecf35631 +6862,bd1b1c34 +6863,8cbf4192 +6864,c90f3578 +6865,f694481e +6866,17878aaf +6867,8f277c4f +6868,b97681e1 +6869,80de7557 +6870,c7a81891 +6871,0bdf6e44 +6872,71578ef8 +6873,18c72991 +6874,da2a6cde +6875,3dcb7b81 +6876,1c73cf80 +6877,a9f54727 +6878,bc7f6ecd +6879,91e19a18 +6880,5383e624 +6881,dd06b6f2 +6882,e8c43fc0 +6883,1d828538 +6884,b9cbdc49 +6885,bd2fd639 +6886,beb8560e +6887,deb7f0ce +6888,5a141fbf +6889,dcf052c8 +6890,cb524e52 +6891,b42f2d19 +6892,99d26bb7 +6893,6cb035dd +6894,86c7ea82 +6895,dfb16e99 +6896,222a2c11 +6897,5a5249c2 +6898,dcc2b33f +6899,7d9ce6db +6900,6a9297f4 +6901,ba5d3476 +6902,498e31ae +6903,25a04cec +6904,91815abe +6905,af8529ff +6906,728b98cc +6907,16fcff8c +6908,da626c37 +6909,3ef8e1b5 +6910,0d224e13 +6911,3b685844 +6912,22b17001 +6913,1a201b34 +6914,9f8fb7e5 +6915,fefd29ff +6916,f9bf9986 +6917,722916a8 +6918,b889da10 +6919,5b4e137c +6920,c030d83b +6921,1e3dba5d +6922,7143e9a8 +6923,838768e8 +6924,54e53fd6 +6925,32c90036 +6926,da9025b9 +6927,debb7805 +6928,b4dec97b +6929,5497271a +6930,9374c071 +6931,47f1c189 +6932,71447f08 +6933,f516161f +6934,5cafbece +6935,8bc2d552 +6936,02fa5937 +6937,24891e97 +6938,247e88dc +6939,d50f3c17 +6940,747f7cd1 +6941,9f95e720 +6942,0cb2b96c +6943,320faf21 +6944,d0e28115 +6945,528b5152 +6946,cbc4c107 +6947,aba1d3c8 +6948,7f737ab6 +6949,af07f13f +6950,16172882 +6951,ca2170e0 +6952,089afc4e +6953,2e84dd03 +6954,6837c867 +6955,000c3dfe +6956,24fa3202 +6957,9b66f1c8 +6958,58c1b4cc +6959,8c5cccb7 +6960,7254c454 +6961,70868db4 +6962,a63476a7 +6963,97448337 +6964,eecdfd91 +6965,318ef42a +6966,f51b685b +6967,375fbc05 +6968,aa7ec4c8 +6969,3ea1efaf +6970,145bec0e +6971,9b281712 +6972,e2c08503 +6973,2d05bcbe +6974,b0b0d7ce +6975,45a1f314 +6976,834ef76e +6977,4347ed6f +6978,2fad081c +6979,0c2b5eb7 +6980,dd43be92 +6981,b23c296a +6982,15d9633c +6983,667c0223 +6984,90468077 +6985,a3510a7a +6986,da6a20ce +6987,944fa132 +6988,430bd9d4 +6989,dfe519be +6990,26530441 +6991,f4e38168 +6992,9438d5e6 +6993,9da1eac6 +6994,d9652ae1 +6995,37b1e05f +6996,51ba0e95 +6997,e32c8e6e +6998,d3405cc3 +6999,bfc6af76 +7000,6a90f4b6 +7001,54bd635e +7002,24cb8e6a +7003,8018949a +7004,9c245f36 +7005,1bd96b44 +7006,98cdc6ef +7007,18624943 +7008,4d404878 +7009,34c5be99 +7010,3bff26e4 +7011,4b8cdfd4 +7012,18fe0e82 +7013,26ef8e6f +7014,174f1891 +7015,20c22070 +7016,190fdf8a +7017,41bf806f +7018,a9203f50 +7019,b0aae85e +7020,cea0a7aa +7021,39062994 +7022,171b6282 +7023,044cb087 +7024,caaa3fa4 +7025,76c4caf8 +7026,e2e6bd8f +7027,2c04a325 +7028,d91552d9 +7029,d014615d +7030,c567f4bd +7031,e5097aa1 +7032,43534b0a +7033,442ea4c4 +7034,cf03d6df +7035,6b43f508 +7036,c0896403 +7037,26905936 +7038,7e9d07c4 +7039,723aad6e +7040,c5334ee6 +7041,10d1de19 +7042,1b752b07 +7043,771fedc8 +7044,e1f217c6 +7045,df57dced +7046,2176ea8a +7047,c3750c37 +7048,f220ca45 +7049,bc1557b2 +7050,0957973f +7051,35826b42 +7052,67485927 +7053,bb3eb027 +7054,7566fcb1 +7055,8e80cc62 +7056,2e4fa05a +7057,e54ca7fe +7058,7835b2da +7059,0bdfe9aa +7060,866b376d +7061,391a8691 +7062,3d347756 +7063,2310de01 +7064,88ffe166 +7065,48bda971 +7066,fcfd156a +7067,e8d12f38 +7068,26d365ac +7069,2d75cc38 +7070,99fb252d +7071,1767a2b2 +7072,ffba9eff +7073,6eedf350 +7074,e778cc4f +7075,209f2419 +7076,6dd5db00 +7077,10b55490 +7078,a3316a8c +7079,cec5a142 +7080,566dbde3 +7081,95692dba +7082,52c1d9b3 +7083,aaae4a65 +7084,c2d56d56 +7085,cd48f82f +7086,f69b92d1 +7087,5b46dfce +7088,bc4deb04 +7089,01d4df48 +7090,a00b468a +7091,754ef7e2 +7092,def92fe6 +7093,855afb67 +7094,6e11f181 +7095,873e6940 +7096,a735ea43 +7097,965f1a5d +7098,0a8768de +7099,a1dd233c +7100,53ed0918 +7101,4cf0fe5f +7102,e46daab6 +7103,10a690fb +7104,6798ca1c +7105,912fbb1f +7106,2f4cb65d +7107,e58c08a9 +7108,735a5dc9 +7109,d002d9c4 +7110,38a83e65 +7111,fd06d622 +7112,6b3a0245 +7113,6a38f33f +7114,bc02ac6f +7115,1d005fdb +7116,d6c60c09 +7117,0defabd5 +7118,689d4cac +7119,9951a944 +7120,544a5eb0 +7121,41fd7ea6 +7122,f8f3d250 +7123,c4d7035a +7124,990b5c68 +7125,5959e8f7 +7126,b280e530 +7127,5d270530 +7128,9daebf9f +7129,3abc1c38 +7130,b811fcc9 +7131,ccbcbf5c +7132,c904b73d +7133,29b12bae +7134,162ded9c +7135,6c54df87 +7136,ef8cf030 +7137,99b537ae +7138,f65a61c1 +7139,2ab951a5 +7140,68edd166 +7141,141e81a0 +7142,429a838f +7143,445c7dac +7144,222ae1e6 +7145,73409f94 +7146,c6553efa +7147,0fd5d659 +7148,62c1a666 +7149,28d32b29 +7150,c1d39de2 +7151,cf49283c +7152,0195d4cf +7153,a66153cf +7154,7de0f3c9 +7155,8177516c +7156,fa953737 +7157,0bc6eb0c +7158,ae099b62 +7159,09c26d34 +7160,e849bbc0 +7161,dd909a0a +7162,0c43c447 +7163,beacbb42 +7164,ed3e80db +7165,299b54ec +7166,ac01ebec +7167,626ae667 +7168,8cdb93be +7169,3a173280 +7170,77c2989b +7171,b71e243d +7172,201b716b +7173,22cde4b6 +7174,20c17c10 +7175,cc82f316 +7176,ca4456d3 +7177,12511aa9 +7178,f6aff9c6 +7179,dfa6b9fa +7180,02b5fc42 +7181,bda8c3eb +7182,363ff93d +7183,eac1af38 +7184,3b285b7c +7185,9b525a8a +7186,665c25e0 +7187,54fd8112 +7188,c71760bc +7189,a70cdb3d +7190,0d07c4f7 +7191,c9201150 +7192,94d638f0 +7193,691db85f +7194,898b8b5f +7195,236029d0 +7196,ab07549f +7197,260a0368 +7198,e261cdfc +7199,70d254ee +7200,e4a47be6 +7201,966b1045 +7202,38d9d62e +7203,d5843a6a +7204,1b0c40a8 +7205,b276a72d +7206,8d613fe8 +7207,1d210641 +7208,6372c6dc +7209,2f7bdebc +7210,11710412 +7211,7bcd5f33 +7212,05411efe +7213,5ef294d8 +7214,005339cc +7215,9fc42041 +7216,ce013bfb +7217,1f21fda5 +7218,2c600d5c +7219,d23a38c0 +7220,dd606a47 +7221,71e250fe +7222,31b77bff +7223,53fdde22 +7224,c5a068a4 +7225,7e92f0af +7226,b3ccb718 +7227,8a678398 +7228,ce6cdd5d +7229,c5f914eb +7230,a8eae234 +7231,5b129aa7 +7232,3e986f99 +7233,063963d8 +7234,4cf75941 +7235,1402f463 +7236,1570cf49 +7237,063833a5 +7238,dabe475c +7239,a2adc4b5 +7240,dab6eb42 +7241,fa747783 +7242,c61992a9 +7243,aff55332 +7244,ffae84bd +7245,11cba283 +7246,1455dd5d +7247,548b7450 +7248,ee338965 +7249,335b458e +7250,e25e002f +7251,bcb88a76 +7252,3b8c42d1 +7253,7bdfc153 +7254,73875970 +7255,c3f5f54b +7256,fcc4cd6c +7257,6bfb55dc +7258,f2f40882 +7259,07dcb03c +7260,93efc7ae +7261,0fac8002 +7262,08b16bfc +7263,6f04f814 +7264,c216d747 +7265,2b496d63 +7266,4b50ef83 +7267,9af2a9b7 +7268,fd296d7e +7269,eb356fb7 +7270,d519a0ac +7271,6662f4f4 +7272,3e67c6c5 +7273,3e7cff09 +7274,10a3fc8f +7275,610a5aa0 +7276,d2e04fb5 +7277,5ab34c4d +7278,107df611 +7279,6fabce69 +7280,3684888c +7281,5df7b51c +7282,ef3d7355 +7283,4b7bf5f7 +7284,4af0d26e +7285,5b84ed3b +7286,fa1fda6c +7287,86e8be7e +7288,fae87560 +7289,81a3b9c8 +7290,3ddfab5c +7291,bef5f4b4 +7292,3e4769eb +7293,b3a74b24 +7294,5d990a88 +7295,0b044bf1 +7296,bf1bdd06 +7297,a74684e8 +7298,53d8c625 +7299,535dba52 +7300,959dd0f6 +7301,4c64d7f8 +7302,af01cb36 +7303,8e4de597 +7304,4fdf545f +7305,251a0658 +7306,46f11f69 +7307,8f1336ce +7308,aa93f253 +7309,c36df64b +7310,2bea6c2e +7311,d6dfe145 +7312,eb6933a4 +7313,5c577877 +7314,0f26d4b9 +7315,22c78d13 +7316,6eafcd7b +7317,4fea39d2 +7318,ad6cfd80 +7319,eab12a47 +7320,3e911c7c +7321,125a9ffc +7322,c15b7498 +7323,6ec2f0ba +7324,8044aca7 +7325,a967c395 +7326,f4ab107c +7327,390ed566 +7328,b0132242 +7329,4aa013af +7330,c140102d +7331,e70cd206 +7332,7248b1ab +7333,00f009b3 +7334,630e6953 +7335,342b5aba +7336,60fc0dfb +7337,22786148 +7338,8ad61f1a +7339,038e37eb +7340,4a4394db +7341,6c5b1874 +7342,0455bf5b +7343,b0a038d9 +7344,fd9aacff +7345,ec54d7b7 +7346,cb2af439 +7347,d5d02392 +7348,67b799e7 +7349,cc0f5f85 +7350,f1fc00b2 +7351,39ded388 +7352,5e37dbbc +7353,36f10e68 +7354,a50969b4 +7355,d2dfcd7a +7356,d252e8e6 +7357,fc87ff66 +7358,062872d0 +7359,0f74b99c +7360,650c4c8d +7361,aa48cbe1 +7362,11677e59 +7363,cfc8e409 +7364,2d980ab5 +7365,45972aba +7366,bfd2ad5d +7367,e66800d8 +7368,052c3d49 +7369,850ef7d2 +7370,7b644e8a +7371,7dd1bed3 +7372,f870bd43 +7373,20126de5 +7374,f672dc8d +7375,a2f280b0 +7376,49a924a9 +7377,44836033 +7378,5ff5cbe0 +7379,cc54912f +7380,a8b1e2e0 +7381,1766462c +7382,cd459a2f +7383,f4b5397a +7384,ece2d7ea +7385,e89c7856 +7386,4633f4e7 +7387,25c8e353 +7388,8295a320 +7389,06d408f7 +7390,af30e765 +7391,1e1bf7b1 +7392,814e65f3 +7393,b4b9d72b +7394,c8b18a64 +7395,a9711291 +7396,66629717 +7397,4c3fe486 +7398,31be2725 +7399,c5c9d5ac +7400,a68c61bf +7401,f689d039 +7402,676a30df +7403,849ef3d4 +7404,20c5ed87 +7405,8746490b +7406,a116d196 +7407,bdc6657f +7408,ccac8717 +7409,60a24e7c +7410,d0a8d1bd +7411,e343177c +7412,b9bac1b9 +7413,1eacf97d +7414,c34e6245 +7415,26b4f907 +7416,9bd8c5a5 +7417,87587d54 +7418,9f489312 +7419,192f02cd +7420,224c3102 +7421,d4d71395 +7422,84b4fbf7 +7423,d08e5974 +7424,1c313f41 +7425,48450d60 +7426,037f61c1 +7427,8fdbff22 +7428,7af6cc61 +7429,8087b6f7 +7430,68f5666d +7431,4d9a7ebc +7432,5d5fcf1d +7433,f0310ab5 +7434,a021356d +7435,2e46b7d4 +7436,43ca858b +7437,3ea8aad7 +7438,517e195e +7439,f71dfa79 +7440,9a1c1690 +7441,f4d1c2d9 +7442,ca9b64d7 +7443,25da569a +7444,ad04ae42 +7445,3b8a0672 +7446,db23b60c +7447,cc015a8f +7448,895834bb +7449,9288191e +7450,e5770468 +7451,22162484 +7452,b50dbf64 +7453,824b112e +7454,969af4b2 +7455,1a6937fb +7456,d05c6e55 +7457,718c1118 +7458,87eddd44 +7459,2993aeae +7460,cd116004 +7461,6ebc9b91 +7462,2408561a +7463,e45c569e +7464,a73746fe +7465,43facdc9 +7466,3f174684 +7467,684fbe75 +7468,48fb3ca5 +7469,fb6e01ca +7470,334278b1 +7471,f0bac89b +7472,303e1db7 +7473,435307b1 +7474,41f6f66d +7475,5e1b2fda +7476,66155b64 +7477,e705e739 +7478,5fffa69b +7479,493c1a50 +7480,412b827d +7481,9cd5eee0 +7482,21451405 +7483,31e62597 +7484,fb1b18f8 +7485,97072f70 +7486,7a6daf34 +7487,96b639e7 +7488,aff32de2 +7489,addefdb2 +7490,801985cf +7491,e0a9bebc +7492,daa0a2f6 +7493,76c29350 +7494,b54799aa +7495,70df9951 +7496,27d37e25 +7497,b035d7de +7498,7864060c +7499,0be6a27e +7500,a5fdae45 +7501,d610f700 +7502,4f2a78cd +7503,b480fed5 +7504,408468ca +7505,d7b3a3e7 +7506,be726a71 +7507,d867fcec +7508,6597106c +7509,0b42ca68 +7510,33c3aef1 +7511,42a42382 +7512,fe73cc39 +7513,2f9cc487 +7514,b5f8623f +7515,f06d6b2b +7516,3823eb7a +7517,388cebf7 +7518,e228ca25 +7519,27ff933d +7520,b9f98fb2 +7521,ee4753e8 +7522,ceceb93b +7523,d729142a +7524,0824f053 +7525,18ad3f6f +7526,75d7c450 +7527,1f625346 +7528,2b393c4e +7529,1240e3df +7530,e3ceb5a4 +7531,1c6effa4 +7532,ead0046c +7533,8ba76600 +7534,9bf103f7 +7535,14e0fbba +7536,c2dd05fd +7537,1cff9ed2 +7538,26d72c77 +7539,e294d139 +7540,4aafe858 +7541,f6a71397 +7542,def8a06a +7543,2edadab5 +7544,f7094e15 +7545,efa062c0 +7546,6f0cd4ee +7547,22b009a5 +7548,5672ae4b +7549,47d8cec3 +7550,209a1968 +7551,00615bbd +7552,2eeed365 +7553,6db09afd +7554,a5903b4a +7555,f9914a3d +7556,b484b099 +7557,df474899 +7558,1600b572 +7559,a7aa72c4 +7560,1ff7f990 +7561,23116dc8 +7562,83515838 +7563,52426e7e +7564,c3adbd6a +7565,bc376a10 +7566,2c68b5f2 +7567,ab11122c +7568,f50ba651 +7569,9f86a4e9 +7570,6f7bb948 +7571,097cd867 +7572,31edf5c5 +7573,70ddf623 +7574,7687a959 +7575,837658e2 +7576,8b87c8bd +7577,b91e2cc6 +7578,f66c76ea +7579,00359d4b +7580,060c0ea7 +7581,4996c552 +7582,7d5ab09d +7583,258ea07f +7584,bb15dfd6 +7585,b4d7516e +7586,9627e29b +7587,d8ccfa5d +7588,5f25d39d +7589,21b6de46 +7590,7d45b831 +7591,b0301415 +7592,4830072e +7593,02af2392 +7594,9f46a754 +7595,5f14f86d +7596,8ce45783 +7597,4a3bf55e +7598,fd9755e8 +7599,5a850d89 +7600,8b3d1d6d +7601,48ddce9a +7602,7195f856 +7603,154f08bc +7604,bd7b7875 +7605,191bf919 +7606,6ba7d053 +7607,58744ddb +7608,705d4cf6 +7609,940b5f8c +7610,852efacc +7611,96181c0a +7612,bbdaaa24 +7613,72a74661 +7614,0378762b +7615,9bc3fa5c +7616,20b1115f +7617,7ea17685 +7618,5d68fc5f +7619,74cb7795 +7620,a9037f16 +7621,56609238 +7622,8c6c6405 +7623,25f21485 +7624,99ac3b42 +7625,958d4a80 +7626,4af592d4 +7627,887d203a +7628,4c9290fc +7629,7085ee14 +7630,5e074ff7 +7631,67c0d080 +7632,a85fe052 +7633,65e6c978 +7634,37436050 +7635,f69ca844 +7636,e25e3ac1 +7637,ab690763 +7638,bd112bc0 +7639,f9bf52eb +7640,0345f2a4 +7641,1105e8db +7642,9cafcb66 +7643,7f3b2467 +7644,1f6ab79a +7645,b5e85a90 +7646,a9de368e +7647,309bd626 +7648,8c3caeb5 +7649,f024347f +7650,8e641b3f +7651,a30e99bd +7652,16b7fc05 +7653,2a3bcfc9 +7654,2b8a88a3 +7655,9f881cdd +7656,db271c9b +7657,cf31ad51 +7658,fcee2c58 +7659,4ef83755 +7660,d0072ef4 +7661,098ea35a +7662,09560405 +7663,f3817a31 +7664,f810a01b +7665,1387c6b2 +7666,2f1480ca +7667,629e1b53 +7668,25867bf7 +7669,bb128b97 +7670,f1c1ec56 +7671,d31b07ff +7672,cefeca5a +7673,fa75d75c +7674,6e7c7de3 +7675,bd5dc426 +7676,51fdfe17 +7677,e6226357 +7678,a7e929e0 +7679,ed35ef0f +7680,ef5cf91b +7681,2d2dfb28 +7682,b15cc75d +7683,0ff3e78e +7684,a03b91c1 +7685,b636f589 +7686,47946bc8 +7687,376e1ab9 +7688,0a812307 +7689,7a60711c +7690,e77023a9 +7691,a8d70b21 +7692,1c9efbb2 +7693,bf157247 +7694,c3ec5dc4 +7695,4d63216c +7696,2eae7a58 +7697,19318cb4 +7698,2b53517c +7699,f422c566 +7700,6abd6b6f +7701,ea89dccb +7702,4c90102e +7703,e5a77436 +7704,00bdbe36 +7705,adda7b19 +7706,a597edc1 +7707,258b1112 +7708,0386ec76 +7709,30b7ab22 +7710,9e6d5cd3 +7711,8a8e0d62 +7712,5a30a983 +7713,22eaa58d +7714,9b2a6282 +7715,f57f5004 +7716,21b84df2 +7717,3a467efa +7718,ff1aaad2 +7719,9149f0da +7720,333eecfa +7721,81465e15 +7722,3f4d12e6 +7723,5fb04e70 +7724,72dafca0 +7725,9b811db4 +7726,4ac366c2 +7727,3d236f3c +7728,fdc5f9b4 +7729,4bcc67e4 +7730,189aa0a8 +7731,00f03861 +7732,82bbfbe2 +7733,3a017de9 +7734,f57b1d17 +7735,4ca59973 +7736,2ded6cd8 +7737,6686f291 +7738,0749e68c +7739,e6df511c +7740,d781ba94 +7741,8eabe077 +7742,95b12036 +7743,ac59ca52 +7744,a4fdd815 +7745,09f23910 +7746,7a91475d +7747,c88c6e49 +7748,929b97a2 +7749,72c117c8 +7750,d66743b7 +7751,38ef08a5 +7752,b96f6abb +7753,77aa2409 +7754,b42f3581 +7755,14780331 +7756,1394b18e +7757,a3503752 +7758,c6fce631 +7759,d3ff21f6 +7760,60033b49 +7761,481b6dfb +7762,e674ceee +7763,f61a1261 +7764,998d655d +7765,23249d26 +7766,1c35247f +7767,3e5ef32e +7768,bcf85cf5 +7769,2a9aef52 +7770,bbce6914 +7771,ca209b65 +7772,5b86fe20 +7773,2e9e1cf7 +7774,faba77c0 +7775,c5e52628 +7776,e1a89be9 +7777,dfa60e11 +7778,bb131d9b +7779,24fe4c7b +7780,f2136b62 +7781,4fb2a108 +7782,262eb262 +7783,df06cd3d +7784,e7d2576d +7785,a7c507b2 +7786,efc4d2a0 +7787,1bb4b7c6 +7788,a946eb78 +7789,d377c6ee +7790,356bc589 +7791,00b30bad +7792,3b19ef90 +7793,f82055c2 +7794,7e0e997c +7795,dd72ace4 +7796,bc49c5e1 +7797,cb6c57f7 +7798,517a1952 +7799,3e9f9e41 +7800,a98a13d7 +7801,f7b77b99 +7802,e76048e6 +7803,13544b14 +7804,30ae5c6c +7805,518085dc +7806,4e75b94f +7807,d3812b27 +7808,5fe25551 +7809,43ae8828 +7810,42f21dd7 +7811,6d4b1302 +7812,5be063cf +7813,da29cdc2 +7814,91c40ae4 +7815,4e6439c8 +7816,35f82f5b +7817,685f2097 +7818,206f219c +7819,93fa4406 +7820,a6bded1f +7821,2a477c88 +7822,da36ff0c +7823,27801a03 +7824,0d499f09 +7825,0b5c99f5 +7826,1f2b5a69 +7827,3b9c99bb +7828,af017c60 +7829,1739009a +7830,c11cbd37 +7831,e855365d +7832,1cc39b41 +7833,17b46630 +7834,e862b558 +7835,b9fc53b7 +7836,6c3f7560 +7837,f9bb695d +7838,6d555012 +7839,a4e28240 +7840,2fe51c6b +7841,4ef5bd79 +7842,9336a895 +7843,e615f729 +7844,083b53dd +7845,8ae60140 +7846,61b577ad +7847,cc2de5ea +7848,f9614261 +7849,32aacc28 +7850,8f1e9f91 +7851,cd50ecec +7852,8789ba16 +7853,00df2ecf +7854,1309a2d2 +7855,4e0ff14f +7856,4ef7bed8 +7857,af15c9ec +7858,a781f89a +7859,d40de0ab +7860,f36f4f4c +7861,9fab63ac +7862,1b87451c +7863,8de31d4c +7864,e94e210a +7865,4941f8ab +7866,6168f9b8 +7867,25f23cee +7868,36a06d48 +7869,4ab8692d +7870,f2c7fa16 +7871,c27c0cc1 +7872,3ac8f7ef +7873,6744d1bd +7874,dc66ceda +7875,27f502c8 +7876,42291973 +7877,a4b72e8d +7878,e46971d5 +7879,c0f7173f +7880,d68f4fc0 +7881,fd705f61 +7882,a8213fe5 +7883,05e3dcc4 +7884,01ca4a0d +7885,250c2d10 +7886,6a964c7e +7887,c65a5511 +7888,e5f192b6 +7889,4373f2ec +7890,63968f57 +7891,dae18dab +7892,67bdd8af +7893,e13ecb94 +7894,9945bdb8 +7895,29b06cee +7896,36a9ff11 +7897,be8d8ceb +7898,034432c4 +7899,94dfd51a +7900,294c63ea +7901,542766e9 +7902,c7a40e42 +7903,0a875699 +7904,334a6682 +7905,ba7ce666 +7906,5c732eb3 +7907,a3c812e1 +7908,333f68c6 +7909,36963a94 +7910,53295a9f +7911,90474d4e +7912,841346c8 +7913,441d81c6 +7914,9e318cd4 +7915,906134cb +7916,6eee97a5 +7917,135cd06e +7918,4b23cd1c +7919,9748c959 +7920,717af3f7 +7921,dc14d864 +7922,84727e50 +7923,535fb987 +7924,a8158bf1 +7925,73e5dcb7 +7926,41e6f23e +7927,414cb085 +7928,7c45ea8e +7929,29a71890 +7930,7faa0c0e +7931,0376c856 +7932,f376a4f3 +7933,a37fe832 +7934,ba6031f5 +7935,cf981316 +7936,9e7fb653 +7937,130a0d42 +7938,c3a34292 +7939,0363f31f +7940,ad4573b4 +7941,9eebd264 +7942,0df289c3 +7943,e7c0bec2 +7944,73adb9e6 +7945,3a981b3d +7946,4ecf773c +7947,3e93d51d +7948,21414c63 +7949,28118e98 +7950,e0a86ffc +7951,ed79d989 +7952,e5778b4c +7953,84e22a61 +7954,29424bee +7955,b4f8acc9 +7956,3491ad43 +7957,62ac19d6 +7958,80aaa0cc +7959,017a4374 +7960,d6d67a3a +7961,1348962c +7962,a534258b +7963,7011e1db +7964,60c272bb +7965,6f1e962a +7966,7b3669e7 +7967,0dcaee35 +7968,20134371 +7969,f16d2b8a +7970,0c83a509 +7971,23431679 +7972,c06df0df +7973,0e44a09b +7974,56ed8b57 +7975,b0952022 +7976,b6324a40 +7977,a7f21877 +7978,7ba00a05 +7979,0e849d21 +7980,ac69d2a6 +7981,3b79d52b +7982,05991979 +7983,131036b3 +7984,8bb3a81f +7985,7a7e5c14 +7986,d937ec98 +7987,a8126253 +7988,321ea290 +7989,8fb6b0a6 +7990,234c2ff9 +7991,cabc182b +7992,d470fb1d +7993,7637f16f +7994,6409b5cc +7995,6ef8dfc2 +7996,c81e3152 +7997,4cc2d9ec +7998,276f1e83 +7999,3e666296 +8000,04832458 +8001,2249f399 +8002,d9339aea +8003,cac6f4c9 +8004,4d2a1d3c +8005,4552dd60 +8006,38e298c0 +8007,db371cd4 +8008,894163d2 +8009,a783c26d +8010,076fb212 +8011,0440ec81 +8012,0c47a719 +8013,4df5a18c +8014,c6d77e36 +8015,a8bedd67 +8016,df57c445 +8017,a380353d +8018,e0d50c11 +8019,56ea2c25 +8020,b6e631a3 +8021,2aea61e6 +8022,cd45b0f7 +8023,ebe54dd5 +8024,8a77a1e2 +8025,b7634bd2 +8026,02a958c8 +8027,c750fbbc +8028,c83355a8 +8029,e23a9203 +8030,2233eea6 +8031,1d93d616 +8032,741ebc72 +8033,83de27e4 +8034,c3702a70 +8035,9b0d16ad +8036,1e271e00 +8037,4f9a264f +8038,b4ebd09f +8039,128213f1 +8040,d4e528b8 +8041,5b512ed5 +8042,e9cc328a +8043,dc4c8e44 +8044,ced7bc51 +8045,abdd3eec +8046,bdba4050 +8047,5b5dff7a +8048,10ca5afb +8049,878a4061 +8050,5d7522dc +8051,b236f8ab +8052,fc79f796 +8053,3ca954d7 +8054,51a469cc +8055,0dea512f +8056,d5f4e3c4 +8057,8f16ac75 +8058,afc93702 +8059,35550e8a +8060,2c23f795 +8061,a1327691 +8062,c78ac6b4 +8063,f1cbc366 +8064,5ed2b321 +8065,61f67bc3 +8066,6d3b481a +8067,4a1fdbbd +8068,2f00a4fc +8069,0e79fe58 +8070,aacf3558 +8071,571aaaa1 +8072,c41b27ec +8073,49eeb3cc +8074,2effe97e +8075,99308522 +8076,666637a4 +8077,95d56f1f +8078,7735ffec +8079,fe081d8d +8080,6bcc4b67 +8081,403428c8 +8082,7b2cb7f4 +8083,31d65246 +8084,cc0d764c +8085,86aec54f +8086,ff500825 +8087,510e59ab +8088,c5896bfc +8089,94ed1d34 +8090,a8e8adc3 +8091,9f8b0ca3 +8092,321c63a6 +8093,80032353 +8094,c845be30 +8095,4bdc3a54 +8096,41090d59 +8097,5d606d12 +8098,8c48312d +8099,3146c5d5 +8100,1e122d03 +8101,eca03edf +8102,058fdad8 +8103,1c957f05 +8104,598222e7 +8105,73385a34 +8106,75329c59 +8107,22918fae +8108,c5bf3fa9 +8109,18932daa +8110,caac4402 +8111,f66257b7 +8112,14790057 +8113,804aa19a +8114,64991e93 +8115,3ec761c0 +8116,a4d75a24 +8117,f34b2723 +8118,65c29682 +8119,47fc5fe4 +8120,c8860e03 +8121,7e30c589 +8122,6657265d +8123,e97fd6a8 +8124,af19e7bd +8125,26b17b1c +8126,3ef68245 +8127,339d4b70 +8128,a0eefb7f +8129,34d1f540 +8130,b92c75fa +8131,d41dd15f +8132,788d7545 +8133,4e5d9909 +8134,8860eefd +8135,27f97071 +8136,f56c7f62 +8137,c675275d +8138,b739ff76 +8139,d672577d +8140,d671f95a +8141,6280d9b8 +8142,60f26b31 +8143,ade0bb21 +8144,3c7fecfc +8145,da728110 +8146,4cf4d62f +8147,e5525a85 +8148,bb155388 +8149,a081a18c +8150,9b964de7 +8151,73dcc3dc +8152,d4d01520 +8153,aed2be7e +8154,5f7fbd4e +8155,48e312a1 +8156,f1586bc9 +8157,a257ede5 +8158,839c82bc +8159,0ed8bd18 +8160,83b5da59 +8161,f36edf75 +8162,bf0f55be +8163,7d55f7b1 +8164,8d9f70b5 +8165,2eb4536b +8166,2233b3b5 +8167,943bb5a7 +8168,b1a7af2c +8169,55b99e3a +8170,147e1f26 +8171,110a0c4e +8172,8fac7dbf +8173,48208028 +8174,4d78d08a +8175,94ccda3a +8176,5fb5d813 +8177,7cff2f0e +8178,83792b18 +8179,cb6a238b +8180,3a834d79 +8181,e5a19d89 +8182,6711fff5 +8183,2cbbce9f +8184,ce223757 +8185,2e496561 +8186,3b780f5f +8187,9162e859 +8188,52e5bba3 +8189,8f8093ed +8190,c54fe6cf +8191,3e65ffe6 +8192,fff96e90 +8193,e26b5001 +8194,7f06611a +8195,7a146f76 +8196,50468bf2 +8197,8824ca1d +8198,1ecb0135 +8199,2245910e +8200,43b2c894 +8201,a5d5b320 +8202,0118e120 +8203,cbc84b12 +8204,d6848f85 +8205,57d09b0d +8206,c704a143 +8207,02257577 +8208,0af42b01 +8209,cf505764 +8210,f2c14c4c +8211,6cc3e9a3 +8212,d3e483c1 +8213,111fefe9 +8214,b9b30643 +8215,1ab2b4d5 +8216,13bf97f9 +8217,6a40c9ef +8218,2bbc6993 +8219,bd432f39 +8220,2a4f4b47 +8221,0b624b95 +8222,b2a4236a +8223,b382bdd0 +8224,e8cbd564 +8225,03a71060 +8226,97d7e59a +8227,417e286a +8228,a60fa380 +8229,8dbf6229 +8230,bf14ab2f +8231,f7d60ffe +8232,5e15b104 +8233,97129f2d +8234,1636f7f1 +8235,ded0876b +8236,5f77b739 +8237,ba9e3083 +8238,6611b206 +8239,0375c36f +8240,23a1cc42 +8241,3d7605be +8242,52284f22 +8243,88597a7c +8244,35ba86ac +8245,2b6d321d +8246,0011e728 +8247,db10f51e +8248,00b761d8 +8249,2b0ac3b2 +8250,251143f4 +8251,4732fb66 +8252,a9d22d88 +8253,5509028f +8254,6399622a +8255,1576cc19 +8256,990de944 +8257,2d735dc0 +8258,d9a6259e +8259,101d30b9 +8260,7ec740bf +8261,e3f2456a +8262,8d432774 +8263,7066b3f4 +8264,6da1814c +8265,8f3c4df1 +8266,91eb83cc +8267,339deace +8268,734ed037 +8269,f4e8f885 +8270,341ef3b5 +8271,89d3ba9b +8272,e58a985d +8273,e38e965c +8274,bccf69be +8275,c7e224c7 +8276,aa1a3a1c +8277,7dd4357a +8278,b0623a3f +8279,505fe183 +8280,ad740a82 +8281,a053a858 +8282,07061cf1 +8283,d52ba073 +8284,89b9f42d +8285,0b0ba4d6 +8286,931f8e63 +8287,9507b039 +8288,2b2673a0 +8289,b0321ec0 +8290,9f3a5627 +8291,f548a010 +8292,3fa14de1 +8293,1984437d +8294,6115dc46 +8295,0ccaa41a +8296,8f1468c4 +8297,d2568ded +8298,cd259dd2 +8299,624c528f +8300,7ccc852f +8301,ba49ceae +8302,636aedd0 +8303,f1c8b10f +8304,29ae7bbe +8305,ecff56ba +8306,cb2abb64 +8307,3002f081 +8308,375dd8ee +8309,f78beb47 +8310,8185339e +8311,101d9e12 +8312,cfa301bb +8313,eb099adf +8314,6b3c8a79 +8315,56cc78fb +8316,7d6ecb2f +8317,2b5b4d31 +8318,64093936 +8319,3aea3387 +8320,1dcf1dbb +8321,2283ba9f +8322,3c489dfa +8323,b55f16a5 +8324,d9035ebb +8325,27d4e482 +8326,e6ac8eeb +8327,b5bf61f5 +8328,9c4f6aa8 +8329,035ea47e +8330,339cc678 +8331,c43018cf +8332,ddf1f575 +8333,f04ae633 +8334,789980d7 +8335,2da67869 +8336,48f86203 +8337,9617ec5a +8338,b4a4766d +8339,0219533b +8340,0f9ac6e9 +8341,dd1d14df +8342,aeda15e3 +8343,a95bed59 +8344,07b3c716 +8345,3e3e3307 +8346,412e456a +8347,d0f552fd +8348,1cc9712d +8349,9328a818 +8350,e7f0c5a6 +8351,ff83e5e7 +8352,260905e0 +8353,de318e31 +8354,b8534713 +8355,0e8792b8 +8356,f33ec4f8 +8357,c5ace169 +8358,4c3fb8fb +8359,361dc6e6 +8360,7df85826 +8361,23453dc3 +8362,9694dae5 +8363,0a711f8e +8364,b51fd143 +8365,ffe9a569 +8366,9b17ffa8 +8367,e89992cc +8368,252dbd08 +8369,1b478390 +8370,0dba08c9 +8371,b3a96108 +8372,4fad98a7 +8373,4057bdcd +8374,95c8292d +8375,a7e36b8c +8376,77cb4a42 +8377,a6d2be1b +8378,dd90a1f2 +8379,0d543002 +8380,9f9df354 +8381,7c0764bb +8382,e9916142 +8383,60cb2439 +8384,955b8f3e +8385,9315a905 +8386,21498954 +8387,28a91c14 +8388,8468f588 +8389,b5c48ef3 +8390,119c22fa +8391,986f6aca +8392,f30f55ad +8393,15be7158 +8394,315fca0b +8395,4da4c700 +8396,96a1d0a1 +8397,1a8ec44c +8398,9b930d62 +8399,90e5b9a4 +8400,e6fd487c +8401,5d3d2d60 +8402,081ad73d +8403,6da357c8 +8404,ac635781 +8405,6438df59 +8406,5988470d +8407,e63a1177 +8408,f5123975 +8409,173af11f +8410,084007c2 +8411,4842f919 +8412,f563fc7e +8413,4608c824 +8414,5fa5e4f0 +8415,112dfa97 +8416,5e59e6d2 +8417,ecf97b47 +8418,0efcba0a +8419,68e21fe8 +8420,0d0611fe +8421,3157dc98 +8422,f434b97a +8423,cc02964f +8424,464e95ef +8425,6ba9ccc8 +8426,be435e02 +8427,865b55cc +8428,a4d818c8 +8429,2d84feed +8430,97691985 +8431,c0599d4c +8432,f49c4c87 +8433,ad0c767b +8434,c6ac6851 +8435,0031716c +8436,38a1e8e4 +8437,05da344a +8438,1b3c9daf +8439,0404973d +8440,677bc030 +8441,19249f95 +8442,c775618c +8443,88c56fd7 +8444,853120b8 +8445,820efa6c +8446,d647393a +8447,3cf2df25 +8448,beefe529 +8449,7828ec35 +8450,f89ba044 +8451,28f90fe5 +8452,7f43f760 +8453,29ed5749 +8454,72b2c1c1 +8455,6b16c0ae +8456,759407d4 +8457,5e38720c +8458,abd99275 +8459,0563367c +8460,70687b69 +8461,ae325c09 +8462,0baf7ac5 +8463,6330d529 +8464,d0312ccd +8465,2ec927df +8466,5786e1a0 +8467,1b30a6e7 +8468,92ad7a61 +8469,310148ec +8470,04c7ee2a +8471,59bc1cf3 +8472,cbfb2935 +8473,4d3ee54a +8474,5c274a68 +8475,f4bb5ea2 +8476,c885f4c2 +8477,000f3881 +8478,853cc316 +8479,ec4c2af2 +8480,92b37569 +8481,b49a7df5 +8482,8d4b1dfa +8483,49d95732 +8484,0b3f9121 +8485,4240a2b2 +8486,f60534e0 +8487,09236382 +8488,d176f9b4 +8489,d91a0cf1 +8490,9c23531c +8491,a816337b +8492,733917c0 +8493,235fc352 +8494,d68dccd4 +8495,3a5f1967 +8496,8afc5616 +8497,6f9cae15 +8498,501c75ef +8499,7ecb1ce5 +8500,39d567c5 +8501,ba869298 +8502,debf129b +8503,8f3bf61d +8504,3d9d3459 +8505,54421e94 +8506,e00c8b1a +8507,c9bd30be +8508,39f33c7d +8509,2629402d +8510,6125b7d1 +8511,9c31f337 +8512,280e1b54 +8513,2b9608b4 +8514,848dd290 +8515,459236b2 +8516,51efa210 +8517,b06784d9 +8518,27c901a7 +8519,e8a89332 +8520,be98b3a5 +8521,ce7c0317 +8522,6f4d50a1 +8523,168a3127 +8524,0216d660 +8525,649a3f5a +8526,d0cb5100 +8527,c55494fc +8528,e14b9c6b +8529,1d53f37f +8530,4b1207d0 +8531,9ca40cfc +8532,2c336f3a +8533,93d43b86 +8534,46ae8006 +8535,2fda19d1 +8536,63836563 +8537,81a05240 +8538,47a07dac +8539,3c1fad23 +8540,caab38ee +8541,a98b07d0 +8542,084d548f +8543,382ff002 +8544,1a199a6a +8545,ae68267a +8546,207bd459 +8547,63c92360 +8548,6a22930d +8549,dda2a281 +8550,837c2cff +8551,ad1c6e4e +8552,ef7cff3b +8553,44c3ddd4 +8554,d6bed823 +8555,f1acfdd0 +8556,9e6191f9 +8557,b01ba1fa +8558,c46fc88c +8559,97cc758b +8560,651b05b0 +8561,5b158640 +8562,6c4e3e48 +8563,cd7ca847 +8564,1fef4e90 +8565,4bf10a47 +8566,42097580 +8567,513de284 +8568,ba1a5c10 +8569,5ff246bf +8570,bac85a5b +8571,15fe359c +8572,2ace9f2c +8573,38fd203b +8574,cfe1dee6 +8575,09ebcf1d +8576,944b0b9c +8577,05c5533f +8578,e18c6013 +8579,b9f8498a +8580,8c5d6885 +8581,364ccb87 +8582,c6083ce2 +8583,72a46eae +8584,eb1337e8 +8585,1b5036dc +8586,1fd7a41f +8587,45351e08 +8588,a89bd761 +8589,430a0b70 +8590,aabea7a5 +8591,95a9765b +8592,b7dc5224 +8593,f361fdaf +8594,fc87185d +8595,e453a7c0 +8596,72b50d05 +8597,bcd55e90 +8598,6427bd30 +8599,49604b73 +8600,2beed4eb +8601,76442438 +8602,9d4e0aa0 +8603,2e3e06bc +8604,c2ebd771 +8605,13601e66 +8606,1af68f04 +8607,692d33dc +8608,ea0c1c75 +8609,9a29c3df +8610,145b1aaf +8611,7140e855 +8612,5465a800 +8613,90a33772 +8614,69aa0236 +8615,48b5a51b +8616,e5aac4b6 +8617,5864e4d6 +8618,c63610b6 +8619,9a613729 +8620,943941e8 +8621,043d34b4 +8622,f55675ee +8623,4b2de010 +8624,0296d474 +8625,82ac08ea +8626,03981ad4 +8627,af5d2ad2 +8628,b585e44f +8629,b92c6aeb +8630,93ab36bf +8631,592916cd +8632,43067591 +8633,31ad0df8 +8634,786bb668 +8635,04129cf3 +8636,1664eeb5 +8637,83ef35d6 +8638,5f88eb36 +8639,4d0a2c36 +8640,01be3472 +8641,4373b2f6 +8642,2a9cc4bf +8643,7b708301 +8644,a748ee22 +8645,f7bed1bb +8646,7d07d77c +8647,9ba6fd54 +8648,33e11fb4 +8649,bb6bd939 +8650,43166cf7 +8651,dc553495 +8652,9e08d7fe +8653,9a2a73f2 +8654,de1ca99c +8655,f2b5f898 +8656,8da037a3 +8657,070e694b +8658,6021825e +8659,10c04fc1 +8660,5cb466a7 +8661,0cc65d1b +8662,210b1cd4 +8663,00dacb4d +8664,7468c6d6 +8665,faacf51a +8666,5779d5b5 +8667,3d421977 +8668,7bd25348 +8669,dd56cf9a +8670,722c1789 +8671,6d2e34e7 +8672,f321979f +8673,8f08f7e0 +8674,f56431b3 +8675,a1d5d663 +8676,9a2498c8 +8677,d3b14d4b +8678,adaa9143 +8679,6f5684c3 +8680,eec5e8cb +8681,212064b5 +8682,8f73474d +8683,011f4b83 +8684,b2ac9528 +8685,eef6e83b +8686,4e0ef222 +8687,18d55677 +8688,cea0a453 +8689,b0b56d74 +8690,cdbd3551 +8691,af1780b2 +8692,b90682ea +8693,3f29599a +8694,5454fec5 +8695,2a65f2eb +8696,2fd500d1 +8697,cbf9cbff +8698,eb40cc48 +8699,d9ba2e82 +8700,ff56404c +8701,228e80e1 +8702,b06d83ca +8703,72137cd9 +8704,8a3566e0 +8705,91227534 +8706,f2a336cc +8707,0562e11b +8708,b179b456 +8709,12f0e198 +8710,157b7fca +8711,3ca2537a +8712,94748d76 +8713,ca52af57 +8714,5b4c88ae +8715,93ff5984 +8716,019a22ef +8717,b57d087b +8718,b24f50f8 +8719,6914bcb6 +8720,1e34fc3c +8721,81e6f912 +8722,6b4014f1 +8723,52199e4b +8724,a1173101 +8725,feabd2b0 +8726,a9a2fa74 +8727,5d147c25 +8728,168ea67d +8729,2271dd17 +8730,76a1c7d1 +8731,398a6553 +8732,0bcf1fb6 +8733,779fe10e +8734,393fbda7 +8735,59413848 +8736,06648143 +8737,09f8b8c3 +8738,fa0d3325 +8739,aeb3127c +8740,777ca2aa +8741,602d8278 +8742,282c0f04 +8743,453e7591 +8744,b7cf15db +8745,748535fe +8746,5ed1b1cf +8747,9c1809b9 +8748,359c5fc1 +8749,d5da9a44 +8750,de4cd183 +8751,00f1fb05 +8752,6667d63a +8753,0a451dc8 +8754,741bf33f +8755,0bf117d8 +8756,5319a717 +8757,4d5e140e +8758,eed414e4 +8759,dc021b32 +8760,beb83837 +8761,54588046 +8762,6bf3dd07 +8763,85134e11 +8764,727a19b3 +8765,779cbffb +8766,e155a5fa +8767,bcc82020 +8768,f2bd5c47 +8769,9450ce46 +8770,494e9826 +8771,06961c74 +8772,e872ce6c +8773,9b4f6854 +8774,02be4853 +8775,f8ec7450 +8776,0b942387 +8777,d8f3987e +8778,0188124a +8779,bbb4a651 +8780,eeeef84f +8781,e1c1816c +8782,d37ab868 +8783,2e7a95a4 +8784,3ca1e34f +8785,9eaa0c27 +8786,90f95480 +8787,a569e155 +8788,ab0e1fd0 +8789,21720ea0 +8790,613c3041 +8791,fad7c055 +8792,c03d6a9e +8793,5d534c18 +8794,84996795 +8795,f6d9a543 +8796,88af0e65 +8797,6d2e5f22 +8798,257c111b +8799,0c7374e4 +8800,6f6bb26a +8801,f4c3d7b5 +8802,9e55e8b5 +8803,d17beb7c +8804,20fd0277 +8805,9c256c64 +8806,59424f81 +8807,77e65960 +8808,5e209232 +8809,4e6f7bc7 +8810,c042d8dc +8811,e3389518 +8812,2b5102eb +8813,5060b66e +8814,1f7fc0a4 +8815,b3b9deb4 +8816,fee4c2d0 +8817,ccf02702 +8818,32c6d2f2 +8819,7e2c8c63 +8820,b93c9a64 +8821,b5c59068 +8822,966cee24 +8823,1a431252 +8824,7dfbbc2d +8825,d9650209 +8826,e204ff58 +8827,d33a2425 +8828,530d02f4 +8829,4e7faa64 +8830,c2099bcb +8831,1a4c443f +8832,b88f80ce +8833,74192cc0 +8834,8de12eda +8835,270f1347 +8836,3ed31d39 +8837,3e05c019 +8838,c25033b9 +8839,37bc2cd5 +8840,2810f2a0 +8841,0585b30f +8842,103cc3fc +8843,e4c1d89e +8844,27afffb0 +8845,b44828d5 +8846,60b6da0b +8847,d2d67ecb +8848,45988b07 +8849,3d2de2e6 +8850,bff92ada +8851,0a26160e +8852,80e905dc +8853,c9980fc7 +8854,027ed6ba +8855,38b35d8b +8856,873092ce +8857,8ef95a62 +8858,8912ae03 +8859,9b5b1ed5 +8860,5e20409d +8861,ddcb346e +8862,39485217 +8863,4000e09e +8864,2c5d7ba1 +8865,a6002a63 +8866,c11addb4 +8867,26c918d9 +8868,75794425 +8869,6f5c372c +8870,dd34674f +8871,a4812707 +8872,2097df4b +8873,28cd655a +8874,7bd87a85 +8875,3677ba53 +8876,a3f8d1ae +8877,33f24d4f +8878,bf4ef7f7 +8879,9a8b9ffc +8880,aaa870ff +8881,00daaeb7 +8882,b4b69fb5 +8883,cbe58181 +8884,e867b17c +8885,a8e832b4 +8886,cbc07143 +8887,ab519ad7 +8888,607d8ebc +8889,cf02544f +8890,c7d40386 +8891,817309a4 +8892,6b28ebd2 +8893,57600e0e +8894,57f0eede +8895,cc6db1d5 +8896,d128da73 +8897,3abbb41b +8898,1cec73db +8899,bede9289 +8900,57ba40c3 +8901,0a274fd0 +8902,5722c45b +8903,c323caf3 +8904,551a84a7 +8905,395c4f8b +8906,8b9070bd +8907,f676ad19 +8908,2667986a +8909,3ed590ac +8910,e53ef652 +8911,9287ca0e +8912,b618f86e +8913,9b3be08a +8914,b098adc4 +8915,ed7795e7 +8916,00236e22 +8917,f7f91199 +8918,65aa19f0 +8919,38a79ed3 +8920,ed1e9494 +8921,2b840e3b +8922,04378087 +8923,95c3cc2d +8924,fe0ed522 +8925,74be4600 +8926,e1d74475 +8927,77a08744 +8928,b8fb15f0 +8929,bae81022 +8930,f062a73e +8931,ec3d5c03 +8932,9bdc2a30 +8933,7e2dc58c +8934,95eaf790 +8935,4fd071ff +8936,9ffb9eef +8937,3652d081 +8938,beed7fb3 +8939,9c602034 +8940,3c1e8f93 +8941,b7aa4456 +8942,de129576 +8943,42505a4d +8944,175d5201 +8945,89220d98 +8946,1b3ee1b2 +8947,e79eea10 +8948,6a6af260 +8949,daeca4eb +8950,991f12ea +8951,76c6d4bd +8952,673eb978 +8953,156ea18a +8954,02456b93 +8955,6557b4cc +8956,15869efc +8957,1a3a3556 +8958,67d84d58 +8959,b13ce567 +8960,a76519bd +8961,1f9c79db +8962,bb29a5ae +8963,176c6884 +8964,6b1578ce +8965,358ecd28 +8966,76bd9454 +8967,5fa88178 +8968,27ca4cb7 +8969,8de339aa +8970,dc9368a9 +8971,948f03de +8972,a921031a +8973,fad772f3 +8974,567bb5ca +8975,88c98a4f +8976,5fc5f7aa +8977,1362bef6 +8978,9b23b6cd +8979,b57b9f49 +8980,a98b6efa +8981,d72409bd +8982,dcd91b1c +8983,74aea134 +8984,c7655fc6 +8985,aa0e3d57 +8986,8c6aaa2b +8987,be01e1db +8988,0bfba18c +8989,5d0d9a72 +8990,3e10f5b7 +8991,2e84e48a +8992,06b26ca4 +8993,943a6b38 +8994,45e381cc +8995,e6b7fb80 +8996,6d2d9abe +8997,306efc54 +8998,e8947b11 +8999,02ae1a8a +9000,e53d0c1b +9001,817c316c +9002,470135fb +9003,e79c7221 +9004,51034497 +9005,2f6600e9 +9006,2b2135f4 +9007,77f2cd1f +9008,516d08ec +9009,ea5a272d +9010,bc587fbd +9011,dccff631 +9012,548731f2 +9013,f913e41a +9014,2359c352 +9015,5bbdcf9a +9016,62b47dd1 +9017,c1d89f20 +9018,4c3592d5 +9019,3520b82e +9020,c541083d +9021,bf7ca6c5 +9022,6b8d1fce +9023,55cc4bd3 +9024,d487421d +9025,857a3de7 +9026,388e59ae +9027,2ba8261d +9028,e6f96a1b +9029,a1a8dc55 +9030,04f75874 +9031,1ac0c476 +9032,dfb9069f +9033,4faa1a78 +9034,b12588e3 +9035,b7ab8406 +9036,8d0fd1f5 +9037,2b694b5a +9038,6ed074d5 +9039,9c3ae7a1 +9040,0325fc82 +9041,93efe260 +9042,50ed8c17 +9043,d9af4be9 +9044,f6ba8dec +9045,0531d88e +9046,dd5c1c82 +9047,cb6145e6 +9048,1f056473 +9049,43fd172a +9050,96be2e1a +9051,fff9f5e4 +9052,cd4a57a6 +9053,a5078c67 +9054,3f5fc746 +9055,b5a887a9 +9056,94eb64c3 +9057,9b340f31 +9058,24b9a762 +9059,083dea98 +9060,99fe1182 +9061,37057b48 +9062,8a824b80 +9063,a6dba917 +9064,6962d4fc +9065,c87eded8 +9066,b1f79615 +9067,e9f39263 +9068,eb7fd50b +9069,0839f1fe +9070,c0de57ba +9071,b873ae9a +9072,5ba52d31 +9073,5cfc57c4 +9074,4479b8d2 +9075,00fccf1d +9076,507024fd +9077,c0412879 +9078,033be534 +9079,2416debf +9080,2f91daaf +9081,e849c6a0 +9082,a32e68f8 +9083,a4033588 +9084,6967b7cd +9085,78d8504d +9086,933d223d +9087,ede2955f +9088,697472d5 +9089,70f88825 +9090,1c4ffb20 +9091,4d7c0c02 +9092,30cf08a5 +9093,efae8009 +9094,ec9ed9f5 +9095,427ceb4f +9096,4826f7b7 +9097,dc61bc12 +9098,7d02897b +9099,a509a3e9 +9100,4839b4a9 +9101,4cac0356 +9102,3f6b6a51 +9103,07cb0622 +9104,083e84b3 +9105,a3184595 +9106,be47f937 +9107,ae656c3a +9108,2f83cea2 +9109,73f34c89 +9110,f0d41ef1 +9111,f7f649e2 +9112,b7728e3b +9113,2ebe1f52 +9114,20ec742b +9115,18dc2bc2 +9116,d16b1360 +9117,5e3c38e3 +9118,82b75f80 +9119,355af055 +9120,822d4aa8 +9121,9d1d1aef +9122,cace82de +9123,bbccc415 +9124,5b70dd92 +9125,331687b0 +9126,7d0a9f22 +9127,3134ff19 +9128,70c807b5 +9129,310d2f9e +9130,ebb2fd6a +9131,6bf7b47b +9132,afb017e7 +9133,aef6aa21 +9134,5d82a08b +9135,1e760a15 +9136,107599f9 +9137,5b87e1d6 +9138,74da2539 +9139,cef39907 +9140,a1c87288 +9141,dfe91ec6 +9142,e97fcf64 +9143,c4b8a1b6 +9144,89168a93 +9145,e5ab34b4 +9146,c651f57b +9147,6573a05c +9148,dd459ad3 +9149,111cfb86 +9150,92094fa8 +9151,aa40ffc4 +9152,b4451aae +9153,53b15d6b +9154,b0d26aaa +9155,0a576fa9 +9156,7713211f +9157,d8df7984 +9158,e37eb06a +9159,2477c252 +9160,6c18757d +9161,3dc84b19 +9162,566c995a +9163,06e55a4d +9164,f56d268c +9165,f0a62c72 +9166,2a8f1fc4 +9167,169a3853 +9168,fdbb41dd +9169,1e56db99 +9170,2ef449dd +9171,82f1db72 +9172,b9d4095f +9173,ce08ab7a +9174,c339751c +9175,005b6707 +9176,57c1843e +9177,55a2cc70 +9178,05494673 +9179,a1968c6d +9180,99138504 +9181,421e3e31 +9182,ca02adaa +9183,8feb1954 +9184,471ecdb3 +9185,84fe7ae4 +9186,f460364a +9187,9b60475c +9188,cb9cdcb9 +9189,c3d7c22e +9190,3c699066 +9191,3c67e491 +9192,3ac697f5 +9193,bd15a48b +9194,8fada880 +9195,d2f9dbe4 +9196,2aac2492 +9197,194553d8 +9198,a28a4789 +9199,a65a6708 +9200,2198280f +9201,ae844378 +9202,f7744858 +9203,f19defd8 +9204,5f5b3e3f +9205,14fffc76 +9206,a43c4aeb +9207,44f94593 +9208,2bbd2171 +9209,837ef19b +9210,66050290 +9211,b2ff0b2b +9212,416117e9 +9213,242e5e8b +9214,c66470d6 +9215,ca588187 +9216,8e5c2cc4 +9217,fe5bbc31 +9218,b172306b +9219,6c07ec51 +9220,c31620c7 +9221,d717e020 +9222,3acaf0d7 +9223,df85d03c +9224,5688a52c +9225,46e61427 +9226,376950dc +9227,f8608ea0 +9228,62a8f4e3 +9229,dada0fce +9230,760a2fd7 +9231,c4775c7c +9232,629a6483 +9233,0e0ec9ca +9234,22d58f2a +9235,7f0ec0d3 +9236,f58b5092 +9237,87598ca2 +9238,9ab6098d +9239,7dab4b80 +9240,1a91711e +9241,551803eb +9242,4fa27c8b +9243,c81fa8bd +9244,148d09fd +9245,c75d838e +9246,a84cdd5e +9247,e566195d +9248,214416cf +9249,3b7646b7 +9250,15d3d778 +9251,c887cd2f +9252,75825b7f +9253,c6bd3dae +9254,df97eec6 +9255,0917f450 +9256,05cb22cb +9257,ee5504c3 +9258,1f3ccccb +9259,792ae092 +9260,83718b6c +9261,764d0cb3 +9262,aedffd31 +9263,552b7654 +9264,6e0c2a9a +9265,74eeb461 +9266,177982ff +9267,4ffbdd58 +9268,17454cd5 +9269,92fdbc4b +9270,e9bc0c02 +9271,2f1a009b +9272,10b09dbf +9273,0cf537fa +9274,3cd818c1 +9275,1b853f3b +9276,18a0c328 +9277,b29a3480 +9278,99fb26e6 +9279,c86d5d68 +9280,d6255789 +9281,6b7221dd +9282,7ef134a6 +9283,54cf6f06 +9284,ca6d7387 +9285,490afd17 +9286,76d98e71 +9287,19d17e26 +9288,27c678b9 +9289,3b39de5d +9290,fc64c9fa +9291,bc629f2e +9292,28a35369 +9293,c57e3c0c +9294,a516477f +9295,d049fd11 +9296,8abafc69 +9297,873651c9 +9298,8209265e +9299,40ea104c +9300,1848e1b3 +9301,8c3669f5 +9302,4ca85593 +9303,2c38e913 +9304,57a29e30 +9305,8b5b33df +9306,07b0ece6 +9307,1bf90856 +9308,6aab54d2 +9309,f4364aa6 +9310,2314095f +9311,b1f6d57a +9312,c82833e7 +9313,3f200fbb +9314,ee310ea8 +9315,ebe6476a +9316,ca1a5997 +9317,dafa2644 +9318,8a757dfc +9319,252a45d2 +9320,68bf667e +9321,6d7187c6 +9322,1a93ea8d +9323,40526f2a +9324,ff443875 +9325,81e9d361 +9326,f0e01f96 +9327,56f9f2d8 +9328,da0784a3 +9329,a8e469d2 +9330,7e3478fd +9331,6f24481a +9332,0d65dfed +9333,847a72ba +9334,0f21d236 +9335,13e9183e +9336,d2b8996a +9337,3bae1636 +9338,18d2538f +9339,2bcb5390 +9340,1d38657e +9341,4c32a3a0 +9342,ec08fec0 +9343,120b8bb7 +9344,8aee1eb6 +9345,02eb024e +9346,1511945b +9347,a80daa19 +9348,2532344c +9349,a4800f0d +9350,5de15da6 +9351,7ff60f1d +9352,387196ae +9353,ba23a43f +9354,b17dac1f +9355,4d7a1689 +9356,dfecaed2 +9357,20cb77a2 +9358,52044ce8 +9359,7b7a7809 +9360,f0974795 +9361,5429d210 +9362,425cc36a +9363,d094082e +9364,9573c246 +9365,660f05e2 +9366,3e7fc1cd +9367,d67f9c9d +9368,57292ea1 +9369,d65a96d5 +9370,8a057366 +9371,9351f271 +9372,2a61224a +9373,228badac +9374,13d87da9 +9375,1979aa00 +9376,e8c4f63d +9377,ae192321 +9378,3f518080 +9379,8c20c68e +9380,b3452d7e +9381,97a63f05 +9382,5067daa2 +9383,191ed049 +9384,161d228d +9385,2a8b8c10 +9386,259b7399 +9387,64cfadb7 +9388,7f57fd4f +9389,ff705c24 +9390,463f6691 +9391,fe84bc74 +9392,979cb05f +9393,4a4b66e6 +9394,f6deadc4 +9395,633981e8 +9396,114f7447 +9397,12d32e62 +9398,8e72a101 +9399,45237275 +9400,f68508c2 +9401,5e95d8f1 +9402,65b88656 +9403,23026aec +9404,c91a1188 +9405,371eb509 +9406,39673d80 +9407,f931c05e +9408,eb7bf62d +9409,ef367c99 +9410,7b26961f +9411,e23e92be +9412,f4d939b3 +9413,2d9bfd98 +9414,0db1fb7a +9415,108a4a11 +9416,3f2c001a +9417,f3c2dbab +9418,bb3cd6ae +9419,fa841547 +9420,b09aa022 +9421,170b7665 +9422,c0bbe778 +9423,8dd15b9e +9424,d48a5e04 +9425,47168574 +9426,3712c741 +9427,a98974a8 +9428,42b8c4f7 +9429,8dd4f19c +9430,802b2afe +9431,15d305f4 +9432,4334e1b0 +9433,4fd83458 +9434,01bfed8f +9435,2f3746c0 +9436,75fdfd6f +9437,a137cb58 +9438,6fbf6b2a +9439,49369a57 +9440,5ad4913c +9441,b8d5e3ca +9442,40ddbe4d +9443,5006e9f1 +9444,edaa3a07 +9445,37b524ac +9446,48394ea5 +9447,ff4c70b2 +9448,08dc72a1 +9449,f74ec9c7 +9450,6fc53b5c +9451,c4afe8f2 +9452,d7908961 +9453,c78cbc6f +9454,a31e2cc4 +9455,51e63c66 +9456,1182f9a4 +9457,5a61ac3b +9458,b6cbce1a +9459,3e7ea85e +9460,07fb2a4c +9461,f3abd6a0 +9462,69586c4b +9463,f939bd23 +9464,fc75bd38 +9465,c298d44b +9466,0f26da55 +9467,a9994541 +9468,fd2443c5 +9469,b70b7033 +9470,811c9a59 +9471,4d51faaf +9472,57745f0b +9473,ac224b64 +9474,fd066835 +9475,41aea3fe +9476,c118dc33 +9477,df1cb811 +9478,68a52191 +9479,681605ec +9480,c2cea50e +9481,6e58b236 +9482,ecf98365 +9483,6697edcb +9484,ae5b6aa2 +9485,1b42cc0c +9486,7ad62bf7 +9487,8171194a +9488,db35affc +9489,4cb2ca04 +9490,972b1feb +9491,3046746c +9492,61d507be +9493,073a3653 +9494,0ad971e9 +9495,ba36c0ac +9496,5a86911c +9497,97d7b5c8 +9498,fc2e33a9 +9499,750ab182 +9500,f12c36f7 +9501,eac3909b +9502,a952ce22 +9503,53a97c26 +9504,16770d44 +9505,e48eb2b3 +9506,fe71459a +9507,7ac09923 +9508,23a1a0a4 +9509,4599091a +9510,53871568 +9511,717f085d +9512,c7b44c9a +9513,898c15f2 +9514,66006e0c +9515,0ab7f10a +9516,6ca708f8 +9517,a73276a1 +9518,73cbb438 +9519,5a628ddd +9520,2782e470 +9521,d7396deb +9522,b5dd1c77 +9523,782d0762 +9524,135d596e +9525,635a22c1 +9526,4998d6ab +9527,53578a9f +9528,ec7ed2a6 +9529,d5da4745 +9530,aa094f0b +9531,23004e3d +9532,6a4f5680 +9533,eb9e14cd +9534,5bb512f6 +9535,b2d433ea +9536,71bcb4c0 +9537,854590fa +9538,58dacd99 +9539,12cd5743 +9540,54791a38 +9541,40d18ec5 +9542,a985cc19 +9543,32fb1fac +9544,720b61d2 +9545,10802d56 +9546,1c75e585 +9547,44e5ff91 +9548,e8d56648 +9549,5f8c3725 +9550,8e4576a2 +9551,44129992 +9552,85755409 +9553,b92fe35c +9554,dd94dd0e +9555,dd8e3a94 +9556,03ec6c2a +9557,6f8727e2 +9558,83673ae0 +9559,faa341f9 +9560,5a5bd464 +9561,21fa481a +9562,ca58dfdf +9563,e8a1e837 +9564,693beff7 +9565,2e10c23e +9566,c31cbc89 +9567,bf11ba01 +9568,6b8cf305 +9569,67a1a646 +9570,54c95d7c +9571,062200d9 +9572,5e66cf96 +9573,cb1f5f6a +9574,b0633812 +9575,d161bf8a +9576,6d7a8fc3 +9577,562ac5a6 +9578,038320fc +9579,e7b60345 +9580,c72572ba +9581,38fe2ea7 +9582,bcf1a8c6 +9583,2f42ed88 +9584,417e07da +9585,1e6bde5c +9586,e3acdccf +9587,ee0a4caa +9588,52e2f692 +9589,1d288636 +9590,3b6f0409 +9591,2a0503f4 +9592,6a88a191 +9593,bfd6b33c +9594,47f19b0a +9595,17aec0d7 +9596,4d537309 +9597,99b959fb +9598,a657affa +9599,fff86ad5 +9600,dc5f072a +9601,1ec379fc +9602,58a41854 +9603,01e66490 +9604,4ee5f15c +9605,50593c4f +9606,738df364 +9607,be0e6d6f +9608,fbe15249 +9609,d8666299 +9610,83f33314 +9611,caa656d4 +9612,074cbb5a +9613,707cd299 +9614,7d6a97ad +9615,19f691b1 +9616,cfbecc8d +9617,820d7996 +9618,c003abf5 +9619,bad940b8 +9620,a11acf10 +9621,37cded92 +9622,c14f0dd4 +9623,e06a6c63 +9624,6f4142c6 +9625,a1596deb +9626,13f1fa15 +9627,db08fa9e +9628,81c2f657 +9629,c9ef1406 +9630,7b73b3d1 +9631,22255cf9 +9632,b7f5239a +9633,1131b51b +9634,435b5eec +9635,c75446be +9636,354de7ce +9637,59e82c98 +9638,9f4c033d +9639,1fe25dc6 +9640,421bc970 +9641,f252a546 +9642,c2dd9423 +9643,e4115074 +9644,c8995742 +9645,f601f1e0 +9646,abda051d +9647,72627b2d +9648,0a2a9e11 +9649,2f36a717 +9650,bc81e73a +9651,bf8eb97e +9652,1276ef9c +9653,5aac4ae5 +9654,65f3e0d9 +9655,545a9c53 +9656,08ed5e0a +9657,3e22a9c4 +9658,a75ae431 +9659,b4836b6e +9660,a5e51ce2 +9661,094fb7e9 +9662,289d968f +9663,a1227570 +9664,b4f99888 +9665,f9f8e139 +9666,35465b81 +9667,3b966ae4 +9668,3ffcd749 +9669,0b56da75 +9670,6b404514 +9671,451b5a64 +9672,722996ec +9673,6a4bbec8 +9674,d2f1d8e3 +9675,72e92eea +9676,ccee3cd5 +9677,c0db1824 +9678,69a8f45b +9679,45d3b94f +9680,c651f69c +9681,606783f6 +9682,25ecaca9 +9683,1d12bfde +9684,18cd9b67 +9685,140da0a5 +9686,f5e2baf3 +9687,3e504ef1 +9688,adb89ba5 +9689,a4dc9b48 +9690,260dc227 +9691,a7df5514 +9692,35e53e2d +9693,9d15d706 +9694,0ed590f1 +9695,ede5a3a7 +9696,338eca65 +9697,f81e8814 +9698,1be0db23 +9699,90b1c17f +9700,7d61333d +9701,56afea2f +9702,c9be9713 +9703,5ceffeb5 +9704,e1d74090 +9705,5b0d1cee +9706,619b06f6 +9707,80b13ed5 +9708,b6a729d6 +9709,8717af59 +9710,6c0b746e +9711,3529ae1e +9712,8d953d9c +9713,e3604411 +9714,cb7e265f +9715,38ea8da9 +9716,891a34cc +9717,f54c815d +9718,1b0b1186 +9719,8bc6c82a +9720,99289c7d +9721,70e0604b +9722,04e1833b +9723,36379f92 +9724,018bcf64 +9725,96ecb640 +9726,bc3c8fe7 +9727,324188ec +9728,71da31e9 +9729,92d5eeca +9730,a226f55b +9731,45178850 +9732,0b07db48 +9733,48113cba +9734,d805f8d3 +9735,6fb08939 +9736,89d7b6a9 +9737,02327323 +9738,6ec86502 +9739,3f964b85 +9740,7e27034c +9741,24d97a97 +9742,ab2421ff +9743,bf5137db +9744,742e277d +9745,85537775 +9746,470f77ca +9747,333989a2 +9748,4562a53c +9749,4149c4e4 +9750,23ac31b0 +9751,b45368c1 +9752,656d71dd +9753,c9d15a60 +9754,772a4b70 +9755,2494c5ea +9756,43e08e14 +9757,9be3d895 +9758,412570e2 +9759,055a3c98 +9760,a49bbae6 +9761,03724333 +9762,47d36913 +9763,a24b6777 +9764,4caa3689 +9765,a2d56103 +9766,42771c0b +9767,26bd2b0e +9768,f38be10f +9769,11d5c234 +9770,73b0be1f +9771,9da9b57e +9772,35724b6e +9773,e5997fff +9774,f22b9336 +9775,519c1663 +9776,50833461 +9777,99ced6c8 +9778,d3795d55 +9779,916a072c +9780,adb9b087 +9781,2c414e9c +9782,64367e78 +9783,bc5440d0 +9784,9fc9828c +9785,d6f3bf33 +9786,d36d8c07 +9787,f7668db5 +9788,7e5484c9 +9789,3e2d3358 +9790,20883d41 +9791,23465aa7 +9792,920fddcb +9793,caf62f3a +9794,10ada412 +9795,73d14ee6 +9796,fb16563d +9797,2a4dcbe4 +9798,8897d89e +9799,3b3c9c06 +9800,671b9436 +9801,cf05926f +9802,d8780005 +9803,03c587b8 +9804,84d9c355 +9805,fdfdc4e8 +9806,ea5d1f2f +9807,4e7b4545 +9808,9d6c5951 +9809,969a96a9 +9810,313057ed +9811,1c102d25 +9812,b57727b6 +9813,eb80e1e5 +9814,fbbc6971 +9815,1fcfc819 +9816,bf48583e +9817,7c4c3b32 +9818,eaafa1c9 +9819,43dbf44b +9820,414731b5 +9821,7e194d76 +9822,9f0dc01c +9823,f47d3b2c +9824,0e1e302b +9825,d2f86632 +9826,72fd73a8 +9827,72732cf0 +9828,ffe59a47 +9829,37ede554 +9830,64f7a20d +9831,b1e771c7 +9832,797008b0 +9833,f3528747 +9834,0b009973 +9835,f883db6e +9836,f84ea5a9 +9837,354a8254 +9838,67f25d77 +9839,c7e17c72 +9840,00209f65 +9841,f2a72b37 +9842,f958a0d8 +9843,bce58673 +9844,f4c85336 +9845,4a7c58d6 +9846,025b57d4 +9847,0096d05e +9848,6b3b0fa8 +9849,45d5e8a9 +9850,155b43c8 +9851,37ed20ee +9852,518ffb5d +9853,306d5421 +9854,8c3ca8f0 +9855,5f90786f +9856,a8693bcc +9857,f344123d +9858,c7bbfed4 +9859,478f98fd +9860,d57eedab +9861,a3976cf6 +9862,415416d9 +9863,7fd0f993 +9864,2dee075b +9865,8bf4ef6c +9866,fcb24f18 +9867,f6da2911 +9868,399ee130 +9869,ae58666a +9870,cf006a8f +9871,edf78791 +9872,af29bdec +9873,cdc696f0 +9874,74acef21 +9875,49291a71 +9876,6188425d +9877,a8c6a9aa +9878,0b1e82ee +9879,1ae84d79 +9880,cab57b40 +9881,e544bb6f +9882,b801dd3d +9883,0d633ac2 +9884,47a0336c +9885,9a82a506 +9886,c7e386ec +9887,579957b6 +9888,d5f796d8 +9889,90a2212d +9890,9faac12a +9891,a48e0f00 +9892,fc8e4252 +9893,32979c14 +9894,c6eaa94c +9895,8665d138 +9896,a73e5497 +9897,af3674f4 +9898,7170b536 +9899,f1464e77 +9900,3af2ad76 +9901,46e5df67 +9902,e79860d2 +9903,05a29284 +9904,5eb3efe7 +9905,07a5c388 +9906,b8695e6e +9907,bdba9f3e +9908,3203a279 +9909,2176abfa +9910,88b6ad57 +9911,0b5a01c0 +9912,0d63fa92 +9913,cb6590b2 +9914,c88b4f46 +9915,a1a03a41 +9916,df1ba99f +9917,2ac86aa6 +9918,8a0b4f6a +9919,0beac709 +9920,83838fcd +9921,7e03e861 +9922,583292b1 +9923,b20e94c3 +9924,66afe3de +9925,8c30d644 +9926,7bc72b22 +9927,4730062f +9928,6bb5aeb3 +9929,cca323fa +9930,59386015 +9931,a1dcd291 +9932,ee0870f2 +9933,b45879bc +9934,6d323ca7 +9935,e2bd1a80 +9936,c2d8d4d7 +9937,432a02b7 +9938,e0aae338 +9939,f908c120 +9940,41d58929 +9941,739c0212 +9942,c0490e21 +9943,4ffbf7e0 +9944,38d99e7e +9945,9b146a01 +9946,05bdb9eb +9947,7ef59722 +9948,0522bc1b +9949,814a86c5 +9950,51c5e0df +9951,415be80a +9952,f432d03c +9953,2c5ddedb +9954,eb8ceb8e +9955,b388884f +9956,63357a6a +9957,67eb1e4d +9958,b134ed85 +9959,8fb475bb +9960,20be3b70 +9961,69db0f14 +9962,90df0701 +9963,0d72c5d2 +9964,4be756f9 +9965,1a4e96b3 +9966,0a6ca772 +9967,718695fd +9968,1d24d1bb +9969,3c9c6c69 +9970,5f76aa55 +9971,678850c4 +9972,da8e3d46 +9973,92f7df84 +9974,55e03938 +9975,0a41128d +9976,cc96420e +9977,2a73a740 +9978,91d61f55 +9979,b7305624 +9980,f0472bfa +9981,e34b50d6 +9982,3250be63 +9983,eb53f223 +9984,1db45e66 +9985,8fd9505c +9986,d377ca84 +9987,fea4e3f1 +9988,98ced4d4 +9989,c5240710 +9990,531f97af +9991,f860e217 +9992,1f55f042 +9993,8eaee101 +9994,16451bea +9995,3940baad +9996,dbb5817f +9997,2057e4b4 +9998,47350890 +9999,ab8a03d0 +10000,17b1f547 +10001,aa5bc981 +10002,0dbb5d17 +10003,7b72f377 +10004,9e14a3b0 +10005,f8c429fa +10006,77d0ce45 +10007,3b0d6167 +10008,3e4f8a49 +10009,b6a63edb +10010,eddb5813 +10011,f0eec31f +10012,711c2faa +10013,7a75c47e +10014,15a1008f +10015,2213a3c5 +10016,603d681b +10017,10786e3b +10018,7c4be7bd +10019,0d361f51 +10020,57198660 +10021,c5c2a7b7 +10022,9dd5069f +10023,c7870bc0 +10024,6b2ed843 +10025,9cba44c4 +10026,4f896dd6 +10027,aa190ecd +10028,c19a1b63 +10029,1ab62bd8 +10030,7a7aa105 +10031,20316499 +10032,f59ea3a2 +10033,e0c1c462 +10034,6a921206 +10035,74dc0e82 +10036,bfa1e553 +10037,48c66505 +10038,145a9d7a +10039,6e7bb5fc +10040,7260099e +10041,b2b967d3 +10042,421db297 +10043,a36fb7d9 +10044,3fb7aa36 +10045,16c340f4 +10046,4f6a98f7 +10047,d44340a6 +10048,a256f26f +10049,b5f53294 +10050,3401fc8a +10051,554ba564 +10052,fc19f6fa +10053,1363303d +10054,1cbb6893 +10055,2457cd61 +10056,ec130aa7 +10057,ebb12f2b +10058,a96bd88f +10059,ee257d63 +10060,7058c9eb +10061,1f20abae +10062,e63d7c4c +10063,d4c09b9e +10064,21bf0521 +10065,bf5c4d41 +10066,d19a2880 +10067,daa07694 +10068,d91eefc5 +10069,473a8e59 +10070,afcd363e +10071,b629ec51 +10072,e58649ca +10073,16f30cc6 +10074,967c7c5f +10075,bddbf7bd +10076,ec364b2c +10077,9b376f96 +10078,24b65d12 +10079,ce3549e5 +10080,dc6256fa +10081,0ec22523 +10082,7e343ff4 +10083,47d8dce1 +10084,574baea6 +10085,7b3d9bdc +10086,6389343a +10087,98f9db82 +10088,6aaff5e7 +10089,8cb15c1c +10090,c3ff1311 +10091,0054cb7c +10092,6a1c6c4e +10093,856f9813 +10094,54ad5125 +10095,f354a5aa +10096,258c2e13 +10097,c66e8302 +10098,33f0a6a3 +10099,7506aa6a +10100,5495e299 +10101,aaab3a1b +10102,5f6dbb89 +10103,559b433a +10104,e10cfc53 +10105,bcacd3e5 +10106,6f0af149 +10107,75cf05c1 +10108,6ddb95b7 +10109,47d3bd79 +10110,43229715 +10111,1cf59acc +10112,3eb26d31 +10113,08539a5b +10114,bf6f079b +10115,550749ab +10116,006777a9 +10117,1d32ced4 +10118,3845d2c6 +10119,a4c8481d +10120,fb6e74f6 +10121,fe7cdbc8 +10122,43afd0ba +10123,a6b504d7 +10124,6618825d +10125,e8891a31 +10126,720c2d35 +10127,0e27833c +10128,982937a5 +10129,fa46d347 +10130,4a40459f +10131,e3ff0817 +10132,a5027f16 +10133,97c56c6b +10134,a6a722a7 +10135,1f6605f5 +10136,8534f100 +10137,0b6877d1 +10138,2df0838e +10139,e7d34523 +10140,c7c99e2e +10141,d088a606 +10142,8a91508a +10143,4067571b +10144,253271f6 +10145,e9bde805 +10146,99f32e07 +10147,f30bd089 +10148,79b4cfd6 +10149,ff9ed808 +10150,4edd7a2b +10151,67cff703 +10152,adb18c27 +10153,fd9dae4c +10154,654b29a7 +10155,a8448591 +10156,983428f7 +10157,84affdf4 +10158,0011f240 +10159,7b40bc25 +10160,d7ed777b +10161,05985a50 +10162,49665c48 +10163,b59b623a +10164,bd6290c3 +10165,2fb70dd1 +10166,2e66a6e2 +10167,1acb3883 +10168,bf69e33f +10169,ad6a00c7 +10170,2e61a87c +10171,0fe998e1 +10172,c85afcaf +10173,bc2f3917 +10174,c5313c3f +10175,d0a064cc +10176,effffe14 +10177,73840413 +10178,a789c66a +10179,6f17acf2 +10180,c017c35d +10181,ee1a6825 +10182,6d65d4bc +10183,d7b2770d +10184,268df1d9 +10185,2383b40e +10186,7fb15921 +10187,32f82ae4 +10188,ec055785 +10189,49b842f9 +10190,7f3512fa +10191,4ef57693 +10192,f60968d4 +10193,fc1d9171 +10194,2c92b174 +10195,c55a964f +10196,7259d8c8 +10197,b0967ccb +10198,1fd02610 +10199,98b03a9c +10200,5c3244eb +10201,e2b6295f +10202,9e58d79f +10203,5f343cd2 +10204,a0788895 +10205,21d456f0 +10206,e1960c1e +10207,627e18df +10208,3d4563f7 +10209,eac9649d +10210,ddfb2a2a +10211,287d94b4 +10212,88cb2f49 +10213,786d08ee +10214,d250a3d2 +10215,d37f7389 +10216,1bcdf96a +10217,8f3a6174 +10218,2957e333 +10219,32a5e6d9 +10220,6c354589 +10221,f049ef33 +10222,3bd31baf +10223,0d278c05 +10224,f4357ae8 +10225,b9d5d066 +10226,418fa8bb +10227,b6ad89b1 +10228,2c288e73 +10229,42cb89a6 +10230,0a7483aa +10231,e949feb9 +10232,be76d61b +10233,1e457962 +10234,1a11f10d +10235,f0e22fbe +10236,88ff8902 +10237,02075256 +10238,f445f996 +10239,d71cf181 diff --git a/hashlib/test/fixures/xxh3_128.csv b/hashlib/test/fixures/xxh3_128.csv new file mode 100644 index 0000000..6a8aa50 --- /dev/null +++ b/hashlib/test/fixures/xxh3_128.csv @@ -0,0 +1,10240 @@ +0,99aa06d3014798d86001c324468d497f +1,5475b13fc0b8d7cf77ead0d66864b856 +2,69678912745c112c05c08cdb816da6bf +3,46dba47e4156ef81fa5bb15de9326deb +4,d1906609236b32ee279fc3d1d13bb06b +5,8b3de1383f8a636aa7392a60f9276fa9 +6,b08462f8071a74e872badba361c36316 +7,8d35a615774aa328371acfb0d64f3414 +8,f4b3bf0800ae5000024dab1f476f3ab6 +9,5bbac6329a486831d6a4ed92ff20f6fd +10,83869ee7243df66f1c940126d360fc8f +11,5bd05995281890b9844e500f73940921 +12,6c6b422f39209d39ec26331d57ccbe56 +13,1f034ab82388226402249379a642b840 +14,69f12649819e99ff444f45ae8efff136 +15,817408ab1b6a0c6eead22b57631ef53f +16,58af7a6e2d2a850b7552683e3834f987 +17,84a8b2d9ac249b55fabb09ac607b2233 +18,c87732764b8a69cec820bf90eb718ad7 +19,1835ed1a87e9d64491ebdd52a35207a1 +20,2568bd0835258f43892d18cd9cd549af +21,76f2ee70bf0568df8b5144bf93b5e63a +22,f17da06a1d9c9ae8d035cb16ef8406c3 +23,6cd48319561c1727c067a961975b84a6 +24,bdd3f1b8926a57189965c742c1d72c73 +25,2c66f967a267edd11f39c5a2cf8e990a +26,3afa0e317a799dd5e68a67890d8b3fc1 +27,3d8e8faa289474585cf873631fb41665 +28,483ca382be9378a077fa7f6baa4e6130 +29,892a1c0a097a0199c6b46645513d096e +30,2dc74b8c5f2c33e64ef4a5204b04a4e6 +31,74a8ae5eed384b65b2acc9142c909000 +32,8ce7de94da44cf5711fa26bb4c40463d +33,50a5e276825855ddca67a6a9c4c7de00 +34,7bb71404cdf4e7f67d3ddac2a764b248 +35,2922b6de08de9b8eaac85eddd953bc6b +36,c55de976a9de4007e7ebccec88a75f2d +37,04eb2dbad45f41fa7cb14d6dc0b24268 +38,b16dfa6f5cacf7e491719749b48d44a4 +39,5109b03cca943f6ee310948d2bc7b33b +40,9d83ce1eb0bdc8d1a810722ed4a95433 +41,5349496491c14e695e7cb21eefdb5df7 +42,aca193d167139bf2ccea4fdf093d950b +43,146bfdb96f78ddb9de05bab00101a7ac +44,03ee3dbb67eca1ac3528c42c81ff97e8 +45,db7c1f69c4a01bbcd3f8b8c5ac0db189 +46,836e7fd6394a229cae4bc6f6cf482757 +47,b365bbc4d9a038dde19b002926a9786f +48,1dbfe3430bda31988359def0c4ff6344 +49,1d9c1deeb8d845571469ad82629a007e +50,696fa9a54f6599aba901b07411c6437e +51,066bc49826ab1a953d2b1b3499de5304 +52,757450f0c351822b9d9619fa9745328a +53,af1f2062aa946f5febefe6ab6dd7d411 +54,562241cfe1ae09f264cb99542eb3523e +55,9d20531a96122c2e16390b7eb18f5c72 +56,059e132f67bb372c49fbeac49026d370 +57,5727994b0570390e3e30291e7621624f +58,8f52715b8bc2c65a5110f83dd6468725 +59,b26932f2cb6e0eec8af6f0f44b00666a +60,dbea7aea3a9d2be65f775e76d8d9c8d3 +61,a3966b0946d635802224a843b42978c4 +62,994b12d4b0850dbc0dfe002f261bc2e0 +63,baf4fbdd1b0672a8dce97c0ef0821381 +64,a3011477853f296ed7608f281e51eb89 +65,083590bfe168f58de4b2f1bc0022df71 +66,553a12433db5a800bc9007cd2fbce445 +67,0b9d75dc284609a204446baf3c1f10e4 +68,4c8c0cbb311878a2d9653bacaf64b519 +69,ea4b92ec63e23bcc7fd0a43870008473 +70,f3a6ae4b8dc75478707e70c6abb7421f +71,f02ab3433bf344d43c2d577f01bda67a +72,17812467922eeed3e5e6e230cd098a05 +73,dea49fe28221032bf7476665e5d5c441 +74,32f4d82ad99bfd61da718dd99da519e9 +75,d9aca64761ce1caf2120b8f7dd7caf46 +76,650f214f9a2836c85da392643903f0eb +77,03c3fc127395e1d5c201ed2aa60e5f07 +78,2e35b77e1c0d9f6aa801ceaf0a9ab946 +79,606a3fdf47d3cbb06226b85e69b2b932 +80,81d716fcc7b21fa22d0dba88166fdf61 +81,7f650ddac1ed96125c665d80fdf70096 +82,f0d70c6bbe15438cfc14e03be0a7c5a1 +83,df360e5e2e25e068fe3d114b52b7f3b3 +84,54fb79f3f9b464fbc2dc11e6add08666 +85,cd33360b648e76c1083bed6b8b9e8a47 +86,0b37f51c67bcf0313566123ae61cc8d0 +87,69a15c31feb0376b00523827254c7254 +88,3db50fe088c1f39463ca1cc860abf8a8 +89,3835166676f7dd93549c832842c30e36 +90,a41e2e2207bf95fd363b9d764546d429 +91,a971303bd1132ab5fceea0a118dc4634 +92,489d3445759b1257c3a105019d8553b5 +93,323e1bb34dcb04be1a8aa12ee06e346b +94,d21d53368a29d7ab2291ab2c8cdb88b1 +95,8a6b46d29a72fde199c505f051b80e75 +96,d642f7e144e5e169d8e05c047e548829 +97,4ba7847e11bbf6aba2fbcfbdeb8cc8d2 +98,0a46c9a62f0a26b7c2be68dda905a86a +99,8664e6ece4e24bb00b73206127ac9f09 +100,baba3723c7e5901ce962627dac510f02 +101,53cdd58805b1fba6c8bac6dc78779b25 +102,1b4f8e6271023f376daf5088874db10b +103,63df775c411ec01ed7aa472a28214e24 +104,921f9ef1f3fd333f5ab26243934ee10d +105,2c2d35045e9a9750a2e72d26798bf4a5 +106,64ff6de0b55132483f2fb7a8c8652cda +107,bab619630b155a394388b1de6489eef2 +108,1e86df45764c6d4c807908aba269c39d +109,687379e399a5561d12fe03d08d292477 +110,dda53b47c45ed71f13e846dc8395392c +111,4e1e33219f9f897dfe6f73c9ecfc4154 +112,558329a47961c74e3c147ad93ea3fc89 +113,0fe2e6b70072e5bd9a93f43d0d7effdd +114,965e00b1e4ed0396ef8358be80c2394a +115,68b246cd67259740cc5a23858c700f7e +116,b2fe480752c0777a16828e99cc070be9 +117,24cdcb0ab7ae918ac743d711c7e9f2f8 +118,c3d99eb4741ae6b1df61fff042e090d1 +119,cac253879bb1cd210bec22aef94da477 +120,0b1fdc716ff79d2ce8b44f7bc9f611da +121,93144b9d11aa4205b8ef41e7fe0dc84b +122,6701a4fc17c7681925ebc48810542a08 +123,11d2c0487e40a970896d55d440aa4917 +124,67f27cc064aaa319ef4121cc31a8879b +125,4de408dc237a24efd578dc0387c292a0 +126,3ef1f9a792a1a5446e54b0ea309802cd +127,25b78dc77e5408913457c620813be349 +128,0f878c798a30731c1276753697c0c193 +129,057a4332765d4cd8ef9eecc8a479e87c +130,bb7590fec3a65641512e93d55ca5e387 +131,94ce8dca48c4fd21ab9b9cc9ec3d3449 +132,89c012a02dce7820621c5e4d068100d7 +133,fb2e83f1664ebc6e9a1b5c2f215405f9 +134,91d74cb57f1b6710db512426592f47bd +135,036450b3754b8818ce4db61b93af9541 +136,77f46677692b9de39dab57dc4d9ac318 +137,912d571ae6da8c387e6d0818f1b482af +138,e8f47317ff7d934c6ffe856bddd628cf +139,8fd29514c11d24ed88825acccf557f80 +140,2aa61e64e984a62d8e527466c0daa01e +141,1e642cd2f249691f86de70dd29d351a0 +142,2b8e550234508f054abf9fbbc64c3499 +143,01e1961a886c096bc525e8962b1dd5d8 +144,ce33363b814085aff13ae621236021dc +145,684dd395c9b8d3f8fc72c62e3db2e046 +146,8b761d122553e1a297194d7cc3997818 +147,070a5c10b3776d5b5aae4baf604a8eaa +148,4ce21e39157e6d23f4313ef97d545f15 +149,6e7c1a37c50cbb95075cc5cd336a6bae +150,920055b624350305f7fce2add1e82968 +151,463fdc426a43cc421967873a19a80b40 +152,1e8122718b7f45ef18c98a85e52ac8e2 +153,83a224d1011443193729a7e5f33fa41a +154,48d617b10caa98356844016cce8db459 +155,07831ad74582dc806da78539c50fbb8d +156,47fda6cd9ead4fe19bea4b7d3edede60 +157,9be19d4b62e25c06e061dac145fe1945 +158,cfcec698219aa7c993b3cd3fd821ccc0 +159,517bfb5a6fd36f2ed297403b6922da7b +160,afe2a2fdd59eb41820df4ce2b273f0aa +161,7e0d998f0de50c41be187dc96a8e882a +162,67986699c97e540fc0d58593923d0070 +163,ceb62388b1e9ee16caa4c694363aafe1 +164,a210d3fb6ab249e81ca4ae3bf0b2fad0 +165,625093049c59b5ee52c20a74fbcc76b8 +166,ed06cec1de35d5e814a6b617db5bad6f +167,38b3d0c51621e29c6724ea52fe1890fb +168,0459b83d718633ebfcdff77ef5eabb1a +169,4744c90377fad20da156d60862dceeed +170,dfac2ed619458ec073be010da2f2827e +171,843860524500c24ccf2c8260438dcb2b +172,9b77e00e1db0303b596f8a846e740355 +173,a5df5728cc994e56b19ff9b86e4ad50d +174,80742bdd61def2070ce24477e17344a7 +175,672959592cac28a2a41525173f6dfa4d +176,ba1e7bf9799b0c1cc580d96086df78e4 +177,83086673f3932d0e18fb021eb23b7feb +178,bed28348e090e4112388e3f1297da00b +179,725e718c506d8b7a5229a96370cded2d +180,7f3d97119442ee8ddf0d86ad291dde4d +181,8f76b124be70cda599d4e2dffd24d538 +182,8529416425ca0af6bd71bf8ca819ac1b +183,e8fc31dd8a3cdca38808b62454f88bc7 +184,8c7d983fb21046e5f0b357cdb23ceff9 +185,78d0f3c5645d5f272527d22989fd16d7 +186,3d635db7a35c35de6564f90c48087a59 +187,a6b276e505078b48999e97bedc65dbcb +188,0285be74e72a267d240b3ad1f9fdb89a +189,cc3eb4a183abd48f1fbec133b4690942 +190,41a0bc49a47e5e4b821e9e199ccc9722 +191,060ffd03a1db64bd9b3883630f3e6504 +192,0a0f47d0f7f8fe034e0ddc2c25b331d3 +193,8db57dce5484261882a7948bf4db425a +194,e369b9ea72cf0266f4697769ccffcdaa +195,238f872ae2cd6e37d330eb29dd5d9148 +196,8ab12f7405acf46e4a66a6941058c375 +197,9b039e177d8dee4e2f4322528371d750 +198,26e94d3ca819f48220cad60e999af02c +199,3e3e1b4a499bfb4283959171809c754a +200,afe63024875f4e66d577e16e9bdbf162 +201,b7ff2e9d6acef56eee636e2338ee1fa5 +202,7ea228aac7e704a89cdcb1f843a25098 +203,5c5cc84dd8e51169a76dfd0c552bdf08 +204,796c0cff8139750fc8ce192990f25ed7 +205,264ba8157bff432fdb4ad503deba47da +206,534ee7beae08127d34a80dc3c4e64951 +207,ed9c97aa1425b24b62531b77972ca69b +208,8156f06cf93350983ba41cd1d96bbf61 +209,31a535ecb3e4c6cd6354810f66a8dd41 +210,9fc6c54462ac2d0a12b5821c5f54830f +211,a56e07cd7732244cad9d33d62dedca12 +212,637d51a5327b5d9a9a80b315712cc110 +213,d6c8db72c1bd5a7723c1ac85405c9a1c +214,5401b5f33332e726f693893b2c0f5e3c +215,3f0437a90bbf59778873b0d1927a2dbc +216,a1e1c0b58cd104f0db28c65f65ef643e +217,bdd4ea220efce79bf281a476999488f0 +218,bcb1696380df82d40bd0ccc4d4c14847 +219,653ded0e82e124584e926409dbdac580 +220,bf8da2a37d6ec2ef9d4d41518821c9eb +221,0884b1f004119e3b43ad92ff7278d97d +222,d76bf64122dd40f6a93668e7f7a83a0d +223,93d2687900c34fab9ffc8a0035dc42b7 +224,7a120ddd89de2cdc2c33e6f33f063fe2 +225,cea7d4df694b59c6f44746184039d877 +226,6fdb2ee4a35328b8aec4239b11bf3f00 +227,c97f9b214b65a2f79c9670365e132497 +228,b2a5ec16e8f35795fd9069909183cf1e +229,4dd02f8114882d175f9e540d9ce1d525 +230,d21f30ee939d98a0c5c6f2cb3db86800 +231,250f5b3e89fb406eca7a7b0cefe4b8de +232,040ec7a385755d4494ee7c42d56de3a9 +233,f5db1a53b8ea2c6c272f67a0649f80ce +234,6a2bbd4004ff8c799eb858cd5dd06aad +235,a9b2fc2c2bd171f607360e523c47dcdf +236,288f2b9863c7ea3d4faff8341e5a75dd +237,25e1ad4e878c99b55f006a7f459b31bf +238,acae026cea9dc58b6391a20056bdee53 +239,cfcadcae4b5292df103dc86b7b00ce33 +240,b1507ea4fafea54ccaf36cbdbef4fec4 +241,6a5435e3c8e40f1d99be286ee0cadc35 +242,56e378cfb4b2c0c5cd25b4ae0eb1f30e +243,a613d5da10ecba512f345a20084c415d +244,f0ddd670b22f4b2fe4fe1900b4758823 +245,aab324a6fe660484111507439e906b8e +246,f86b9e6b36aa944a4ae37cbb69e6dd9e +247,7d7567adebb692c2ae5cd69628159762 +248,faa986e0949c5c5155092228169c53fa +249,0ec4a3454ff2af67e3a58c41acda5ba0 +250,85c7b9649445eb6c59b1249cd17870b9 +251,82ed617f34e1d8c56548d0234c320037 +252,48a99f39c546361bde8825bb706434c8 +253,bf6d1abb9cec70f08277d3e463f15b1b +254,9e9d876ba8ac07d0716862b5619b5c39 +255,17d7b310bc1bedb2bb01d7e7eeb9e64f +256,14cc540aa2704f8a29189de8bfcc5dd4 +257,72b5917bae802e020e9fe81ff4d617d8 +258,e7b97b24ba629a295ba4821a157e39eb +259,1ce045cf963f131d8ae8a0d72e091d19 +260,ff2c553b021ea71a1c124b722ca44bb7 +261,f272a4e61ab96be909687e846b91d89e +262,a0cfe3dc509188445d9c483021e72a14 +263,ac1e1b202165449658905ca05de5411c +264,7ce3bacb8fe135e3769b85137eaba2f2 +265,c1d885fa4f76c94a6f551e17c871a6b8 +266,d2342884d230acf38dd3c5b85f026908 +267,1d599679c8bf6a29ccdecad2203a67ac +268,c125766bbbe426b6d0a397d4431cb4cf +269,95fa5b3eb252ca4c4c7818b3a269a49c +270,989de45d82572dfe5c0f3b0442231cae +271,aff016ab632784dd146f7e91fe668f28 +272,fef1949844d60ec6b29b40ac0f1fd3d0 +273,0a509f46422ae9f6ce48a1e93f0e479e +274,37f750a2a28be16ff71e3b01b2549d22 +275,ee9a3a9880e82c0902879a0b355deefc +276,687f78661f0bdba9a13d4e4500500285 +277,d34c129646acebefe070e38b58d441b1 +278,9d5bde29b9059b7f99e8d5d68d1706e8 +279,638141214b5c09e460db46e19f79c550 +280,9c781f64a7be7a399cc2fee827b3da26 +281,076f38b83b15ef4332a06b7a5bd58f0f +282,6e969afa3180e9a47de9dd809b8b0f60 +283,04674c27b36d13c87eeb3b61a284efdf +284,3799cba0d2c64619b17c87b37ed04f57 +285,0f5444d199e230a8576f556c5fa3ee95 +286,4a24b4aadc45c4c22ea95935bbdd6f92 +287,170abbbbc4cc5fea0c283a1e9c517ef4 +288,64a6ed97e5956043990fba9d1374bbae +289,7d1cdf862f3722e90b1603c2a79d3fbd +290,1181e5038ffc5de81fb97beca05ac48b +291,a4be8c158dc4a65f6c1a0ce179c9aeca +292,f490c159f7050b19becd2520116899cb +293,f6881135c4c3619cd713d84a38b22da6 +294,701f125af12bd29d575cc5557de74527 +295,6c88ea7b3d5c756fbc0ea8b791b17690 +296,ac4ab88423986cfd01998295c2357eb3 +297,6dd70bbb2c5517e33871129ba6bba81d +298,539542bd58e3e391c07261e4352bf028 +299,c31ceb7d5f1c6f91f30bd3b7ee93928a +300,a9a2eae9afc58a673dda14d16a77138f +301,69cd8936c39ae7b664e69ed9ba5c27ae +302,669debcb253d8117758905ffbd3e8752 +303,8cdd003487b041087d9211c2be785673 +304,ebd5e1da2d9d5a84f3550cc6793b89cd +305,34d2dc35a4343707d7241123b344357a +306,371bcd482ee70f5e53feef199ba8595d +307,2759bfe8ddc32a353094c71284b65f46 +308,549af78364a6ce0160eb5f6e8134f246 +309,658a99dc50dac41671ec86c94d7bb739 +310,c78481b00959efb18419212c61ecddaf +311,67a5b85c1b3f76d9eff61055cfac9462 +312,dedbb836de52d55cd0f86694515f4b69 +313,96b37d8d978b80607f136c7bb7dfdba4 +314,941ba25c1a23b2642804383b1186cc9b +315,a1af66724af54104d85197a4b7af7c66 +316,0f1093ec49525795eaf77261467927b4 +317,552b9864cd80d7da3119c5592e4a3dab +318,b277a24e7f110701fb5faf5e97feacfe +319,4df05095076c2a1fec4b59072d207244 +320,df341a8eff703dc2a27e7af17431f4fe +321,dcfc7d368b7cf74990f9e80b2f1fe869 +322,190a2e84d8c1ddd4a4510e240d3b0937 +323,ecf0f62328afcdea8dcbe37a13b0909b +324,e57eb752f9614d7e54b6f9c0f11c9463 +325,3a41b03191317c5fa7bfaad203816f42 +326,4cf813097c38d3a7e8bcad11d94eb5d8 +327,ea17028544e1c7208e82e9c81d53f94c +328,1028642295836cdd3dd18252fe697532 +329,303c855df37742d22823bbdf90c80d06 +330,d57cec62946a9d7482fb48bd52870acf +331,fcfd6eadbea8872b8dc0f66f19b71390 +332,45552c4125209fde53cb1600df0fea44 +333,4e450f6eed271774a3af597c2bd02994 +334,e5a0ee76da1e12bc8d0dcf9310795f10 +335,bcea72795420b083be60831e840c5cfc +336,de0b8a63fa19dc64cfd997b6e1b052fb +337,9e254b378eb662d3bfe14dd334786279 +338,5c96eae1365ecf397dc3821fe6e425fb +339,647d83d4dcac806c68b995000629e9f9 +340,3b803c8e460ba30759a4ebfbf98ee600 +341,9d7cb52f6b563d45ec56fbe4b9d6e83a +342,81f712220cd7ca5570235a3ae4c1c066 +343,954cc467ced176d53af44bac36789f71 +344,2702f85f8f0159bb5f5e98d337fd7fd5 +345,9e2c332d5f654edf4382ac075282051d +346,4ca7be3f8b0b82f093a4d5230a26b213 +347,4edcb1680a9d5c2a98fefe56ebb7081e +348,bf2e723ad1a5f8f36f53dd11b61f977c +349,04dbd46e4e6c95e9921f11abd7c385f8 +350,a45f34c3cfbe70555b21c415e6e554fe +351,6dd6e27f145b215a9a35c0fdf144922e +352,48ac117000a011b4bd965154a6f61ed3 +353,342f639d364643b1f1e336ca2156b4d0 +354,e9a839cfafb1850fcc5d2ffd7c2c913c +355,a36fb36a36555f109ec4fe4dd81f8efc +356,46308fd4655f1a63e81ac7a9c3b363ae +357,20f74b5e9810feba83fd4cf000b29673 +358,71736b99a6465898f7c4f35417cd4f21 +359,a3ae08b873750e30082aca0383c0ad2a +360,accb72c2216a4a73290e6227d9aee805 +361,37ffbd776f751df9557f789592025c5c +362,0ea8d3357b65980a58ad1e3dc47683da +363,9dedb33e5b89159c435397929cafb1a2 +364,1569b5f5e551ea953c781f3fb2c957dc +365,019e30f04638d7cde5331e303090aea5 +366,e30de833b83a97000983f8f5f301c10d +367,9c1933cf53e7f2e02ed9d48d96e6abba +368,fa8382909c8e00d9392edd6f8a23efee +369,488790a804da3abc24cb45927ecf61fa +370,e464cbca7d561eef4d38cbf605313604 +371,31cb3ade3493f7cbf29833cc91f73024 +372,cb5177fc90d97e11627b2ab212bac037 +373,d5e984c49578950375af21376b9af215 +374,5c70cb9b9697bc67d1d023885ec67f64 +375,f2e8c18072bcf98a783eac72fd7d6202 +376,86c371e9fbb940133c0bbf4bfa84732d +377,9158b3670f14dd62f7b9d14ec1dbcc84 +378,7315e56de1e8e07da8e8574e22a7d2ad +379,6d34e8f9c8db04a51d74c18eced7ed6e +380,b0a3009f6fefee969b273acc66d3eb11 +381,9503c95529809f6276e7eb5e24f43d64 +382,8a12834c853ff78b2886f9cad76dd07d +383,dc1b4a04f923e660d6ad1f3618874932 +384,d3716a6baa6f79decd4b75f77120275c +385,3859fbffaf59298acb179f72269730e2 +386,5be2c7425a858ab5d94294eed98fbea8 +387,ea0a0d75230ab6a63ee94a91c6c16419 +388,77e13580b750244899196699cb352dd4 +389,686680bd42f8503e9ee0ab639a0f3521 +390,b23c4b8b616f1ff0a4983a5d5db4eee6 +391,8ebc574a40fb67c3bbd1dd4f60d69a7c +392,df5965b690a5ea6c9519ffba87fb002c +393,68e60803bbe93ba001cf0303e0a47bfc +394,530ddd94e2ff93637bb6471ce048a0e2 +395,0e44ce4b5083ff026cf473c0a7d59f1a +396,85e9ba80ca54aaa68c412cb6c512f54e +397,cec3390467b4187be64083db32f8ce7b +398,9fc538c83b395893f01b90991dcc4116 +399,80931abdfaa4ae26335386ad4ded18c7 +400,3cf9ba66559d6fcfdde1be8f611984d9 +401,b1a8e9c468fd8e966aea5da6eb5083b1 +402,b5f07b8e40a8dd857f0a68ec238315e8 +403,ad54ce78fba08eb72bce6e99fa5671b5 +404,0f92bae40d8642bb1b3dacd30edba65f +405,fc58f8968d7f55b4b553aa8d678ab8f3 +406,6e631f6a6606b66ab0b8ea11120c8820 +407,b19f9ee357ba5a6036f416989d21e604 +408,dce47d06ecee546b11d778491e455482 +409,4739aa963de1aa0384ae48f55db110aa +410,592fdb164a942bfd5dac71caa81ea25f +411,1cec7949f23399d185d82483fc9ab777 +412,e15157844f2c2b3688725ac36bd075af +413,6dcda7389ad712b3d04c54fd421db1f0 +414,5ded774239f5d47fc454d8e79a7e8c77 +415,b419d3269bd7eec8ecc4a301920e9784 +416,53be8a86b1d831a37b7f097e4898b475 +417,72b6e485e415d7b28fb44b08eacf1ced +418,0d4b6fbfa08c0719df2d32c6429d5426 +419,67dce95d89377eecb574d8c03aaff16e +420,42d120b5301c09e214c228a8c3e10970 +421,15e7a375e5dc2210bc2705911891c583 +422,8c644eeb0c53ea04a89571320501f4da +423,1c282bfcad0ad2b8aca90c495c1839c8 +424,9c9dcfd4439aa27ca47eb533df3a8498 +425,eb2ce6e97cebcbf5a6272f61dc21160b +426,25cb9a3c7c0d1d862246eb47fae98af7 +427,50c938cde9c214ee254af25b061814ce +428,8629918e6c6f4cb1e69b32a172175f39 +429,f52a04e72a9d6f9a6a072e5853ba9031 +430,aa1257e3f919b02a12366ce722c71b68 +431,7e39e40782a65905b8297a8997d71acd +432,7826a58c7db93455cdf6d6e6929ad2a8 +433,f74053611fba9d076b207bb925cb755f +434,57c73b2c0415c1453e24760846c2e54e +435,c211270abd7ecdaf2ebc8c13567cba36 +436,aa7836d1e50b1b1a2397bf75131d5857 +437,ec150b11d67bdbb0646f5967da43c1e2 +438,e4e9eb0decc5cf2153f6f93b837a26e4 +439,2f3a440e41fe0f570bb8ee531779ce92 +440,7af688e481531616ea455e09251ef3f8 +441,9622064f5f287485e0f8a4d32f9192f4 +442,59d0096f57ba49aa21db213e78ebfb95 +443,727dbcaf8b7dc83c916463b3f7ac3bb2 +444,65c66bd913067ac5dff98b13fe594975 +445,9529400c71e5dc6bfde9e4be98f5ca3b +446,52c0e2f3b507758badfa7ea027058b2d +447,5aaf44425e2f9f0ec708cd24bfa0a5bf +448,7632a2aa8b7b9fed1821605669e4a80f +449,28d040f3621a350680cee0112cb83c2a +450,28ce4ba1756c9fb2c8505c3d4afb76fd +451,53697212541e49b979274a9d7f530455 +452,372007bdbc5014b1738ec45486925130 +453,659f977ae01142f1f266bd99210e2c27 +454,c68d3c6b5c92ce555c5f06422bb3cf69 +455,339de3aa80c0af9d808b289307faab30 +456,db212a220a4fee468df1611c95f54bc0 +457,d2a46c936e414c8e8c4f56139e5c3f63 +458,116f39a7858f3a82babfb8751eb4a99a +459,1d42c03757826ca5b6ce96d958c44006 +460,aa86ad67de76aba371aff67b62fd201d +461,5dc9eeaacf24d06c9e6ba7faaedc38b6 +462,5b6da44e1b5aafab00bbeb3499a84ea4 +463,a42054a0fa60a17d55be2b18dafd3901 +464,30eeebff8519d3e3e08dc14ddbd62ad1 +465,a100dd591a062fbc632b0bd646653e7f +466,6459b017de518395b229623c9ee5366b +467,53d8cc2fa24909a634dad2efa1f7cacb +468,1608eb367717a72c67883b818d9e59cf +469,c07a533fccc94b0d8f6903c6ed79b1e7 +470,1c47ed41a14e0a715f73fae41851a44f +471,a61ee0652d873879853525f7cf6d83e6 +472,60a6cf9387ba6ebda5bf9391cbac42cf +473,f5d78fe6d26ea028d019a4a1658b7326 +474,f554580834dc86911c38e7431d720307 +475,86501b0f9c322fae21ce26ee2fafebf0 +476,245f29a6dc487568a26acbfd6b2f2dea +477,c7690a46cdb63700fac905955ca77ef1 +478,2593ab07fb7aff0c6ee8a8ddd3794a19 +479,26a1cdb719dd3e166419e90698769434 +480,d9d32927cd8bba44b78bab92d7756b64 +481,72c75b89338f9ea2263dcf649858f98f +482,d75080f88a0739cd09dc412746abbf4b +483,db0033ab74f7b583348e3ff4a917b6b0 +484,edbbbd71e63f39271cdd6a735b000f39 +485,46f32859123bc4b9e46bdba7a25d2730 +486,690649d64b465ec34e582727ef97f810 +487,362d35b1ea4da9b91a8d146ec1f72534 +488,22f84354340b02dd06e1f7dc7e6b839d +489,bc92d44b0762786c0101f2ec7df97de9 +490,dc8174f54bd7b27f6401792dd97ab945 +491,2c026bf27b87005334094b816b7b9f7f +492,db5a497b158cb81251829a3a4bb451e6 +493,3fbd2c9013c61598eb283222adbdfdb5 +494,4db54a7e1b880a0f6206f7697425576e +495,1bfbb21545fca38a5f7beb20fefb6b62 +496,9e9a80791bf7f2a233410da57438aaf2 +497,20704d47e58d6290542fa7a9486fa3a0 +498,b001d21cf4a8c5f55d0851252cba6356 +499,56a1a513507a4e1acd38149dcc4f2d03 +500,8ef6c2703dae5c538ff0e8e11195ad82 +501,e1f92bc26692e9fd20581e0856547919 +502,588b5cd147dcfeb4cb8b15cd540fe3b8 +503,4319979e504db4a36a3fafb4402de747 +504,b92add94462d387af9dcb14ac21fd3cd +505,5f6865e584e9230029e54ee25d3eb31d +506,5749a498f9211097de83270ff89b47d4 +507,f7faa8b88d498c87c272f4aff0ff40b7 +508,507ad87e3d5a41d66dea145ed7813bf5 +509,ce19862008c887f656f3d62360dbbbad +510,af92a4c25606477d4552f7dfec612e41 +511,cd78ee8398fe9eab7f2ca356e93571e5 +512,5e51a02bec51f89d218da7a5e018c37f +513,1af9bdfe73bd594f961db3e43a948207 +514,77b33d7eac52b0f3b883be80c3d46486 +515,90cdbe15a042786b1baff6333d3ecb25 +516,c6f30cad324a91320e309ecf31bd1ab8 +517,3897e07579aa168910372baa11fd7666 +518,740a47b50fc15f8f8caacb42c1942322 +519,bb0cac3432fbdb577565588cb475a256 +520,2814fffa72fc9e979c538c92b5904296 +521,ae8a1b34dfab063ce2003217dd6045da +522,46035d9337d9d6e3a2f07a2cea03587b +523,fc0b890a5672d4e8a90771eceb6b80a2 +524,d9739e6b5b35b8a6fe39e55b9489bef8 +525,f0902cc40c36ddccb91ee5a873450129 +526,074febaff23c6da0193bccdcce469306 +527,f6f6f9927dcd3d9495d5d64b8b8d36c5 +528,9a6148ce1334a15f45945c6c790f33f5 +529,2f96ae2aaeb026a0a9f500fa8bd51ebe +530,ee1ea4c21ef98266663b1b5a1a2b191e +531,047030539b1adb8f661cf8c31248fba6 +532,d8b7587b071e8e8dce85bbe44a1d3335 +533,12671f97d61c50f7d3afee0eb719505a +534,31b91999673df7fe6b73c3f976a7ae5b +535,3e11cffff4953061026967ef34c4e487 +536,a4cd951bbf966d83678e66c471ff2eff +537,dce835689afe11ac0c33288ff407459f +538,b8f5fc0c0bf176c6480d63fbb8f2562c +539,ded9a268ff3d44a1823afeea870ce8a5 +540,438e7bacd8ba3e71b40e5e96781a626a +541,57e19fe8573ed2439de4e1286dd25515 +542,104e16e64aba68b88fc5ea5a2eb7ee09 +543,11a816015d8c314766e086a8c2020f7c +544,2b97278df6db4ab8c8d4f76cddb3f8a6 +545,b8bd6b382787909f8b11bbbd87617cfb +546,d64800f5860580136ca5d69d45c8bee6 +547,851d7e941f21bd56d0ac6ff48d59d613 +548,e4950b09d5137b377bfed5a77c571cdb +549,9448d9e847b0f9fbe697e44c33e506a5 +550,d836936ddf0665b9cb35a21304b47b91 +551,cf094e929962dcababacf57971307207 +552,e86fa022c5a5cc82be52980f17194f40 +553,57c57cc3480714a3ff20900024d4e4ab +554,d101da536717ecc421e42503a748d996 +555,fdfead7db32c1fc5b1500b136fe9f24b +556,7af07a045a0d3ddddc842aa007273b25 +557,300da728bac7930c51b4879c28b8c6d7 +558,851bec5ec73ad447555db21fa1101cdc +559,0165e47e5b0d4589c5307e55c11d4922 +560,fe2efcd81bbcde44e70057528a44e55b +561,73371011207b57243b291706a7afcac1 +562,d3d4733b24a594173c7ed3ceba622e55 +563,391d04c5d837d453067dd2fc5a5f1544 +564,b5117a86ef0ff371073847c80a859fa7 +565,152c20834b406d571a43ffc7dc0b83cf +566,77f85c03cedd0b5c503478e724e77211 +567,d726a211136c534ef07f4ad99f79c5e0 +568,9f750d055700564cb0b2a010e3b4ffff +569,defb0549b578e2f3aafc1904376a6386 +570,bc83f36d8c20160b464eee6913d974de +571,ad94e5743666fc910bd09f1a374d0f9e +572,f91d156527db3b601e34926250bd9822 +573,d638adfb4b628a4d1e5fd499c3b4aedd +574,e49b36b0df722d893c43afc29c631d13 +575,1f4be64f1747378569663d612905b252 +576,6e6c6c1577546376db045b133482b68c +577,474d5d365fb437d9ce5fff25732a11a8 +578,5e5f7958aefb67482e8a7c407649c66c +579,0c9c43e870b4c638ee67c54cfff0dd9d +580,490e08a06c8f9c65e142c8756d932e0e +581,7866627be3c69f6deec22e6c41508f29 +582,147a52c66f7dc5b2c1d453ce1e2419a4 +583,b09a92f92f594790629917871a7a4a89 +584,55b91f370e3bb1fe2d8ae017fbf09693 +585,a7503cc2b19fbfd737fc7c9c78e046a5 +586,2e0cab881a451790dbdb889243be06bd +587,ebeb7a55126cb88f5ac375e36ebf456b +588,bd9b287c32463eaefefb6ca4c324a6be +589,f05788d8d21405cae1a1d80629b03c10 +590,e6b85b92674d016eda7ece26ba64a78a +591,1041d39be43360e7c47a8304ca699b04 +592,854816fdcfcda7d8ab831b787e22ce00 +593,6d4a8fb49303b0b11c09b8a831e3d053 +594,554997f162b6a472d354a5f66fb802a5 +595,17550246ebcd923df02fc75419d373e0 +596,785c35767cb4cd2eaa4d29abb87ad74e +597,9923c14625984a15bbe728e0c25c1fa2 +598,9e9e4a6e81be492009280187a447720e +599,c1c9ce429e030284ffd34ccf3400fbe1 +600,dd357d21903c4b4b1261a4640ee5a196 +601,764beedab833e56f3e0ae8a59a3920ba +602,e73de09538d2aa32ac3d3783c166cfc0 +603,0628c44cea54dfe88832ff4f3f6c31c1 +604,0cf73a2401f2b5d0780aa43552db52b1 +605,3c38ae0644708baecc97f6fde10c145b +606,e887c5a0118879873b5f34f79675e110 +607,2334646327eeb52aaf6ba9c65b3c1c69 +608,b60dde6853beb82654752e61210368f1 +609,5cd94e1d8878a0af8491f05c2e708c46 +610,8dc363815062339e1ee4eb7c4dc53c28 +611,d358e0612d447801438fe4b224c64274 +612,5c121b4b574062705879655db9eeeacf +613,560af3829b075002e6915cf8ab46f554 +614,9885e7c60e7219057799c7ec87846c27 +615,7c5e41ca01c57cb9db9c95b0a19ebed9 +616,c466d814d950f92a50fd8bcde439bb5a +617,82d3f68f89ccb3e69c76e99058476a24 +618,309927eb9e97d2e3d4c2fc607db544f3 +619,0cd859629245d99e704d9b87ba4347eb +620,4cf7754ef6fa70b979079c92f75c5345 +621,669a36d6cb50086cd72eeae82e82118c +622,570b2dfdd3fed8b21b496195c6e68c6c +623,5da3f7bf219e389d87b3cdc07aa22d84 +624,f99ed61dabace5e6fd75f8b0f08674a4 +625,910648b7d6b5ac7cecd9c862de906839 +626,ef5c46d004d87de18abd376ff6b389da +627,9a018b0351f255158a39b7a6240e19ea +628,496369b5ff34b0c2947c2915b88f2ab4 +629,e309764c4dc15936b28ca246c224f900 +630,6bb0f2297fe771e468c390f4da4fcefe +631,58864da52b690504b812fee594f69976 +632,c8530ea749600a3bf3988f8b81f95fa5 +633,91f340a45dd55bdd28b5071918b4bd67 +634,766f3e5ef3cf48a4035bf907f22693ca +635,9fd9cc993848184fb5e16d1fc134627f +636,cb26a273e7510ad2e2d331118a2726d5 +637,87e4d08bdc7627af68a7fb82a1c412d5 +638,3d599fd25c5e014ddcc216099d62a29d +639,4976cdea44f1a3ab33c92dba23313890 +640,dfa20c1197245f52814e46583f1b4001 +641,f4e2f8ae714fa74fec23cc6ba76ad32d +642,8c4a46f9575c48923e22116e90e54647 +643,5def27ad254015b0bb847d333aebe445 +644,1349ec772e7bbe42aa5a8e699f2a8d30 +645,bfb28447a3abb63e53ce531403d643b8 +646,c8f93d8d66d77d935dea21f768aeec64 +647,981c3c616a98e81e8bdb550c44886611 +648,00c7f5da5dc972ba1f82c8e229a314b8 +649,8e1f82647ee687e44eb5902ca2300c39 +650,9c024061128c4852fdd0f489c1731e66 +651,756e8a4b9917bb1be27a2990d9bffbca +652,353c808ff77d724c8637a434ec6c1de8 +653,b38d67269de2c85c79987432db3c0555 +654,c904dbcec4849b005269863336495abb +655,f00400d6fb5d1436849a9df0cd1ac9d9 +656,f10bd52bbed1358381c9d4c4f076db8a +657,6a05dbdb8b0a70b8a2e9ac9ed85a34cd +658,3b7b04d4a2481b21479652216b805b43 +659,1f1a15e2dd351d40fe0296543b60a339 +660,18b3c849a6df31ff0894a5bdd70024ed +661,778575526f158fad0c2a82f868a75d0e +662,5063b2ad5e8eeb88ca2a998239591cb8 +663,3a9b24770009aa59ce1b4738229b9692 +664,9746372a8177f3efc0e545be2f59e493 +665,8bc1e596e9eceeba0add3170233b75ec +666,8be18c126dd56ea14044776043717b29 +667,19c800d182d5ad0316a5d2469a0cf03f +668,5ae47feaaab9ca1402ec30ce2081f98b +669,3a3d8ace69be353f7771f14c5d125082 +670,6e236159a5d4fb4bea8e04dd6c3000d1 +671,f6e92bb8654fb14209ec67a34012b066 +672,1d5c4971fc584f45ac9997658a72e292 +673,a96d176811d9e2a91d25753798f8a9c5 +674,79c3433feaa7e43d814b7f6e2a66ab8e +675,7e8e689869b8c8e8264e7e48dfec9110 +676,01f289ed174e73a152b87806cccdfe33 +677,7f17fb6d867a7680ff55649c0d6a0f84 +678,5d6b0b47eb8f5cb903a65fc6e822aed5 +679,70fc7c9b247e6e54894590cece816a5c +680,1f8f65da7d3b2158dce8fa3308960027 +681,72888e2fbb07a951b567fc0d036f7ae6 +682,55dfa5eb52a313be8448195747ef6be2 +683,908af9e38334b0af868ffd4b8129e6ca +684,3f3dcd5a3beb429c8fb01954e50bdd4f +685,c8af1c2c0f0eaa01679c23716dde2247 +686,52d6c7c28b21e6bfb70606ca4cab7795 +687,56c9d7391e29896f999ea6e912beaa40 +688,09cb49cdd71fe7e0238420d843f16f10 +689,bfe9906ab37425744d754d1610e04917 +690,2103b6cc08b94061a59cc66524494d39 +691,89efd55e4891b983d07d9d134951b360 +692,f7cf3e67aaa892dd271e161972c9ae58 +693,886333334aa1d6585704617cc4e936bd +694,d571a73ee22737afee0e29ef567f0e5c +695,d0cfbfe68dd29e07f2fa2d83bc378883 +696,f236a09fbc285ee65417feb7b3842a07 +697,4ab05e3910b70bf1cdb76b5a8f65ee48 +698,25f25d2465536e9d6752a98b1e6be0ca +699,440efa9f8a5603b9bc35c46eea89c6ab +700,a706ff5442102bf8a83cd658b145c2f9 +701,707fc25a29f8cb55e0c3c2b8b7dcf362 +702,a4f9b4ead71b27acd5c0b21aee5f330b +703,9c621b2105a8661c552a0b6262337b23 +704,1137c0840893c9ebc3b1ae4fc4d4ad68 +705,0f8237195178c2e71287078b85687d7c +706,36ea1b0d3042fd0a544606ced6fa3767 +707,9aef47c692f2a479275839ae86bdbd80 +708,839893d87b9766a2154020c5584eaa02 +709,0d60c84b02f7b6a8b08a528067dae860 +710,3bcca948c5fba1f7a45f80d67af185b2 +711,bf9c45aeb7f4e02f2d3d4646dac01993 +712,b121d5d9acd4f5265c78d89133090c97 +713,ae450ae73737a73a863aeccfbda5d323 +714,ae021b82d0ef20e97bf5d5eae0614bab +715,1a52640831ac085f5d41bcad930ee016 +716,643db7b9e6e50427245297bf6a5cadbb +717,a3bf33e7ab5bf2960a5bdf6241f0508b +718,f75c121cd161943102344bdbec297a18 +719,16ef0174dddf1d08e5f993ed1d7b8c74 +720,b12a778f384c7f0181d21a10ea8de6e5 +721,7064ad62f0034490bd3fe9d29fc9534e +722,11b11033d36cab11eaa4e786df3a7519 +723,9a7e8119c51d5a05b2737d0dbfe82c78 +724,0b2eb280302765fe9f8af61cfc582ea5 +725,ce48b9a80a96a4464c9ee71b532870a7 +726,46520920d6bc107b446d08a0a3ec77c8 +727,3b20d354aa0ac3c1109f556a9acefac7 +728,ca23f9d4fb81c959b9da5747305e3f57 +729,a6a368cbc6968729b8269aac09b8ed04 +730,185afeae69b242a68e3dde4734a0d461 +731,a751b7f3b400ff42cd5dad1842f59c39 +732,80b7905a3d26a5f0397a59f00168df51 +733,ead430a3ac7a544e7cc8ebac20883577 +734,7e4f39e3a2b9841254313db21b3778bb +735,c39aa534fc29c97cc12ae1ebdc04b09f +736,26233a7f5088530b3349aaefff6c33ed +737,31b93f992882d2ca83e40f4eb1114f90 +738,dbfe4f939d83cd02455012e9d35bed9a +739,0905a7c24b321ab2f9eea57a6037361e +740,2783cb459599261c22368dd118580c48 +741,6401286a9d038297dd8f1bf85455e24a +742,2d85cdd1b8eb45b64f72eebcbf2038cf +743,413cad1828405fc573cd5edbb5877065 +744,a1c43da778a5451b39de995c64515ce0 +745,5f21e6fece4cabd58015b49d73f5a877 +746,84418d95c2948394c8a5204ae6c9e05d +747,b12b9c917a5e13daecafbda2119f73eb +748,57d5410b589fa3f53c008c28ab4bb6ae +749,88ab95e662e06e34c696fc3a104382ec +750,e65ccd334fbcfc1db28444caed8510a6 +751,bb210a703242c638218d61e65f108e6e +752,af64e19e39ddcada2737e84fe46ef05a +753,f0c2e31b3fdd43688d8e8388fb18a151 +754,f89bc9d6e474b0ffa3d74298932d7000 +755,597344b68d0d8f5da20410f34f3371e6 +756,ab78bfe714599092262faa181d365007 +757,7cb2619dc558219dba60f8bc3036442c +758,49d5291a72f2a6dc9717442516ac0059 +759,e5958d170a6f561799d40496feb58c81 +760,f573c048d92707968a60a42c0eaeb1d6 +761,f328aaf7e55cf01dcdeb594acfbd613c +762,892ec554b76dc15b9de2c7290bd29236 +763,e131587f416b28c749f05e7e108d43bd +764,41a053a013f2b997996c1104f9ad2bf7 +765,5c1e242198a6f50dcc14ca735f28c306 +766,3dcd6c8694fa25fbba45c31880129e6a +767,37fff1e67a49ee4a927dd8044b5efbb7 +768,938b368bf11f8def8edc221f22c30827 +769,e18c53df765005eec9eacc0d7b1cfe79 +770,8438a2c002da8c523779b894e02c1405 +771,50ba3f6fbc3893ec0c8f5409812bb1a3 +772,7450f709d1940b63423e2d7d14d2af50 +773,0421814509e9b6e6b8c231a0304e58de +774,caf4443fdde596669ca5813b49d479d1 +775,a3ecaba484c982e9b800f7968e9dc9ec +776,97c140eda1c1bc3db54b9dadc6139831 +777,6a781b5a6646d4b1fb32e3b86f5234ea +778,b13a58b1e84e2cafcf885e9f4a275dc7 +779,83f9f28effabde82530f857f5dc1ce6b +780,07919eed83acb00e2a11d415899963e6 +781,ff89b7f2dbd87035a9f078ddaae42166 +782,a5f149aafebe02f7f896a9eee4b0cae1 +783,2fef1a39de28911343138b0155be8f16 +784,a15007187ef5feae4c1803c4a7580140 +785,8777cff3e9f6d107c351eb356d184021 +786,0811f4a61640813ec4aa0789f45818a2 +787,faec1d8862979bf53d6b97e74972d25a +788,d539711ab8bb0968cde1ae88d8e166d1 +789,5f47ccdf3027de0ca487a78e1c1b29db +790,86f8410e6c45e6fe8d584fd3f0fc53ea +791,149622bbd26336e26f68c647289eee26 +792,71f1c677715ec4e765fc1e30b8bf9661 +793,3669e780ea25d1b6baa39e15448db6dd +794,d41af9298fc8b093e6cdfe4f057ad8b2 +795,17d5524083bdab4205808ba246f54865 +796,03c4fbd15e5d89b5da852d375857c77c +797,530b4855a11b2d171a44534e8c186f4c +798,4af34bec971c176ad8740376bad70418 +799,d357c7b6780144c8c42cdce2d13bbf9c +800,dd89dae2e3454bd1b88322d6c4a86d0c +801,e2c8978e0f9e5af4e42a0bc6d500b79b +802,32a08a438761caf20d1e6f45b4f3d5e2 +803,072950ce812c5c8becbaa9d8e539af67 +804,3559270702d4938cde750dbe58835088 +805,7bb93f7c69abff1fac689ec73a20dce2 +806,6fd2717663497212ba0237d1f9a1736b +807,b371128f42673336d6fdea3012c2b8a1 +808,9848ae89e2ce2acd2ce6a86bdb89f15f +809,02183e36da99c19d9677d99a174fd119 +810,796fb3d8ecb20a7b1de00211fea48a73 +811,4a02ecd8e05029b27a84c14511c7a0a6 +812,874cfcc748a88a45b3eb964d20ffd3db +813,81964fb7db414cc1b1efbf2c57aee93e +814,dd8ac4c530f4f251724ec8af553e1c5b +815,aa72a1e0794c142f02e1c649ccc284f5 +816,5d48abf99a79b6d9237f195120ad6000 +817,8f3ebee3462dfac7ac571e49e30cbc41 +818,0cea2a1f2e39bb6d8de0fd1ae2101b30 +819,b279e6e4df612279364b2ed8d74ec4c8 +820,2e0fab22b3443e2a1276894a94e0503c +821,b7f0a8bc2323c3c008381cead9c4f7e7 +822,01c0ac2d611da8ae58d2f16c7660f6c6 +823,5bbe51838f3528c6e352e8a51e8537eb +824,4430017f7a3c25b96e8964f77e7439f4 +825,19925a75e3af945a3678f10d0aa080fd +826,d76dc9f515bfac518b6bfd73b91089d4 +827,940bacc64ae18e6f02cabbbe83b6a888 +828,df3c82cb5668a5d08ba279e49d8079d8 +829,64d1eb4ebcf1eb1865112a36f2648db3 +830,4edbce3714203a23442302d889fdc639 +831,a647b5300c97fd740163ae781376de60 +832,f5bb0ce9b2f68764dac51f7f4d209c99 +833,7fcae5fe6a4522672f48f4c90fee7442 +834,fd9e93fd3dfa0d1c2d475fca61c3ce1a +835,641636002483ac194b38b441e68ebbf8 +836,db1a4cf51ee5f227b916310276973d46 +837,5940d7e44dd6980704b80b5950fd0fba +838,22906c4cc200d029bbbd888e5db70656 +839,28f9c556837a0d85bac5b81746a5ad35 +840,8dae766441dc93e583befbac299fb7de +841,9863ee3e7088091505a29b405952bac7 +842,5112ae0a31667a787290ac4066fe136a +843,2628c5c9a78228ea21b4507cf5f53a56 +844,5be3dcc9be65f365c396b3571890ff65 +845,d87851631990247be5a893b826cea65a +846,76ae010a97be8e09acd3b38def3602dc +847,a5ce16633e01f8438dfcfd4e5b4fd565 +848,5dea251bd5c0b05b416146445912620c +849,1929b351570f28164451c40bab339907 +850,d333c26867ed4692d6b302b178ff750b +851,fd081030fc018fcd93218ad6089a73ba +852,a624f67380aa0e1d3a82b68d819416b3 +853,437d76609c213c76ed90cca571d18eb3 +854,9cf49c61e0b623e495a016a2436c8b3f +855,b39c5f36c084fa8ce3df1f022e5c05da +856,3fc91a1565a8ca4768987a83b56c8855 +857,f844a4c41b5a26f959e892f90137bfac +858,8ed588df3676338f8a78b6c4055b8e56 +859,baec52efe6b98ba163ccc5f39555a8da +860,517083006c524e51a3cdcae0cac60f46 +861,da13c1dfe6389599e398546da1ab5ca7 +862,e4f6de1e4165d31a5977d2684751cf32 +863,be52d91acdb68dc416fa9d74e400e0d1 +864,ad669a06cea8f89c729d63e969ed18ac +865,204c4038b9dd5f5ceb5de699efe561de +866,48eeff94f794b844c3eb359452d07c89 +867,a0056ae196f302f5e8b611f08732b90c +868,18c5242e06691a9a78354e74784c1e54 +869,7705f07d6b4e0a028885060167fbbbdb +870,4a844619795b4e207ca6b5c79b5373c1 +871,4af1b5efad790fe68560c203b0bc5289 +872,c1d9823a0cff616e4c59dc6742033750 +873,f165bfc2e3c74b7f8855872e404d75fa +874,de98cc214100c0167a0b9b8024adc8ab +875,57550fbfc3b8b42a02163f47c8222cf9 +876,702d3ce7797546584d6b0e9eaf6b3561 +877,b338327f8dbf6a7b4028813a3f35ad2f +878,9c2188c2fcc8b2e8937cecc574e8b9f6 +879,c965920d6d7c0b49b1ba0004b338355b +880,4b2943fb0b6c54d036fed1c4a47fbbc3 +881,95434347bb260f9a463d64848c3b0072 +882,b39e5ed5298762019011a9a4fe3f549d +883,043b2a1bc096743dea0ca6170e910214 +884,7fa384cd2977e5ee0a5efb0314875213 +885,c77471e8739a53fae16b9c325312cea6 +886,136fe01b5b0c8aa29d34e1ade7d6f06b +887,d76f138fa2babf4dbfe3b7819597447a +888,89b435bf014da4c3e8506ff29f508bee +889,1d9933539cf69f535ddddd739ecf908d +890,fa7bf72a2fc25f2880e174247ceefe9c +891,4d6cd112cd3efff63ff6e13a651cc49c +892,93e89570996f1cf4e009e7bb12fb6e82 +893,777843b6d0fcd6960a8210f71c721cfd +894,10cb9355ee6b1b659dba38d3c8c34aa1 +895,51cf6a87ea2bcd584cf8f32b6ae5dd85 +896,55b5cceb2c7a5582ad8ae1ebce7db334 +897,f02773fdbbad6ec2e92c2219d5b2b411 +898,611dfdb097688c419ee966522695748c +899,8cc29ef1bf42912ae54eb09bc6657290 +900,914cadd1a2f88c7648d56c73f6adb3f5 +901,d72c002cb7340afa0d0dadc6926a932b +902,69b5bc92ec04b236caffb049855f00b1 +903,c374ced520bbc1937d62e32a1a0d16d6 +904,d0afeda4a383e101f93841b5c9df2361 +905,82e8762490dc0b39130cc58492924551 +906,4562a7c4d1521aef54181565b482721f +907,39846bd5af9826e0770f487d218e0310 +908,25e7a7311141ffda4715b3a5969407a6 +909,b294593b2e0855d23c478580aaa09397 +910,bb5ee7dd60abd43f34fab57632cb8ce1 +911,012c6893005bbf8ba42e4f2a3c2df0c5 +912,33f2709a621b22e96fc90eb06a9f22e7 +913,2a4c8b40e8065d7b6b12c7d001f8377c +914,7419912dc256732a463dd713aca0a51e +915,28011caae8778a7f0b1b4bccfde22e75 +916,259287fc20adb706cc528bf43d544325 +917,5f707daec3d6a63c67e4975b051eeb2d +918,6d155bd79de9cdfc375204c2b16e2611 +919,15cb915dbc85590ad1a947a82c238da6 +920,778259993d692a3cc65a8953c6f719f5 +921,1b2c9990e5cf4f1feebd909d46065241 +922,a9acd7e527bc2b2ac12741922e72c6cd +923,24315eb5eb7b4ae6e9bbb62dd4cac966 +924,bf8f2f89e9bbbae09d73acd05a172b94 +925,79186f20848ff46c6c8648a9d6ee5f6d +926,da54bd0abdfb76d562be173d17c3dcb8 +927,3d3b941479f4711731a173cf44aa4f94 +928,ba75ba5eabdca4bde9eb7554cec88347 +929,774c562fecaa5a4d924d70774746fe74 +930,cb711ec514b8b3cb7c2a4fadc61c2021 +931,2f621da87e18eac2a48e3f3b57b5e150 +932,f6b1599a7785a5460dd35d4ea111c983 +933,edc204ffe6056149893bc6c193a63ffe +934,f2300249df43367790383d82060f8ba1 +935,37c44fb289b42ee95a924daf38a46e76 +936,122ca4bf58ac0db3f76c364e38e8a17c +937,4a0132780405a5cbfa076f7dccaa0d57 +938,add235aa4d454a644935d082aeb9a663 +939,0d1a589bc018a25f79c3f470549495f0 +940,46660786dcb1f54a7f811eb7626027fe +941,ca2acb9c8d746a31f2676feb201c10f7 +942,5e83c7b4c0871c64b850f904d845b03b +943,58d08e5e6998af559d32e9ed962b268d +944,31329595f2d682efb8233abb0811fd30 +945,e8b599494e07bbd56e43292c2ab55312 +946,bcd88e1ab5b3f261c51226b22f27fbed +947,3d31af9c20a31436ed5157a48f74dec1 +948,5ea4ad4c6ac28e3d6300db283d11ce03 +949,ede8e42d1c4842ec79960dd20e517d24 +950,620662b50242048d3f0dd8a2d1fcc1fd +951,85dc7f24cee70f03ddc76d1d4cc1479c +952,4f781e76194c53fcbedf0a7c1fbf9da4 +953,11f3c2d1b769ea2886f5fa35a0b7549d +954,33590edaec0e5c4f964bf247e30d8fe4 +955,f74d0485cb23429d5100ed833c330239 +956,05f4d2f6d234d3b926d9e516a0e36997 +957,0d55376366e537026e20760908a1809c +958,b74488f864118176f39a8aad5c64d737 +959,8760ae04567c19ff3e1da1241cbe7580 +960,3dde7d4d21fd23142a81bf3df05f2ba8 +961,395bbce2d23056ba1690a0e1b2e3bfca +962,74022b3987f12fd8bd1e76419e115fa3 +963,80a732aaca8fa678134df78252ceb283 +964,ea85bff9b83652ea9acd45011193230a +965,ef16b4f4aaee020578f2e99be4ce347a +966,88c8130e94408dcd3c4d0a98a46ec656 +967,20b51152fb013e5d084ce3854291933c +968,86192c76bfe062a3851d34e93e6fec0b +969,2cd1a09610a8a3e99baebf78265c8baf +970,39d82ef805e43cb4bbcfc21447bd1a47 +971,6b9549eda4d1426e83b0f9f012460e44 +972,76f3db896b1480aa9f00782d041107c7 +973,e9c16f06fc7c8f6bf64e4cc464ab10b8 +974,32214a84a9e133143cf11f63bdd517ac +975,946e9e52dddc4725f586977984691334 +976,b874d8ef3f9da32eb1d357f07ebebf7a +977,8a00a12958d94ca3267c3629b5666809 +978,bf0dba9dcde3eb1e7c9e99d48264aac3 +979,353d7336ccb8b4edff111339388bcb0e +980,996291cb902a7834fc956d8bf7740e58 +981,154cb6409559cb0261cee794caf2a9e7 +982,697603701f29bef9b0eb64a4d90bd64f +983,116ec4dd2a6bc346abe568e80732fba5 +984,a568d360597dbde3d3c681f45605d59c +985,0cdbd8ae86215b0ee2b2a08469652c56 +986,07454b2aa72faf15a6f2e7c7daeb4fac +987,43f56298d44d735ab5b66d7f067f7623 +988,2de084dd05744dee455b6f2561801031 +989,3d17d09ddab4a95eb1f12358dc34148f +990,c9857764a96738010cdf3193d20324e0 +991,a4a21d18106d104217a59c64fb32319a +992,7a18cd28dc47992b22f0831705f613c2 +993,426146df3668809e0ac25a5f7cd54820 +994,e75689b7eaf237f318866f52cd67816d +995,cc2d91172cd75191089bed9eb60893bf +996,a43e76a7db5897970870ddc128c8ecd3 +997,c52fd6ad3b032e19e792d591b4978ecc +998,89e5abae6db82a35d53fe06185af2f60 +999,051e9235f22727ff44e7c42c924268ea +1000,8b7510ab99ace3be9e6bc944162b8d17 +1001,fd34ef6efb34ba33c5d7cb06b1a07c65 +1002,66019ee9509bb7aa0f689c5cf391aa5b +1003,ccc0e22e3d67d2fc1ccc90f0e487cd64 +1004,beb2b1f7b163f1fd5ce809e973c1e910 +1005,58f80baaee7762b121a3ba56855c7c67 +1006,d4c0112a0be9a145daf8998fac5d2d1e +1007,df3b2a48b6a04238a2d91dfccd91d347 +1008,96735cfdd0e4a6edad9e3ac6416e0536 +1009,6c89ed42ee31843b67860798a18bcb75 +1010,6297a734dc857b2a4a94c48533ed1ece +1011,72213dcda0033834f6c5e9f5089463e6 +1012,acee5a9a2b1f4bb56b0dab746836cf72 +1013,33681da259daaedfec5509aed9d75ad3 +1014,5291cb7ed1431531eeed4fe695da9cd3 +1015,956da53a40b55eb307d72208594809db +1016,8edbb5bf90cbae584ec528b5ef24a5c3 +1017,576731c8a1c26173eba1570d1dd84940 +1018,581de1e00edd85eb724e33aa5097617e +1019,a9d6c5e76115ee4e03425249c07143da +1020,1a70f0e4383a6de113a7a497404e1b04 +1021,21dc6b6a46682528376ab9fa01c2a125 +1022,6cab299d0645b761f16b5b177890e33a +1023,14245a66f6f9b15d2cd035593114f1b5 +1024,0431e8341e8bd87a4e5a3638fc59c244 +1025,d864e359cae82d1e0b33fefe2401629b +1026,99e4c9d132063226acc5e389d7c530da +1027,570cf160e633cc70f84d7b98351c78ce +1028,1bbcdcdcedbc1ac3dbc8b65e0a778bde +1029,c2ad22188d98b1987ec83dab72821f97 +1030,413f11c8d5208b4ca4dca8d08c160a0e +1031,176e6d8e6141fbf5ebf34921ca10eb59 +1032,72722b30c769eed8e0685c9179d4660b +1033,7ad53291298fd720e9b1a92fac547855 +1034,9fc5ead1857e841055bc7daacf80c1a3 +1035,172f49b69751e06af506bee22621e822 +1036,dc4f5691c5a2f68612bd249bc34f5e89 +1037,a3ade4496c8b478b9c15e58001523931 +1038,199d015d2bcf43c80f9c077311620e5a +1039,47bd344697b8d82079967c65226bd1f4 +1040,a99e57d92f312a36aa4f09f441bd378a +1041,9508e3cde55c5e67dd4aacbef7199f89 +1042,c39219db1c6e42214e559da2f4639859 +1043,54c16f39cea1cbae5b93c081cb976aa0 +1044,8e9133420e154b87d6be2675c07de7e2 +1045,92e05bb511264109454f9c7afc4035a2 +1046,c71945097d19ee788bf3ffc7573ae25f +1047,fca43e663f7b4d832fa366975a98a0f8 +1048,e54e1d3651140f871a8737d86d770fbc +1049,5244377ef57b1198bb0dfbc049f2d332 +1050,5ddaea83c133bf2f7bb8032ee9241a10 +1051,15011abf3fad3413f7cfc3134d43bd42 +1052,04dacd29a79c292d87688ac179808dc3 +1053,428c6ac6d62a0140a7d2a07e2ff644ab +1054,6c0b2c8650a1d2ce703c45851307d42d +1055,f6ae030b19044dd6e8714c7fac2b690c +1056,4fdc6b6699b0ad005a511e18ff5fde05 +1057,71bae3b8ea223a5b87cb640ff53201d1 +1058,ed96285e2a2fa5671c77d8cc5d71b8c7 +1059,0f985d46289a4202170c5af03b19162a +1060,277c6f8ea872bc7794bc6b0849898fe2 +1061,c84bd383e23ff4b71a5588741c02bbe0 +1062,d429a813796e100999d69deb73d18e07 +1063,55dbc516cf47089eeb6f2ea98fc732d6 +1064,6a2329d844d923fbad3b089369a6327d +1065,e99bf278a8ca56c04943af35b6498eec +1066,198206f76e469438def054460cf89a7a +1067,fa43ad4dfc09e72659fd24fb7ec15bab +1068,32216e6907a1f04f87eb69495aebf4cf +1069,222fea95387f3032bdcc5c9f0d10fd45 +1070,3abc385bb510aaff9649413f0bfe5797 +1071,f1cda90d93c1a32c8891524258b6dfb0 +1072,59933e50006c03f2f9485438bf596c00 +1073,ac5e0f32a6510f68fd69ab15ecab69df +1074,fbbc74190b0a1e8914ab4885dbbb5521 +1075,0e37f960e76b8ebafa637bc6328ca789 +1076,10e8d34e6734e54e75b28d30cc4d6936 +1077,c828ad543f61d9d8809877a6ecd047d3 +1078,dd82d696656c26976f3975bb2f1c99e5 +1079,f90edba021f4fb6129507c5bab49528b +1080,ddc995f9d1993a4bc3e2fe9d75d93816 +1081,6f4d668e5049ae0772b90b37ecd703e7 +1082,d3bafe67389c4c30842879c4b073408b +1083,213577be1beb863a9f4cd65275a973f0 +1084,f2286947b882dfa147fb23bdcf66f948 +1085,c85673843fb27bb4a47bfaf1ab303faa +1086,0b25deda5b2ff4e9ee08505d7e25c954 +1087,2e5e2fd00bfc49788821ed7a834cef86 +1088,62fdd6bbf1e7c56d673a2a981a15e647 +1089,efaa0545710f8f0c46548aa9852ae43d +1090,df47bcb9285dd97907c16930629f8223 +1091,899356f7b90df49d57866b6927bd8e43 +1092,74e54636b81499b13ef8a5f883660ac3 +1093,8df3dcb1fe29f3e4f71eddf8c46e063f +1094,509089a22ba49ec015fed519387b65d4 +1095,30e1a534301249b3ffc87ea3adffcce4 +1096,e89444bd907c90477ebdf35e62e9c248 +1097,f9a6eddbb2436df2cc30972491a20d85 +1098,4d266a07a8c6837b729a27fe43744b75 +1099,7b9a5bb83aa113083535fdfd6ca2deb3 +1100,7cae44f9d26c54743f33e9910fcc6d03 +1101,4fbb8691a5c4e4ea38441cf31c1e75d8 +1102,90859d2deb06bc4e50ed0153dd6409f4 +1103,de948449dfb57dc26749cd546f8cd496 +1104,fa9b15db15c76fee98f58be7c13d7319 +1105,3919cfd02f7e06208ad8b6e9df458ed3 +1106,4c0c17c5c397e4c8f83695515048ab84 +1107,a7c271d1ae2f5b99fa3fa19de21e42bd +1108,9046c3d71484aa9eb9b7581e4a37f90a +1109,607476df1c2c21eed6744bb6f02a4769 +1110,3ad68c54541b033c65d152503bba6bf9 +1111,3178b72d217640a2a5e4d9c03776d139 +1112,82543da9ccbec5b7df29d1c2f27c7465 +1113,09e9dc1d487d75b30851f4ef253f57de +1114,0de3127f772cc225c8ef4833ae512347 +1115,6ece20517c8f728e73efe0b2604e7c2f +1116,dad3724bd3c6e80d5ad744f4704d103a +1117,6d17cdc087d81e389a3206a6fdf2c6f2 +1118,a9f919c860de81b2b5746a4a9b94769a +1119,461e4cd9406f113e97c0bed3ab55143d +1120,1adc8c6a064f01f66d95a44e063db5ca +1121,83c5aaa6ac56e986be3ad94c3a44b842 +1122,e1b4309cbab592bbcb78cebbfea24b0f +1123,736fe051786988fd071eb029431f7acb +1124,f09b4f8bed3d7ed19a47dae8df3a7380 +1125,a1b9cebec2a157f1a8ee6ac1059b69de +1126,27381fe2f9ea72a69676d63551351f9f +1127,aa912e949018e41ceef0a5ff80be73d9 +1128,53cc59804670d0b30c17abb9b473d624 +1129,b932aa1c2a13a4afb8bcdadc3c81c682 +1130,838b8da1a116501adac87b903256b1b0 +1131,02c01352041e0b0e9c5df3b675073b5c +1132,5de7af636e053b0cce2a5b4d52874cb3 +1133,69f03e5eb959cdd642f3e6613981d500 +1134,54d8bbe2fb97a744cdf94d48f40831ba +1135,601f352e6e8bf4d784cff5f75a1a1a85 +1136,281c08b1c42b62a5ce0a370368ce7ca4 +1137,5cc0583dc589c537e652387a3b5c6570 +1138,61f2fa39d48731bfd037c895c8d72c78 +1139,80c57b1c8bc6228820775f28b311670c +1140,6d503a4f81def12f2ed5b4357e132162 +1141,d1b16fa7b6d0d8d292c7fcb1ff235229 +1142,7887216137985f530e40a82dd8293bd0 +1143,906a18b7c4ce3d267a55181dd288c853 +1144,890fc4ebd243df38f010807490d0bf2f +1145,cfc9f34d35cda213d85e262847a7edee +1146,0b50036753a738ea9251fac561427dac +1147,a6fe3e776615f8f92729167b194eea82 +1148,dfb976dd3404fedf87936c11d01060a6 +1149,71ae693c3ddd397122898e1374f2be3c +1150,abd3af960ce627b64d0a05259cb30224 +1151,caeb426d4f099f9ec25019d07df5d3f1 +1152,fefa72e7d85afcd6d3a6ea593e828b53 +1153,54c0ffb54cdf0bb05862b74c003c7693 +1154,0a373c06dc1fea77f49e5bc5beea828e +1155,67e2f1404c0abb757bbb49f60ed89f0c +1156,711f1e93cbf3a72edfa2d56552f552a6 +1157,79f8be1faa15b440a8a7adc710507577 +1158,ec0d59a9ca06cbe9d4af84f23ada2a51 +1159,a1c2ad1ebdd94deb48e90389ade7d49b +1160,9a4996090f09dc44b015eae38033df00 +1161,b5fd3a0c749dfc046463ae8afb2089e6 +1162,857ba1892acabec8b09697aa87e89d4f +1163,3211a45f0b5a7a95d6e7f5ab1b3194e0 +1164,7e86544ea6e94910d4e1827ad4836045 +1165,87657753efb45cd0b189ed0917a9bd4a +1166,689213493e92a99b459c9f801a32740f +1167,a069c8b0eee83e556aaec4fe0762b8a3 +1168,0accd79b7061048c2c0db85e816d78ba +1169,921ecb3c20cd7f386288e250376827e8 +1170,e68d289aacea7ea4cfb13d338747d845 +1171,ec30732612688b4abbd68edd02a6ed20 +1172,c34be965e271eb828571e232db778b5c +1173,b6b8d5ea2c7d7d5057b7f5387526c004 +1174,f2d341fe4322971604a5d5e5f6d4525b +1175,f4016408739751d1ccf3d75669728dcb +1176,3a5207f1d3c00356d7a3c1264fe10678 +1177,7c816f7e4685864cfb4cd33db9827c12 +1178,143ad10117b0f80af39e98a17921e338 +1179,7625f9a5080c976befdd19b6f76ea3c9 +1180,eb776fa9826c0e6fc07cb10ae0560a74 +1181,97838aca7d202e5254880d3107f3adc7 +1182,1de119435db3131fd2b34261a7cb42d6 +1183,fc3f3387b3eb7fb7d80c3036762c79c5 +1184,43b507223aea00b9bcb5b87638d06010 +1185,22eb4ab43bea79513f22f60b5927e0ff +1186,7549d03da6402676bb6f4f14e8f23837 +1187,b69c595deb7b72c08a6ea2d8134b9d1e +1188,763b554979666d9e50e63116ddc26a87 +1189,d6242fd21f1bf6b578f2e4dd76c1598f +1190,3163c3225308bdc0dbb45dab184aa68e +1191,4ce6dbe5dac3ab74d8e71c2534f30411 +1192,cbf8f319efa0aa4b2e6cd3e5f31635df +1193,d723e0c3a489867df8bd3add66b9d391 +1194,286fff5000e68b77ee95fa5069b267c6 +1195,365b7b1e6dfb3be2f3634fffe3d049a4 +1196,7be78ea3fe9faf9f446ebd4d0d4115d8 +1197,e33c4f932eb55f2d43289a2024a981a0 +1198,115c9e6a887c049e55b265e17e44c1ba +1199,19df9f61be790b46580d01fb984d0c6a +1200,53fd8b3116d30e839842886d509345dd +1201,58b3bf1298d933c2edf6ac787f360ee9 +1202,af7d1a6679aa79f5422ef09df63494a6 +1203,5d34462a57fcddadc290520faf830966 +1204,9f91516e25642085abb2793fd557c151 +1205,3ed77cda93bd9055275ccd88ee1eff41 +1206,576d14bf89db1b7bf2550149919b0d5c +1207,25545ef35d1e076d5013c08f53a9b233 +1208,d32d72902a632d4023df41af933b42e0 +1209,2635826393b4774ee0c2157b131b393f +1210,12fc1c72aa3e35169d53f401bc176ae4 +1211,31a9af80eadb12e82be763838585e898 +1212,ccebd3959056c171b6285934465314fb +1213,4798f93d8d03055695b86c1ccf8a0592 +1214,75dae5513de62a8c3fee3b0f675e7009 +1215,2692d8ca85f9380d8255b5b4ec6d0a16 +1216,4f69c1d95be568b744cdd67ace3a1a4e +1217,932d41c1f5904aee029dfcd989dd7daf +1218,1e0fca2804d7a496cfc6a6426c56beb6 +1219,73eecbd9ae675a3cc7c9253d935c1b53 +1220,29577702650cab1dd3f28489f831bd69 +1221,754e4231ad9ea9e531640202da5b10e8 +1222,8315d3fd6471a70d313c07f02b6cc4e4 +1223,818e12d6dfa0e09371e19ddc35c4b2c0 +1224,fc0b65220906c9cfd1ef9477eb4e251a +1225,ab2f68cd1f5206b96a76a0ee79a82694 +1226,4b2461432f318d7a446ed51ee484039f +1227,962a95e987b23b1041c64d2ca3f9e07a +1228,788833bb6198d0c87cd00bc9185632c5 +1229,09eef42b9bd0b82edcf9d260d4d3e6fd +1230,875f6f2471bb911a26d937bcc58395fb +1231,e1207c45a5c8350ed5b48df514574c4a +1232,1e8fec6338025a1a9520ac369c86b637 +1233,285c1a761620834eefc2427b0d749f36 +1234,80bc2a4c010391f0290490249511bf76 +1235,6b9f7b6fb2a160a9743c23834e13e09f +1236,acf4c15764658da45c55526041527b02 +1237,8da70d4b8a206f8129e63c41120c7b4c +1238,e4a4314afb0661ee91e97f598aad126b +1239,174f545dd6f0dc58589c6c6c64ae5350 +1240,e9f419a7d5e876ec2f895b7096fd0c08 +1241,59c6804710eb64653a9155a63f27ab49 +1242,74f778f029d881b68ad4e85e4aff276d +1243,3faef3d3adf8f7dc04a8f2e839b53e6e +1244,13243d3e33fab9ea34991a4fefb805af +1245,c9cbd1f20860c9478c55d6c6392df617 +1246,9f473c226fafde9b8135c23954f00ca3 +1247,0fd84ae2b1040c5fe7b3de2e90995fc2 +1248,eb3bd7eaeac4e2ceb6abf9a104b4b56c +1249,dcc435ea45492ae20d3188d5b7098f93 +1250,5be13ac0a212225f28fb0036d312b23d +1251,440a6733f940da2ea493a61b2af5bca1 +1252,a6c478544a47eaa50db961d7a669b03a +1253,39d53350dd7aba30f1ca81eabbbd3063 +1254,8cb4378b98167e7099d6c80b7e3a2110 +1255,82f1f6722f559fdbd7029be4f07c737d +1256,8b5bba082afe0cdf9ccb9fae6ad7b036 +1257,86ba1e87b52f46038d05f288078ac8fb +1258,2883011cb27d0b06c010a3bb5303a367 +1259,f77188541842152072f1aa685840aa35 +1260,4fcdbb434c368c3ccb1cf87cb39c2756 +1261,e931f6b6f3d13b9f14b16d65d9bef1ff +1262,bdc8f44751dea36d8950e324f2053e0e +1263,b0e3c7931875be11171e470af8e6a52d +1264,331f349d5837648169d813614f36ed59 +1265,142cc7cd2d46dc525888795343435be3 +1266,7c3da6d2afdc20064636e3af530ce1b7 +1267,7b639f559555a083e91204f3072e59d0 +1268,d6e5e588667fb0f46973b3f68673ba01 +1269,c21e8494b4ade2310c22d0406c497286 +1270,62580b0d853d28bc83eb71e481466a7d +1271,87d7470efca297e4a14e1e341d46f33b +1272,446fd1ed63e874562fa4758f8624af22 +1273,97ffabe9791c35c0104978d0c56fa87a +1274,e2ed667a7d21cc925781d744bfd6e087 +1275,6de1d0118fc2fdc687741b9f28ccd4ca +1276,789016acce6fc3c0755ff5406e4058a8 +1277,9049dce01b91ca6b19f2d908302d5ddc +1278,6d9c69c12cc542709b12d26a4c087a94 +1279,09f355f56121cdbbe21ec430e8b57dd2 +1280,ea6efc70d5aaccc7e21deedec6a6cfc9 +1281,ff0e131f75266863136e4f22e2715eb4 +1282,1c34917869cef1907bb8dc3879006cff +1283,b52d072501cc140a6d0a257363a4a472 +1284,c840651d1b7aa7a0d9a41b22192f8c89 +1285,bf5a3fc11bd967dbb8ba9f58b7da7d59 +1286,44ba8bade74741f9ea9e14dbfdba0177 +1287,e5e3f6aec5d1b55a005787eeab7c28c1 +1288,30a8d1f0f53d6eaf7d5fdda0faa1de10 +1289,9e09010f324852bc7447d2876e959bee +1290,1718fe08af847a2d4fe8bbc759a0087b +1291,5ca4fd8265b41dfd26718a5aa4776d84 +1292,34b9c1a18ae7fdea6c6933b0a62fcefa +1293,7d8153c3869dec702ef9edd49ee7be4b +1294,5b6c96ada3f3a18fcb8af5d93b999cd9 +1295,081f214a9f5663f9f7ae79ba36c15484 +1296,46d71115fb0571c14b3e7f220d0e0b3b +1297,1d5356d19b84ba2203a84efea5675a59 +1298,611a16d5d1f4d87ade9a9d7b21040bc8 +1299,99d326f629a61258b0e017c8e9fdfbfe +1300,d584f8317b37d862fa4bed9336616249 +1301,5febd3d9b5285b9addbc7a7af46d647c +1302,536f4097d4d0035edc8819998377bd72 +1303,de4e6213a9e3505d5a2a7ad3013d7368 +1304,2f639d7a0fb439c79c911b3838a624ad +1305,e77525c8f9ef75b0bc24a60bfbad2cf0 +1306,e3bd7c61d326d5832398de359896ba87 +1307,c9f905cf076e6e234c1e6884ddf0878a +1308,d34b1e9253887e3685353cf5541af907 +1309,7e8b69c09cc05ab781a8ddf5bb431cda +1310,852c6aef5329504be8ec21f256cc2288 +1311,f27a5c2ebf0157addce93da8d5831ea9 +1312,b5597905fa23ae12350eb3145f3b007d +1313,7f03654530bc5372f4f0bf3542aeb357 +1314,e6c8eb3d30dd247963ae0bbbf8200ee8 +1315,7059d2aee262b9d4fa6a0d7d54023fb9 +1316,50829fbc27057f3a8ad112ae7760e82a +1317,15f7708cd954ab7e56b9382047e9914b +1318,b2765c7d5900d294545947e06efa5d20 +1319,64e19db0838e4762f54c6ec6d2464a1d +1320,db5f3cd3df948338db0d9bb91cbada77 +1321,6d2370609e224728db56b1742d18eeec +1322,7877bbc6f93ec3a36635494ebd86a87f +1323,24e3e8baeda04cbf4b0a34e49079579a +1324,a119315ec6d1fdb546a8302c34568009 +1325,4da98fd92a9eb408b0827aa13b55166f +1326,de8c6c2262cbbb09a848db03b6740735 +1327,e97c4490a3491a39e8a35081c89eb273 +1328,ad662abb0377d3496902a1fb7019d22b +1329,0842417ec86a1a92020528e991eae911 +1330,77c8990e026adac0517a2b3e6ba19acf +1331,51e1673aa1830dda95379afe12146244 +1332,6e09eef20fda94c2871e8a80d812d792 +1333,23faf222360b845ec75adb343ddb8fad +1334,211488edc3b34082dcf5a5ed302a2966 +1335,0be0fe2332f9c6d6a5ffce6325cb918d +1336,1b4764fcbf4085acca55ada1cdfbe7ee +1337,9f438de70ea1ed2f55f52206126caf33 +1338,1d204eff0002e294170d9f96ec8f0263 +1339,a7b04428a350a94d52eabe089cc83596 +1340,b961b77e18551ebe31376a660e879516 +1341,6e69cd6fa8619bb38d911a027ff4f31a +1342,772dccaf9857c37954f10e9fd91d545c +1343,4564adc728175bf0c813b5f7be127ae5 +1344,a3223e2b4b63994bc3fcde773e85232a +1345,5fa5277893d88f92a1e7e3a8e039be1f +1346,b5d6393ef0c9e098f2344fa25d5f215d +1347,2d92874f5365aace4f2c1251cda8b016 +1348,8551ba12bfd7f7f4794fa681ac9b0c80 +1349,f3fccc95b056f52701d433802db8a0d8 +1350,ce412cbe94e6baddee4f810666b15ecf +1351,27855c66b08f19305db4d229b98b2825 +1352,7e83c8e23a2a305af79b35f6221f9c41 +1353,4674a02e0de3f974befe6047552e7342 +1354,8dc292bb6a14dd8c5f5ac332b55caa48 +1355,06fa95cd5406c7a822979c9b9fccc55d +1356,7084626f40dfa11cfbbe044e58453459 +1357,5c406a505f3c8e9af50919845ebed6d3 +1358,83593cec9030e430df7ab72f68ea5c65 +1359,e9e657d65c195e88d9663cf4817eff00 +1360,38bed2158f4b7237dbe5e7b5d7b57782 +1361,403a153491a99ebccd90db32f211161c +1362,7d130615696c2ef3f069fb65533f3f55 +1363,bcfbb29a08e06dd559ba5d99cc182e55 +1364,1cace727fe6af7876d2e82602982d8d2 +1365,34d08fed117c4ba763ca6481c34165d6 +1366,bbc5e786e3d3268013060fcaa3ae992c +1367,92a45123c1ad3f0626a51f8b9b0906ce +1368,133cba2745c6988bd7d0696f0994bef0 +1369,d8d6a9686bda8ae69081788c5b59b44d +1370,c7319110f6275de7938009b4dd9fe04b +1371,ae44f91c849e8e9a9ce3fca8d1943a3c +1372,8ac0ce4143e07b91cd8dd66eef7c25bd +1373,4e7b664732f8f2677665749bc8df84ca +1374,740d5aee78fd2ef084197439eec83c92 +1375,a2452491b4103ec37714a0b0b6774b1e +1376,795a4fd2bf08b8c2a5510f93ec57f6dc +1377,22507193b9de9621f2aafbd1b1093f5b +1378,c5ea39f881394e3f040c59522362e9ad +1379,75017b852eb5eb0380a3e65000fafec5 +1380,0006bedd53050c117825d623905651f4 +1381,184d9b23494c97075a271a0e8f883cc1 +1382,d07429784a0249648f91baf5bd9cc47c +1383,a273e653803515cf61998388aee152e3 +1384,548019e23323bdfd7ff7c816ac38fee1 +1385,9ff2272a9566459e635040f71d21d672 +1386,d2dd1711bbb3b5417c8c805ff63d3885 +1387,984117a1bd9b7383954afa066f8bbc21 +1388,732efbaad96702bff505d58b6ac185f5 +1389,e2fb0e6adc30383e75681c64da785254 +1390,a8f7c8348f9f59ad36d204d9a7343fd7 +1391,7e1b91f3bd8fe9f4824d0af5177d7cec +1392,3950347f0cf5f2d6063f068ffd0f53b1 +1393,c8c521c6406d2722a9d54db75efa89f1 +1394,0f09f896302f49c0cfaa258360c9d650 +1395,550f60f3aa9302cf66149f1df9c44175 +1396,898c86e96b1876b23f30eec83ef8eec4 +1397,226cdd64967b31275c532d1c0a229668 +1398,0da947878599e1611fe2ef04d137ed41 +1399,c1ddc3dc6a775f623bb14b8ca026b8fa +1400,effed888dcf2dd8f2d2e75adcf3a9637 +1401,45d5cc118c7787e86d1d3a7a42a34bd1 +1402,16396a2941a59eb1af7307e4e78d1c61 +1403,cf9933259ce752bb5d5528ba14473112 +1404,67a0b7d27134c7623efa5866bba2b8c1 +1405,7b50e3b8dddf778b4010668e4837c307 +1406,53ee560506720276105031c4ce58082c +1407,64714a938dbd278d28652126744c0abd +1408,e3d66a4b891f1a48ad8068b6122b05a5 +1409,f56665669f18d9aa98bf41a48690e272 +1410,953e6b63a2b94aa394d7a6d74ba80bb9 +1411,8b9ba95a9262f46f03819d62503d41ea +1412,0916ef4fdf7f3eebb8f4397cb218166a +1413,c1cce12aab37f3e754311ae0c28b55a2 +1414,8bdf76e09ff5931a62795e0df4635601 +1415,95b21711fefe4fc3e6de212e4905aad7 +1416,1b4ae95310c5e9af6753f0123e91cb10 +1417,23a6f2adf93737d396ab91238bd40ac3 +1418,b049cc066925f6737f1de817d517be6d +1419,966aef9927ac9f1aad3aff3d9688958a +1420,c90c34503c3e29ca564f67eb414b1425 +1421,583d1bf7126280b5a438c46fce193473 +1422,4149e86f07b69978c8412b0fd59cb173 +1423,ff30842bb5978dacf2bb30cd70d02786 +1424,a4ec2d770592ebb20900e54908124581 +1425,54f2e2aa51e258d57bf7db445470f987 +1426,9e336521e244216fd79c74395e9c9089 +1427,c0fba776d67286e2303a71b5a3c0b247 +1428,709613bb67e0c6dc33e20290d5fb9598 +1429,0d5710ea00ce348beb5a911e02675c47 +1430,102733ac6efae77ed94d1e5279282e4a +1431,9daf23c63495476f1f905bfefc3fc029 +1432,897960b45ea674ce0951df4e6f52889d +1433,48624d06e914f11b1d807c0de4e82cf2 +1434,9a2cdd369f793eccafc00c2d9dfe3ae3 +1435,7dbe5e9863f39b2a5c4d0ddd96d3bea4 +1436,cdefe76128802c21241a0c05af7482e7 +1437,522b51f08b76a82b0fce040a3edc6243 +1438,6170ee3900e75a63a2bd37709e265490 +1439,c97aaa67f5b8ac903597d5a23d452219 +1440,3d782db2f672a29168e7768af7ac038b +1441,3bf85022539b5a7d851245be79f906d6 +1442,2efb629aedacb29c576725a84c304107 +1443,1e5b2c136c5729a6f4834317048bda2d +1444,073dd723e2f1959dbedbf0c2e854a583 +1445,cc661449a11329972d3239f288fc7ef3 +1446,9a6782a0058d5a6bf6e438d8dce1ffcd +1447,e4eccfdeeb1119eaaea3396b559d963b +1448,c79ff2a0b15a0710605d81799a34885b +1449,6cd9288be1eec52e95400fbd5e326b6a +1450,ca205c1bf5bed28b61742efc01bf1345 +1451,6cc3b7e6e7ef55eb32b25cf7a2ea3acc +1452,529c98403267b7142bcdcd1374ee7674 +1453,35777b8f8f9d6cded9de003dda29de7e +1454,c85a5996df12f87a1b999e3d60fcf207 +1455,6f21671d8854a9370f9681ef36bfe795 +1456,539b43148d31db8976d292f112a6cda0 +1457,fc069749bb2a1cc38ff313343d417281 +1458,a358130f42bf55070acce363665fe99f +1459,e11752a35babed259743149be0ba6804 +1460,cba84c2d8f98055e632baddac8f26521 +1461,da4c162f0759f49b061a31e11eb96c7a +1462,d47a64c851c437befebee73425b1a201 +1463,6901fce27567cb4599c40624c6ef2025 +1464,bc2a3df8cce0635dd27e0e2e2a062a32 +1465,470970e0f01d9ff7f921c6ccb8c9ab35 +1466,4211de7a745ac5808ff9446b2279cb9c +1467,b4322e6072635d03a82949106bd58bb7 +1468,de1f6446570c4d453d1b94f4c7cb7657 +1469,7ae92f7a99aaee6ceb11eb9bbcb290f2 +1470,5ec9a30114cb926dd9538e203efc7749 +1471,d6bc402feb3c6b6f00b4ae6a1bd5859e +1472,78d15a356289fbc49f10ad66ccb82b97 +1473,a63befd6bfc259a36e9fc04a740fac9e +1474,ff66f11878326065fe3e2728a709664f +1475,be3e935ce7b7c8055863f206977eabb4 +1476,aa343f8652fe0e2f20162479dc2a04dd +1477,6755e10bf8080f2a2d309dbe5d0483f7 +1478,cb732e846332b6cf9eda7e7c345de73e +1479,1d65934d0052ee35d8a34df64d7402a2 +1480,0c78ba09ed434fc94e3588ddbaa51c71 +1481,b9de9d966d48b50edab825e2a443e9c2 +1482,0ff3df81efb6ecc6f5bf6f8939e4b11e +1483,7785b5b92bde0572c3f252ab9eae7925 +1484,3f1f3b49c20f3e705452e1362ca53498 +1485,a84803ca03be6ccb0370928c30eb15b9 +1486,fa8bc4f34af4627aeedbb2b9731c9af4 +1487,fdab3ca1fe6507256338598c1a983480 +1488,8be8ac30e4a823733ad40446978c9aa1 +1489,281d2f5f9aeee9dceae5685f1c9db95c +1490,fc41c8ef9a0fcad782e7af65a8d35342 +1491,e508e4ba2ad4964d097609c88904743d +1492,2cc7e20ccfca707ae4f537643ffc82ef +1493,2a46954ea3654a13373c8b4ec2c5eedf +1494,c13eaee84b07596a849c635a3f7e2498 +1495,c35888b1c8779c2ad5db1cd16423ab65 +1496,8b370c549b5492927cbd4cfbf3b009ab +1497,2fb7fc78ecf09b68084dd43c4c76b574 +1498,49ce1bf659ade890c26579eed4831efd +1499,e0d4a1442890930849e538c74ba61bf0 +1500,ef05300185a66cd41031d7d882441ba7 +1501,e33421f163817fb8039c0a64cdbd50c5 +1502,d3092549748facb4cca2b813022408ec +1503,079bff6cbc74fa1fbf2af8dd371b5fef +1504,de726edc0a053dcfbd3404ccf717a26f +1505,b0f630761fc693087e1612f335cdaaf8 +1506,e6d54a1a4f4e326e8f7e4cf2789d410a +1507,2012abfdb8f063d9c7b433b20262acf1 +1508,30933cea481a7b9eca9fe0e88470260b +1509,8d7083f82f3a9dd37cef3eaa17a8ad66 +1510,e1cfbd1db38749f03859ad04318e053a +1511,1d5d195f149d68ec6d47dea2fbf9c047 +1512,07b8bc5ca29284cc27b158377109d856 +1513,dafa50cccde6ac7296afa3fa3d22d281 +1514,a6ce213f930d167fbf01c74d69f82be6 +1515,b204253a99e37006ee7c0c122f511ccf +1516,1dc97531423ba72e9e94ea84abf7d9cd +1517,c0ef10749da6bf893fbe3b42f59b668b +1518,ba361bbd1574040dded530575f7b2f3b +1519,044d413886b08f834f78bf6528f382be +1520,27cdd66321e33355be4514800bffdb59 +1521,d254920d4f41abf05c8c73c1bbdc3f4e +1522,77a3d8e4ef6c6b1c0e465952faec37c0 +1523,16471fdefb58a2153f5c5385933c1729 +1524,b238930cd58eaeceba81fa81d231c3fd +1525,338d39572862ae076cde3802f91e208f +1526,be4ea8d1f179d168f2f061eb9c28bde3 +1527,b3d2c2f641a2ba8d81c7ae8b146707ec +1528,5e4478e5c27c2af33b7ac95aca87f7f5 +1529,2c1933fe7e6945c30d9ad577d2a73119 +1530,6a1dd8e85528f315d9373de742f5c8f1 +1531,89a0289ae46ddc5e5e725800f6144e2c +1532,0e1958e32c9396e662b41840ae2e6d00 +1533,379896d481610234bc778d86c7e2b843 +1534,b26c17f6761bcbabb83d7101c27dd505 +1535,2f99e3b42ee72e787bbf19f9a90ae465 +1536,c3be0d280548d17d625d0dc2003c1fed +1537,f95ea3eeef2a0dcf1de460a1310a3950 +1538,e3711cddc6038cd452bc337c3f11828c +1539,ede29db6bc5698d821901f1ef98a276c +1540,e4b64d70cbb86b813315c1c034dcb376 +1541,bb85af9ff33dfba621adbdd1a1d91711 +1542,3518d54cb9c6ad8cf1cb728205de83c8 +1543,c769b4a0a65e595c1992230b2aa55392 +1544,21269d6015b697653c62a3946a9eb604 +1545,5a6c02b414057a38cf019136855b07b4 +1546,fecd323792b27ad9ef12be4e351ee89f +1547,4de6828325f72560d46553adf47dc86d +1548,5a5c9ca2b3a6fb22b2e82143fcda2fd2 +1549,e51cdce58f038051f692f047a546c5ea +1550,b4e7a69886f3115af30d027b5f9916b5 +1551,732584f8a0370d3a461747f0dc5991c9 +1552,3337ee7c10d6d97ae9f63399e4807b3f +1553,3a53c47b776540e52a8ed5355d755dea +1554,c91f6036b513130de631a58f55488209 +1555,8da9278e392e4cb200c8c12696ce44f5 +1556,69a91641c1f48c992b73aea7cc2ee554 +1557,b38e669915739991d9adc441ad5951b8 +1558,b2fe77c55c2ef15d797dcf09d993f747 +1559,0348d37331508f2806865eb0d4c4bf3b +1560,cfbd0b29929c59ada9e4087b60ca09c4 +1561,1a708b62d8692a487c729c6bcebf73c7 +1562,5c8f89349e690585b71af8a6c2fe3bda +1563,eafe26e175872ce0f8d39d439b8666d7 +1564,49d6af01b245c606d7d80d6564999373 +1565,ad8023f68d2ce23beeb83c2a1a14fe26 +1566,364ee5fc5662426f4bf97d2242186dd9 +1567,adb58017eaa62d5e83286ca1d348dd14 +1568,b3420766d04bf642a1a30b759d4c80d1 +1569,e7ca64dcd36a033b4d17dcd15fb1e21c +1570,376318cbe3c784f9ea4adeb5a90a1d4a +1571,bcdf043750a3f4c0bf5129b12a5ba032 +1572,258d154b59abd26d2d20d57572801029 +1573,86dc8686e1c7e52f5320423b20e7da50 +1574,0c5d064d4dc782b907f19e634c02f0f5 +1575,917eb8c04983dd5fa71c213dce720fef +1576,f6afc41874309223468d6beb74c14501 +1577,1e840400be0ea59b16958b2379264426 +1578,0391279fb4e191a451859f2901202fc5 +1579,afd8928fe655aa4f9cffe569c71665f1 +1580,2ea85486c9bc7092a15a9aa0f2142cd0 +1581,2fbba7cee777b487c214981cdd4b55d7 +1582,abf9ebd6d7235aa80ee81e57f7153e36 +1583,c1d95f0c3240d2ef1b1230059941ab62 +1584,b93f689bd96a482bda91296ba9a51de6 +1585,0f4511bea97d6a9542faf6095546cd79 +1586,02419d8e091fb658a45793acf462a428 +1587,b159b51a4915bb2ba9fb4d565c889909 +1588,004684fba4dd671ae155f64ec0b069d4 +1589,9b1e88a22f5551736aee942603b8e68f +1590,8b658d98c2f2bac432e047a093cf3690 +1591,ef60ef8bbb4b40bf6156eb2ea110756b +1592,5fb15292d8425f626982da80b9a1a81d +1593,a5aea757157ac09024c9c1a23872f387 +1594,78f7370fd30169253ee033dc14713dee +1595,5d276b1c858d8a4072b1aa9312db1d89 +1596,bfda6832f367b6bd86de550a821005eb +1597,f9b5966e0c21fec0937855f6a93d44a7 +1598,89153f71dfd1b83257f83a401658729f +1599,c3bc9ca2d21d4d4929b3678bf079eeef +1600,e3305e8d9e5c19073b0cde63ab13de56 +1601,b31a2eb22830c219e9a112a3f904859e +1602,368ca21153af4b143f913502e7acbc5d +1603,71e230e91fc246d6856ca28ac53edbf2 +1604,e19909df795c33cd663ef61e6e42ced4 +1605,c270cba9afd31cde3c58aff2e7e747b4 +1606,a4194a063cdad60351f52a049b7a5668 +1607,56cda859bd99bb7c552533677436491a +1608,bf155676e1def1abc3f579168c2657f3 +1609,c92654f752f28679ff1ac3d69d93fd82 +1610,eb048c53d52145fe8e413f36a8e356b2 +1611,bc5b904b7a4e74c7bb6b0c51ada9dcde +1612,404b576e2759e6f0abc123c635d34595 +1613,5958e912c4a8c84a58670deb46516064 +1614,6fd1fc379c2200f4fcf4d5074c8ad61b +1615,ea2ad0989a000d3243fe2e61f5af09e1 +1616,db34cade560a86a50742e15935525a4d +1617,c4f94ed55dfe74c6e71b521d496b48da +1618,788f2537a6412035a195b4b3069cb087 +1619,98174c4dfb1cfdec3e45369ef2d01ee8 +1620,773f0cb5d0d53dd1895ecb37fb821da9 +1621,17fbec820c19be63b950395acaa2b318 +1622,1f441c5e21ab96449b15771765220dc7 +1623,8fec82e3d4c2a671b1d3cddaddab5ede +1624,ca682e2736b374b0aa7ed31d030962a5 +1625,31e0d312384c1f553477458c826781f2 +1626,f3ec2ee00dfc7a95bd3f3b41014a37c1 +1627,19596b4ca95a73f360a145cb42541e91 +1628,74695a252c8802c2402ab15a751e38b7 +1629,e1f0d9d78931c33c20f10601c2436b0f +1630,b4bc9ee3ba76c5fd64f1c8e927f7b392 +1631,41ea2fa361bee1fea725b036088a7770 +1632,1f852f50ebc637d1aaea7f3bddf94f9e +1633,d15da586601a2d0a8142f6a96d13658a +1634,f365d41b51ee7e8724d6d127ee54d32a +1635,276fd491eb4457c013e7f5842029b7d9 +1636,3250048b5079f8ba0521176a2b1c26b7 +1637,b5e9c765fc405c0ac10137148c97d1ce +1638,9132a05a283e03fffd0c45cb36528792 +1639,6178615cbe896cea3b4a63dde8900fd5 +1640,9a51c81348580acc5de257bb27883216 +1641,779ceefa84fdf495c8b6ded4edaca7c2 +1642,29f7ea6109e2c0a2462ac5f7e54da4f9 +1643,09ddbcca0ffd02c01849ac7a23a44d9f +1644,4b8a76de745bb150629dfca187d66b4e +1645,027bcce723988ff970a76274ae3ccafb +1646,9238c11c05fd832122ec11b8b8d9ee2f +1647,6efac79ca76a2c943db894929eaeb28e +1648,92e24cfb5a87ec5b62db69c4171d675c +1649,0bcd8664d35cc65a06254761cb5b5ef1 +1650,eed19cbdf3856d9369e801e9552bccc2 +1651,e1fceb8257232ffb36c164e690f67db6 +1652,71b20caf1b9e86169e0018b1551a2f00 +1653,a5bfd47ef4ed9b4b21009752b932572d +1654,79b53ad116631636595ff4918c21547b +1655,03f96415f0c9374c693070c180df2134 +1656,b3ca44f0a519a410fb15bd4c53b7da3e +1657,95576224c23c5a025dc0eec034174b1a +1658,544e1ee9ebf5597098fbc1d311f161cd +1659,72605acdc72fe6a4a05f1503d2766524 +1660,de4b5c9d046b6a3ce1e5645569a70253 +1661,56769e4f92a5eebd08f7129285b3e071 +1662,9f6ea959752a5042529d523086cb06f6 +1663,b2bf312e9cf7ddaf38c5d5ed1bf49050 +1664,7bb392496b4ac0d76412d5f6b0db0a1b +1665,4c7896d28984f827d540dfcc00336295 +1666,eeb56fd150edf654c546106ced064b02 +1667,0e85a14a513bed652bab046a5c777bb5 +1668,55d62aa6e4bff0321cbbc63813564389 +1669,74d0fb33546dd4c04b3b10161ca193fa +1670,603051ffc48b04afd981b3946a66208b +1671,addf8ae63fe3291f19ff945a74b99bee +1672,9adc02658514870d356278dc75aa30de +1673,4595053b1b489605885c4d54ecfa4f78 +1674,c071fc39d3a764f23abac705b4c11f43 +1675,8c224f1df65354b76e46fc57df24ba4f +1676,2772f1617ec0cc6a4217cba0fba6650a +1677,47b4c8dbd06a24c4ee0b0cd884e67428 +1678,3c06f167db21b071eff5cd6683affbd6 +1679,56d2049be898fd9c0eeda31cffec5c71 +1680,167140b070a826a4088124383888a3f3 +1681,d49783be6bac51e0210735c5b73c0ae1 +1682,675e3c8c464da453fad437a15493948d +1683,1643df5e80d54ddf34f3a42ed74b7d4e +1684,0fd0e2e803c38380421ffc12e795155f +1685,eea90f11fbc9aa4b7409ddd854a90aaf +1686,b8fae27247943b005e4027d9d13dd23f +1687,c01b80c812aed48830a41fed0d82430e +1688,1d1e5fe1c4ac22267ecbbdb1ff46ba55 +1689,8daaf3f5bec058aad9882f799731978b +1690,1d1723ea75c7b59ff721c11ac2c470f4 +1691,10214c4efa63d7e6fd8f6508a877f73e +1692,f488c2295a852c2c4a3f93c56b7a72b4 +1693,c5c3a83f1ee23042ff3c9865d1df8ff8 +1694,ce7014f5aa471eba6a5329b933750f58 +1695,b094ee79d589af39e80bce42f36a2688 +1696,8705fbe686fa218b22ef33a5092d441e +1697,5bf474dd3720f64ed4b677d6ec8abfc4 +1698,abeb75139e4e3ff892b3ca6262d7352a +1699,07d4a47b1d9e56b44202e4b4de6ed712 +1700,cbf12a941dcaf378e5b96fc57e0cc2b5 +1701,8cfb689941fb507a69f2650f0f319c0e +1702,0cb702fde019a5b30dadd3e403f772cc +1703,0603a7d5cf2f3994aefe142eb1eeb0e0 +1704,63773efaad186268a3954f48aa2fbae5 +1705,b7869a040aad871a52d548b113a1433b +1706,7908c0d440854b6244a8310672841009 +1707,61ef43440c17fd8fa7113ccf690dfbeb +1708,5b55042ff38b87e3d9eab9bef6bd7200 +1709,cc6d8f49e0f68e3c8088a093df834ee8 +1710,2637838ae37091bf6f73ff646ee30aca +1711,dfeec1e1bc852517bb3b9de6097f7758 +1712,337ca50e3de66c286bfb4b9cfa72c6ed +1713,ce9fcdc63b90b96eb70db1a9acc500e1 +1714,c5e6087b54aa5217a63cd4dc5ead9ae4 +1715,1be6ab1ff736b47cb771b20cfb27c92f +1716,43ce3a02ba60f097c7bed5c2a0d929fa +1717,16c0058c7440c8e6b6081dd692c709a6 +1718,890fc97a68a53b5860ba243a8f7bfa64 +1719,cf794e94673c37299e881e25ee8de50a +1720,3717b759f2019a6148ebbfe0a8af2d49 +1721,07b65a976750b0bec35c298cc1932763 +1722,9c6b709de482e3a03fd272b8e72b0e9b +1723,f91b4e33da9b59c5d8753c3a5b743a44 +1724,20ccddfebb22cb087b45d01eb8a7b61e +1725,2b91515f4db0ebcf9d96635a92fdeb36 +1726,c880f0ab3fc3534b6ac6eebc6ca8f4eb +1727,56447fce31f7906ba0e9ba47de5c0b60 +1728,07291a6464de73ca9eba57e483846b5c +1729,438039a2d3cc15500c56ea92a2fc0bce +1730,983abf4d8d88411720c402ca6d4b208a +1731,3c63e7a586096159f80e6ad1be2d79ca +1732,5139ce1fa1dcf34b4ce3299453f3e40e +1733,8a11654f3c40f119e1df67f37e72a2b8 +1734,c4f6995fe2694c6adcb2268ed0fbabb8 +1735,f7458e732e1fc27bd7396b6a5eb4e4fb +1736,e461d2a4d95e366add9cd90b5a28358b +1737,0cc0ac8d6c10ba4392ecce436478c82a +1738,2706e51dc02090e551cb40995ea9e123 +1739,697891757650ce320375be974e4357b1 +1740,40a03b48e16923cc2c5a13bc3d1159dd +1741,e837d0bdb67a4f80028d7992ead89fff +1742,e31839c3607ab484a670c1a37a721592 +1743,b4b87339c75a9e3caf2a5cb99c9672be +1744,1b018ad5f585d05741d3c571b700c7d8 +1745,1614dda201789914055e37ce59fdf9a4 +1746,e0fbf4206cd03cc6ee5ce46f41d1369e +1747,25af646e2244c8b1a985bd756f0f31a4 +1748,ab65e582d95e5ef53eada1a48fa1c382 +1749,d9c18606d89fc1ce52e29e99daf4c83d +1750,9e7cbca32ea6293b16b03aa306858c2a +1751,f4c1e3abfd8262e0c3427d6f8523db1f +1752,fe9bc1a755e344c0c0d7f73d194798b8 +1753,5f732dd2a7adb1e917eb276a2ae7c577 +1754,678617776aa7a4ef09ecf2d679073aff +1755,2d8ddd4f2872ca5d19b55b8f703bb767 +1756,32241f2164e2a98545205224e53fbfe9 +1757,ba392125f255a81e3b5996a823220a2a +1758,2353cdb003e63b4fa730ae34aefa2062 +1759,0f7f5e93465e0a858f344f4ce4483b4c +1760,a431b225d1fabdfa49bd68deff04eb41 +1761,2a4e0ce6446d70bb7da18964e288d352 +1762,831d989a4b0fa4bb4ff00f8e30ad5bbe +1763,c174536890027aa0e6a4a11b116838b2 +1764,882c5769aa5da62f3d3e1585f71248b6 +1765,43bd3ad486c404b33e3449d861817422 +1766,6b43c8bdab3b00218d5880550040d252 +1767,3f719e8a35ec61656c8d6ae3e6a4183d +1768,a5ab21e5fbcf690b87dea15f1350d70f +1769,1f4fedfa83274db2e39fe85c87f0bdfe +1770,4f2e36be59368711da2cbeb1bfcbe176 +1771,1f60ac8817ae440b10b4bac6043d1d10 +1772,8a3badb78eaf68e3090812226dc209da +1773,261d552d9f0eafba349bd1f17a31c2b6 +1774,347e4bc4716a7326704a2535db23dbb5 +1775,5278323efedc94f92fc8aaffddfdd101 +1776,538b7a26f27699478f88bd65bd5d69f2 +1777,ef94181c7fccbd4e051782a1740411ae +1778,30055e4d50c8defe30efc4f44888bba6 +1779,cd3a6e378af83e31811de9e3a9e71925 +1780,7e7c897672d73a06ab61cbb6271a4f51 +1781,3361c956c7fb00f1b160eb461b13962f +1782,7750df89400cb15b8048fe0f39fa5f5f +1783,74fe8185add4471f99ad33489945b5eb +1784,e2b9c8e73470a7b320b1b44b28f537e6 +1785,fb9392eb2e0b99c7017e04237ff77227 +1786,129165f65273018b2ab2f4483db1ed32 +1787,0b58818d367431e23ade24f8f6cc9372 +1788,4c51aa45d00b61cefe0ae99dd99b963c +1789,f590caca6233649c74b40c67c0b5efa0 +1790,7f5620982f5986e00bc851a625578ba4 +1791,4cc01825d04153983db7a59ffd7f4966 +1792,d5470f07de191ddc76fac8a33f4bf3f7 +1793,d40965e608b12216bb257c27d4ad408e +1794,f29df9b50cf9abb77d45a70bae0ba4ea +1795,8036c0ffa5b4d94d41956c45c4172723 +1796,eb8eb4240e2b2d8e42622a0e195f1f23 +1797,d69042d27c31cf8d61d2cf5c1b91493a +1798,cce5f1965a3a20b076f44bb4f53fb19f +1799,1d313c37faab6c701ead525681a69595 +1800,7e489b573a95b06a4af5ecac0f468eff +1801,bb0853fbc05edc75f8029a54397a4738 +1802,4bf5c97e1f3c698b1c25b92f0bab78f9 +1803,7bc04509f44c763f28b2e1dd1a80fcd3 +1804,31ff4bb5b289e2254f4f57da65274f3e +1805,6d0e8b44bfaa1e41a53ddc14aa3bc8ec +1806,e573ec3d7de5417e3f8fefc1a4bac3d9 +1807,efdd33998e3881ddf505f5cec7e77007 +1808,44b3850d30d58dd0f91e7fc2f418091b +1809,f7083a2a14aff69efd99f363ae4d4628 +1810,e8ddc938158737a9826292f3a413d614 +1811,851fb38a851789533002da3892fd2109 +1812,885e1ca486b9ecc0a75e21a4a7c560e9 +1813,ab570d883bd21fbf0c2bc0e109335fd1 +1814,e7f893294c3d3c56c6a0d43f3d1c2404 +1815,0faf05fb51fc0369ac1371c15836bb3a +1816,98daacde3a0585191af53010c9224db9 +1817,e9ee221c2fe0754e8f00d2c16f4bc5a1 +1818,060e047091400cd5ef38971f04a98268 +1819,7ce1d386463c03c9223d791d4df55d7d +1820,03a2cf64e14b6e660d2bd4472ae9c688 +1821,c52dc765d6d896e7440d9692993df7a4 +1822,b5d2d55b74da9efdd773eb4d1fe8cede +1823,cccb9a579ca7ecc3c6ad4e08af5e638b +1824,609757c2345c9f3274bdd13ed3f8b978 +1825,9b91f71abe90ff9029d60d3d44caca88 +1826,34aabe2ffccf47597641790582ffb2be +1827,ad5536cf6bdc1b03361c47112d8396d9 +1828,8c2121d9d6e46c8f98aa790be1d824fb +1829,cb069a9b584b7c296c8b66c4fa039718 +1830,99bb01b9a04008f3cb8ffd5bac2ec395 +1831,87e2ebbb4dc9c55780642e6f2f2f0eb4 +1832,2e1a20993742a076245a6ae5c5280f3e +1833,ccd86cfb5fa2e2bef9f3c4a5933f67cb +1834,f11508c70fc74a6382187577ba047026 +1835,578f692c5ae20facfa230ec26947adb0 +1836,286b0e6bb8185431089da104e209141d +1837,0c872426f36d3bdcd17153b747d207dc +1838,149a76f3c27c0a17ed74205de5f62847 +1839,277066779e6b8ed563700e1b809d762e +1840,6810120fc79420a0081d0c6bcb84a0d6 +1841,4c6f0d2f8c9361fb3014dfbbfbd20205 +1842,2e09ee95a98ad913f376d8f94a8d7323 +1843,497f6f0e2c7f88dd05506880ac7f34ed +1844,f835d49a9ab150d0afeb9ca3a9b92233 +1845,cce2ae20d2ff9b106fa83be7839e6068 +1846,c0e2d8b132984763d9637365885936c1 +1847,4db37d5d27cb198ee0dcc87b9b76f542 +1848,9e50849ffdbd283ad07b1fc55e7016d8 +1849,3abe98958db681f1a0723ed341f01da9 +1850,70beb98ab2e96856635181feac88f1dc +1851,7474a605cb15e9293e8066a6fd76f6af +1852,8dc6f8d36e4ecdcfdf1292750d010716 +1853,8779a24e30aba6a6738460999ba0493d +1854,000f5993f1975b26b344e336bdd1d0ba +1855,433de007031a4c5c17dc3da7af665e4e +1856,c74d31068df1bd847190f733d9c5ff57 +1857,1d2795c4006b459b863af6144badc24e +1858,b8bc4cd5a9277156a610635b52123336 +1859,e96f587b6eb789f6a3fae2e30d19430d +1860,ca13856ed815a856df5a9f659eb92afe +1861,6e4585ccf4d4efff9a9faea370e5947d +1862,e6d8889ffc686756eeb1b100e27f7fe9 +1863,698c05d491d239636bfa285cb1005d1d +1864,8b42f07d7075899000dad18332112e94 +1865,59246fbb0637ccaced80b63bc08fde9b +1866,96e63892300a7af43452e31b144e79c7 +1867,1c3e8698fd28bbf8f3960cdf6d003011 +1868,7b642a06c5d6b602dbdef53fadf8e4a8 +1869,586190950724502af99f2adcd9e0b6c9 +1870,2fd05b51d68867920da9d125e5dda9fe +1871,1a36df617cbe9a8314f5011aa4fead63 +1872,f84ea92617eaea8aa6413e738ce44852 +1873,a9b776ca3c9785dd697ad2ac23a3c7f2 +1874,76b801f7691f3edd015d0e8edb27d255 +1875,d34d417893b83dd00153980fdec39088 +1876,138098f56abe551dd8d91bc93b40869c +1877,b1c191b946f95b256a865fc802c5e1ad +1878,e22c08c1219dd2988cfe44b17595b669 +1879,005b01dd26debda5680b3f32bfbefe37 +1880,8decb9ea20543db1a8b5f4ba92f2b5cd +1881,fe9d26ee2240f7a8ca2f558c091cd635 +1882,567610133ab0c64bbc6b03d7b8b357f6 +1883,e179bd338c4c78b3706f0115a13f1b81 +1884,5813cd5989a724e706ed830c73f00069 +1885,9ba8fbe0a858a1f87fafb1603a5cd78d +1886,b2ef04500cb9bd130dccc11bdb4201d1 +1887,ba9dbd1e131e97538ed37799afe2a69d +1888,18f25b9b73d63539a1cbd56dcdd2a2eb +1889,5a9ceb542c0ca4d487f29838afb66f6d +1890,1c0a018f3dab174d1c541e7cd5ffed79 +1891,71c901bbf96fbdb4c9e6cfd5ef7ae234 +1892,0f5edb878bc82db0bd6a3e579955fabd +1893,374659b017bf27f9113a0bc5e1182499 +1894,2872c57b63fb9706c2e12ecc5290f1f4 +1895,84399fecdde93a6ee741cbd437589739 +1896,fe63315688beca901c43c4ff5f3e6d58 +1897,9795bef9ebf94ca940a84c21fd868a47 +1898,eeb913d3796947794f0418c2ab7e89a2 +1899,391d44b926b8b3c648aabe934bbd7e55 +1900,af426ed228777cfdbf1cdf9dd19be4c3 +1901,e2f6be6f22eae10f14066f903494264f +1902,9c1307e8f4ddeebc127e73765347e4ff +1903,d86ca4a011f56b5b71c4217565a55a7a +1904,713a5ef96d81791118aeb501c303d29c +1905,67f3a7d396aec5c6b024aa26acba9034 +1906,4d039474d7ac743e1d61476694ced78f +1907,5c6cf81720ed108360642a700f14f3bb +1908,3bf2e711522e1a4d7c64ba52b0ab9f89 +1909,4bd0bc716f8b0bc635683472ca1cf1d5 +1910,92ac44d659e24770231ad841b1ae0655 +1911,fbb3eb037c05baa086393e1eb819c08e +1912,09fe7361969440ddb79e52409f0ecb94 +1913,4357d27d5cd0106b6d8e152dc1fa60e9 +1914,0a8e0bb9d62aeb3fc68911439c800d21 +1915,f0d32e14b06c2afeef9e1ed2ee919dfd +1916,6a22693506017a6da4c5c1ba0be3fe0c +1917,b79d86793a478a464cf1c103e0adb841 +1918,41de1db21d1550bed6d2574f5e7273bb +1919,59f8aad51f6e6c5bfc326d18cbc18c47 +1920,d4ef0587461d472b85d01dbce4ec9f3c +1921,501a0ee6a8b418f4c452e186985b2957 +1922,b8d00fa344b390c9cd778e5397e3851f +1923,c75a79bc13ef18878b52e665e644bf82 +1924,7c3d0b68a0905cf37bccb3fa72537b5b +1925,a568ddb681ca419f2d4359d8549d690d +1926,ad6a77479ddeb2b2bf0b0c584e9ea28f +1927,eb0796c720be3cdf09f6f6f6b8a50727 +1928,c5d785219a915da9aef7c4f00ac118e5 +1929,5b78297fa8cd5037fc2795ecf20b10e9 +1930,e078928f97ac9dd91c390da5ff546489 +1931,7341319a364263a65d8a4de417b5c632 +1932,ca244cf358f1b947d00b3fd7c1df6c41 +1933,b0f37292744e6b9c012f7b51c6e8aa3f +1934,050b87be8dc0eb2f7cb22eceff6a633c +1935,0537c0a03448b681af622e4a8c93e33b +1936,874619f251eec76cf6e3daa1e8bc22fa +1937,4b23586174ffe0b33d2eeb25b2913df1 +1938,70bdd944af3675919c61dbe4a1ee779b +1939,750d49fc715d0a15591960f8713c6bcb +1940,2b26cfc7b47beda2e8050777aa5f502f +1941,4ddeb6ad8ebbfd244293c9acce389df2 +1942,d543c1b9d531a6819c9ee1f982460253 +1943,e11f64eebdfcfc91ae39a07a84ba82f7 +1944,6552ca474824b6ee0c7448898c0b28d6 +1945,b9eeb85cd59926a381d40c7828ed4c42 +1946,a8e72dd6d94ee3613d47c02eccf173f1 +1947,546b61a8456f79ef148ca8467711af8d +1948,53e56883fb64a91f2e797d4765ea175e +1949,07d7d48a3a164944f6b289652837f592 +1950,95364dd09aa58afa8364e18be58f7281 +1951,30a5561ae3c47cf270b477a74d7272f3 +1952,50c6658a91df85b729b489c7ee729e24 +1953,e11385cd1534c0296e724978ab7d1179 +1954,f31fd5ff34fbd9b979691b1bf5136360 +1955,8b2aa5f623ee58ec0c55706e736d6e8e +1956,4fe05d63b01d60b755316073f19711c6 +1957,f117bea46475b2c758fe33dd9419f361 +1958,7655fa7d9dadf7d853c5a7081b547b89 +1959,fc9701ee46d953450206b3da435588d0 +1960,bd4e077d86fc38b32bed1dec4e6e4d10 +1961,d7424e5ec86c9532bad2623f64e518db +1962,69d5db6bf9a5db408faeae526a25bb31 +1963,4fb5c3b7590c676d4225ed584622a0b3 +1964,b9c0e545a805fa4f6ba7dfe296127bde +1965,42703bc915b87dcadd4f9d9a84db0a2b +1966,8699f9320bfbc3d11635de322ef14f44 +1967,bc63118bdc0efb2fd099ba2c3840df71 +1968,6c780d609057736ed0aed30572bc434f +1969,6410857a8d34695f64396dac1ae6cc5b +1970,8bc51d59852d127a77898b3ea5d047bf +1971,cd76dd8b0021ab58ea4536de5683d7fb +1972,0a129fe65313dd96b80f95173c9f2689 +1973,508df99984eec22403cc37bbba2d7aa9 +1974,d081a35062b1ee9b90b83c7de997b81a +1975,fbd6be94a799812e5923b4cd1f26bb98 +1976,7e9bc282d1f23598486666404a49acd3 +1977,364191a60d66bb547d354d1a2f8c86ea +1978,b8538b47a356f8345c821f9f7f9d4f8e +1979,c8c478c6f646b2f2fb65a777e1f6ad73 +1980,c25dd3ffd58451cc2a1bcb144859bf48 +1981,3c8d5b85f55499cf671ee69016b018d8 +1982,243bd9313f819fc0c18f7e1bec7089a5 +1983,aa2b3390cb3b58d34dbebf18a4f40f82 +1984,305e1ab7cf016d012dedc0382e76d46e +1985,3ce5d5c49b19855950cc60f13a83336a +1986,d069aec10cf746cc80cd620ef7a1cb46 +1987,aeb2c0dc67003b6f105ebd021b515bc5 +1988,cd6f522d0bd18eb9fafc83fbf4505983 +1989,8dfe6a124618a47d433ddbfe12e21d38 +1990,9a7ed51775edd73444ccd15f70e55752 +1991,486a72f18d6285da232367ed37b7857d +1992,a4cb1e467425e751bed9579e40a980f1 +1993,3d0dea8ba693ff08cea7080cdbd9ef22 +1994,b6bc73ecfea7e0a35e451cff9b3fe03c +1995,bae49f13a62ae64b5fc6733fa2b9aeda +1996,016ceccda869f300fd4a397292a680dc +1997,0aa5ca860e4e6072d4da96c37652d029 +1998,03de753020afb572c4ec45a5fb6ce670 +1999,2df99be57436a7619d0102cf5199d89d +2000,6f1d6f52ccefd9fa08920ae76c0d388e +2001,3699230a47b712a185d7d685b185c4ae +2002,330b57167e52869967eab4f523ea2253 +2003,ee2d86900412cc55cc869ec7dc35eba9 +2004,ce801b041bdf3aaa66222fecb37cadf8 +2005,d9c322a381c9378724a199b538945004 +2006,804f5346969f3f98188f20c98b98a8d8 +2007,8705494a077e847c947e310ab1dfe809 +2008,68f5afcbb92a96cd9a64ccf8ef7e8cab +2009,de39cc6dfd226f7ed41137c196837339 +2010,95f4664bf51cc8595855869ca17491ae +2011,0455a35ad6968030442b86e5f5cf2334 +2012,3bbdc69bb1bfcb17b9c630aa34bf34df +2013,13241e622c66f2e3fd42af1e5f781886 +2014,a86b3ce1fb8753e134b86752545d42a2 +2015,f51d16a5ce2cbea86e34b39bcca9c3e1 +2016,61a82a64a745d900874f998a75768041 +2017,fe588df9f6412d71c99da02357650a7d +2018,e8172a01cf18455ea9b6ba3a969e354c +2019,7f8cacfbe8f8549b0d74f29dfa369d4b +2020,54684383cc13fd4371b7e5d983d1f854 +2021,bdaacbda60531f982d41fb21747cb4c2 +2022,7d30bae211e7f581b641521c605e3d99 +2023,bad87294f06be29692d00cfcd669e67d +2024,6ab3cc1cf08f4b728c45e438e2b783ec +2025,70645e621b4bf868fead78d3c59d1644 +2026,0de3f972e9f344eab985267309252cad +2027,cdfcb930a452be8ed0734cf67310922f +2028,376260bb56d0b19e91756214883e1db5 +2029,8c785115a56eba4e248fe35f800a0862 +2030,bb9ad6b0f6f2b173a2089498c6765759 +2031,c239cf0dfd15add07ec512712f703702 +2032,1f45eea60cc443319d5b9a562be196a7 +2033,3a5a829cd23d4597b7074a9530e3fb5e +2034,8cd53cd7668730a205286259aa2b9a64 +2035,fc957e94f39ef2c10d3bff0233feaf21 +2036,15ee04ef880625a1eaf1ef7a27078295 +2037,794fc3252087e7039ad679c16018af49 +2038,f54f2fd5e1d57d7f4f789ccfb5122db2 +2039,8c9c9204d3d67ddd4956a9d7bf2c505a +2040,fa85b123c2f95863af906af3a6657f8a +2041,2a8b384e7c98be304e43b173a5fa335f +2042,1915dbd3fef051f5d7c4b97c8a475f91 +2043,1d8174fce2d00557396350b5269477de +2044,3139eaf748a0a667814e59526bfe8dbd +2045,bd1ae7929521263e68536cb8beae1638 +2046,ecde28509e52ac1b3d2d929119c44f75 +2047,f5b03104235907133706db0e9d5744ea +2048,be7806ac6db14766b03f1fd34adcd3d0 +2049,da70a3c6cdd4ec59d62db9d0814d0a94 +2050,b6c234dd9986f8b08925ceff77ea4c24 +2051,7707818056e1c37a086e531d699bf846 +2052,98a24711f64650408fee2190ba6e3e81 +2053,7ccfed7a3d7aa5e2f79912721d285e7f +2054,db9f95e9e669667d5d05f196afe78096 +2055,c79100bb423f839ef2c916027df9b4fe +2056,dee37c96a3a39262e546e0ee62bca97d +2057,06e6f4c4125e28131964592bdd4ef0f8 +2058,729889300609eba1276a8de914355999 +2059,165ecdee7513944879da56c217023b6c +2060,358579ac8ad9570ea7bf025c6f1b49dc +2061,a6a5a0f014ec89cd9675c9b04b06e164 +2062,053cf7c40af568bb3a240f0f57b36aee +2063,388e0466658019e5903c7fac43418793 +2064,cddca2f5ad96a6326193d48c94e96522 +2065,5dabc693224740db4b63d06bb551dc6b +2066,0dadf32c26c74ab2769c045a9bf4fb27 +2067,300bb5d3602bbb9415e843f76f63e24e +2068,bad57bc3a949060958a4e0ebb1cdbaf8 +2069,79bab4286f0768b65db99f9dbedd2dd7 +2070,072d6b7de89f448791533932e5bce03c +2071,367a4f9e0c40af8670b64417a4226087 +2072,83572139f8e333b97f08a23248fe4c91 +2073,7ac1de2f60cd5b37023cf28abb0815be +2074,142981722f57dd21392c7809001cee6b +2075,0af45d644703bee9e998e780b2d26e62 +2076,4d0845d4ee628bd920ead26d617b34db +2077,330c31ed83a1f985c3398764782e826b +2078,3e0f94519ab1cb2dc650b642a1a8086b +2079,c9b8d21ef4744cb62cb78300ee6dd58a +2080,47deb37d6559ee46b5d89ec6f342f9e0 +2081,b8ea37726167316c77ae148e43714250 +2082,4d12d467f06203263c8b28ee1ea5569b +2083,a04dba1c87946706dadb3c662f01596c +2084,7abb982672d8b5db7dda443610a27c80 +2085,48610cf35f92825470c0f8a78c689d91 +2086,1cac550f1ea57501fb1c72246a3e2129 +2087,5735145ed411201fbdf8ea6217e494e8 +2088,fa9c1b9f2caefd38deac45c0ed7baa99 +2089,18f01da87d6118fd9f629c60a0adbec3 +2090,5394d2fe064e726732b439932b18a7da +2091,0ff946a36cc956068fb5972cc1aced2b +2092,61694bfe75b498bc6b8037f22414c9a0 +2093,38784aeaea36640491069bc025b47b77 +2094,1a578b594a34a42097afffa103c50de6 +2095,ab840f30183635f23edcc1079f448910 +2096,415c969a856d56c387b958ced25b9871 +2097,7328c1ede50f1397fc8267d5018a92c9 +2098,b81bcfb175d3820d7a09901c97be77f6 +2099,58fda4bbff02c4ea6bc7434164b4234b +2100,6a59b7118895597b4a83167e5bf5c4c6 +2101,ecebdd9dcdb1fa14de8167a9cdce97ed +2102,b0f759567c2a2b117876521d92eed821 +2103,7b885ffeb0332d6daf41bdfae22e6948 +2104,ffeb5aeefa58cade7239de110b6c8726 +2105,034a0ce1ae0bc635b24c484536744558 +2106,a9fa004ea45723a1ca88446a7980f094 +2107,1d6bdaed769e803c3f97b6e488e6635f +2108,06c7af0542b089c521065fef60829af6 +2109,91e59570b2b3b7a3d50f01009409cabf +2110,278e8712ebe02acd6d09b474d6cef8a8 +2111,edf2df57d209b02065a51822dd82744d +2112,b77920ebaf258b175d5cd5f37743f034 +2113,4620fe9024b67053cef09108b400d21d +2114,5688aff2fe7ce8c891512f34f8239ada +2115,cb5abd7da8260700efaf27d123e8a81b +2116,8f142cdc6b565bda6cc870371623e495 +2117,3bb6884232152aece75f3220f66abfd9 +2118,d1b9c055bc6fcf5a9b5ffb13e880ce55 +2119,0be30d2df6f0d90ffcfeb1c3f3e3eee6 +2120,d343cf11e5fa1b6bba452a7d7a58559f +2121,40531a2364d97a3a2ea9af9566c50595 +2122,ebb946e4cdf9e13d16f3f2912cba9492 +2123,c5587b36f821e595bbdc89807d75dd99 +2124,75618c77e861f9505902e9305af4f05b +2125,8d6db921e047f20e4c0baba52d33d73a +2126,52a6da0f15166763c96e7b2101e0a5b3 +2127,12f4411b24db69a179f8a9be31f81c32 +2128,a00c401a9f1c5d48b6e3b8fc82f6d510 +2129,d5a7b21d0773c693ccf917db55b7010d +2130,d07b8179a0625073b969da0940410128 +2131,e35a990261b98716b6583fbdb52fa9e2 +2132,bae24cd5bdae3935e5da8112c7627a1d +2133,cc959c4fb98b72305720053c5d6eac24 +2134,c5e70bde18d04845e2b883144432b3b7 +2135,4193648168a6f6d20d8ba2f2b6780f14 +2136,f789b8a82880310de0abb74e8bcdda26 +2137,8a315e3bff61d63bdbf39cdf83c25881 +2138,f0e4ff58fe6651619aaa2d06a792d5a5 +2139,07aa4f6c39f04f98c2e6326d4ba977cc +2140,786b94f7308786d1ef1de8d4da602c95 +2141,5850fab5661b393d269e468fbaf75029 +2142,d5a70294b0833a5cab33a8a851ca41cd +2143,0af2061160f0211bd93a924c88678b20 +2144,c9ba75cf228e7aea71d21841c6726879 +2145,e5dc0e89ca1d41b4f5022e933396d366 +2146,f1b3b823822d6244d1e747d3f937e774 +2147,bfa0e2c9c45fdb88bfd54533c40a9ec0 +2148,9bcedd5c46c001d9f772ed13ee619674 +2149,6323f87e3d21a52dd8102dd268efdd6c +2150,293551288fae2a4ebe587665c7caec0b +2151,81167c9fada7dce431aa9eaf01917f9a +2152,6c0ff1f566b45b9cbf1413e172c9032b +2153,4ecc32e9b9d14779e12c29cda40098a9 +2154,107fabe9aa740b9c6454c49f31f1a084 +2155,2d66ff4086c31a089367eac4605a5404 +2156,5bd6e0e93cbdd00e5aca5ca0a727bc14 +2157,044b744c698db781338c20143d4cfa01 +2158,2a1a072d312add3fc6d9a14094a96ce7 +2159,2dc217628cb5ecadbaac995a8f4751a3 +2160,00b08d0b8a73e800c7b60e58bf5b7f04 +2161,ae261212e7127ab84cf709c85f1e4735 +2162,3c48fc7a5556eb6637eab6726fd50074 +2163,4c67986f7d29fff68e4fb1274c64560e +2164,8c075ad990a52eb6613910d71bce053f +2165,6cf218e5dea217d8cea8bb5c95324c38 +2166,cd846ca8435174fba3183db08d27558c +2167,cabe5ef1ad7ae7bfee94d978cf5a4697 +2168,a0dd1225eb74dd4babe8afb069db2330 +2169,446f17dc969e58771836132cd871e925 +2170,daf85e063e472d211328487a2e175a1e +2171,2a476871cd66ffe8989b799e2901fbd0 +2172,bea3b561c09d92f4716e7c30a2b869d3 +2173,65f9fa9a45570598164104a7ea6b5c7b +2174,cdd8c00af366787ebf4e529feccf0914 +2175,935dbd392d07e931500a4a4dc638f145 +2176,f26e19f3998724e4cb8499e8065f269d +2177,6d931ac3e7f6bb066a4e85cedfad8d17 +2178,bd9cbecdac60e7ac872d2831ea35904f +2179,4c411c9f4881dc56032ab85ffa936014 +2180,a7041588536f75ba51c41c4ea2f25337 +2181,76e1249d328c6e3b434b1f12f8ede286 +2182,4341a0a72b20341ee4ffafae76e415a9 +2183,187376a323804471e5b40642d14c20fa +2184,3a736882a60e6f217bf7d0094405555f +2185,55d50df425e5dbd42e3a26c1a998910b +2186,346414656e68354e3aa22267e6730277 +2187,b44c0fd7bc4d2788f0e79f2a88d311d9 +2188,570c0b1b80667492f66f1da70458bf1d +2189,2e628b36cd940ce1e424bdbc5ee8f410 +2190,201fac0a4972d2c14e7caf7bdc00e8a7 +2191,a931c8cbec064f8dfb625f7047c0ae4b +2192,9efbd150189e5054719d6940dc993710 +2193,75a8cb00f79dea1bac06bea142e45ff1 +2194,ec7906fd6dfd9ba4ce0b97ad11ec0ccf +2195,eed8db2cd6a061ada8152a881c04244e +2196,29161e822896e99cc39b7275d9faa25c +2197,6a607c9079b8d3023990b48c4dc6e431 +2198,3f78bdaf0a9698e7615894e99a6472de +2199,dece80985056bb09a84d06fe2b3a6616 +2200,521d15dd79f9386e8e6ad8b2a06cd43d +2201,63ee45dd928d26c7642b42b1f9cbc0aa +2202,45c4bbd7405137f2945b23bb391a0fe7 +2203,284059888c10fe0c27118e257bc98197 +2204,254d62115956ee2969fe8319b7aa0cb2 +2205,c703fe3e25efb884611b699a2aa72214 +2206,e5ed94fd660b2d46e7f734582b10a5bf +2207,a9ddfa0f8adfbe762275dda228db413a +2208,91d899b16602c6e0be907db112b987ba +2209,e94879007ba7b9e1afac234e41bb4fbd +2210,a15244afbf8a2cc9ad1b6d25170705ea +2211,9f9dc01edb40becc95642183d253d2ef +2212,18dda66d2dbc9f69b35b66f86928303e +2213,8ce5a94a5dbeda36d4eca07461a15ac2 +2214,c649e3ced95b03f024142f9b084e49c2 +2215,7fcec66fd66b6986f75b6ff4480e9c60 +2216,c121375a504984e5044f8c7ab058ac53 +2217,2f214675bae0a50c93965a7ab5047555 +2218,f82949504b75cbf59189c13741369941 +2219,a25959d5230e3561617c485121ec6a32 +2220,0a08fb33ca79481378a72c6e3a061ed7 +2221,0832ba5a89c9430d2c1b488eab78fe88 +2222,07df896bd1b8acc156ac83f21bef18f5 +2223,bc5e798cd673faf4cc830a0328e8b254 +2224,ad50dcfc47830cca2af48c58c410c01a +2225,d4ef3f6ee0e3026b81d63e8f2bbb33f2 +2226,3a3fe55d647607fe18dd18b00db0a66c +2227,2c0706ad7a6b114d429f4eb360706e5b +2228,0bf70a161e7ab5d927b354134953e80c +2229,f6427b1b57051c4f418440a3d85a0331 +2230,2e9b701eacec28b51b2868752e47bfe6 +2231,063488051120226700cdbc5cac96b75e +2232,a8a5cf6ef91a3cf61a8813f12f950beb +2233,594e507894dac7eed7668430a956d9c5 +2234,2b785d33aa154c30bf2591c75441e409 +2235,95e7a8689b22117ee70d790c52fe0723 +2236,07875767dff6ae57251bd20421ce8441 +2237,fce6b141271de536adf7ac4329835c7f +2238,23353517927d246223ca420d2ec5693f +2239,8e82259e261f15c7ef8fba68a1cba342 +2240,e00e472ea2bdb529178f043c6e8fb9bf +2241,9facf3759fe592f5c0d63d0c20915e35 +2242,ad0a40d381e122df57191f43dc1270f2 +2243,0727521526d6f2a3bfe6096713ea0c4e +2244,ffab4ba5efcafb7b39cb249f1c2afddd +2245,373a52c8b41aac2dcf1a1805483b6340 +2246,fed52ba3d89f0d00464f509f49e60072 +2247,2b9a40e9b3f583278140e74be6a18d26 +2248,56a4a5ac3392beda27621868e4c4b571 +2249,a4005b0a33b4c93a01df7b568948f062 +2250,6f509f1f6c5071d7a0c4ee88f6319ff4 +2251,947879a98a24f5f7c86f3d9e269b6512 +2252,7a31136512c7c2caa705cf1722e70b4e +2253,bfcc4c7c51f9b6e8cd8138970d45d617 +2254,a92ad8f5fde82aa662baeb706a8262fa +2255,9219952052c699bfeeeecb44676420a6 +2256,14f34306a2e18311922bf177137d902d +2257,33108ffed46d64135a7ea310ce0705cf +2258,69f5f96f69205a73114addbb43159689 +2259,a924cb709a5ac4684aaffad05a856257 +2260,ef900f3b40a01e2845b9c1e9659f1d86 +2261,277e6dda10290641c5640c444b01938d +2262,deb2f720faae03f529149f34b6322721 +2263,dcca4f76141116a84c031551a000b159 +2264,e9fe626428105273f6ac790c1ed639fb +2265,39b3782a8f5bad3d6582e60d377fec87 +2266,996891757882833922e110b030f65698 +2267,10a9d58ed1a6026b49611594b07d27b9 +2268,62ad15a43f98c0033fc99a8c28a34b19 +2269,22340dcfac30c6904aad3b7e5f2a8597 +2270,19f4fc450502fd9e219f31b06738adc6 +2271,fef689eca5fe5672ebfaebe2e0ddac05 +2272,cec555cb0f2fecb77128d279d359e6e9 +2273,7423d93c763262ee8e3e352dc237dbc2 +2274,4823103aa677cb9b869c877bed309e1b +2275,2f89e3cd9ffb75ba6ea63f8f1baebf86 +2276,62ea877aad2ae656e993e6aa231db868 +2277,ae42c85d0342505201182c154337efa5 +2278,d1dbad7b2c21fd52c8b9a7574be7a11b +2279,3894ade050ea4b405198b84dc810194d +2280,00bfc4a5fa26ec5cfb8f18a6ca326c46 +2281,272f9cfacfb1803ade4285b1e28d940f +2282,182e1c1af031dd9cec2a005d9d59cc61 +2283,2b562e3a0391e5a04211b353c53d83a6 +2284,e93134c82f647d8bf72966597c5729b4 +2285,d758fad1d9edf951ae5c7d4cd5f3b446 +2286,5ec920c033874cbab5a0279debe88aa3 +2287,8a5b06fd1c1916398e9e581e47638b0c +2288,00dd28f73cca9e2fdc8c3e71adef2fb7 +2289,fb40a3075846a7395fab3143a429157b +2290,9921e37b5c58b59662112081e5aa2319 +2291,b2693204204596bc4ad440d46d83eb4c +2292,ae257df41863a68f7604bc41c438c0d8 +2293,8527a61f67c80787899d183b8bb5b585 +2294,c04cf14e97babf62bf833e34aa653be2 +2295,6a1054cb55ed417bf80c0f4a3f5a83ff +2296,78222225f2e47540467e042b566673f4 +2297,a40cbb326f82c53bed3285953bf8a7a8 +2298,33401c6c2cbff56b63f51a1cb92e9990 +2299,8492d4357676e82a86df230be08d20bf +2300,964b4fd95b04eccaab8adaf1a41cd36f +2301,33878b733ce29b0c3afee56f306e1f22 +2302,2ac98f1eddf900379e6513a9f9b11a7f +2303,a37c98d44dc9aef296d93e2d61413015 +2304,fdbd6e7233b1c55380ec7f9d20acda32 +2305,92ad0497ac28669b0b651e5584ec1eb4 +2306,8a66d3969f79e89a7459cbb40af28681 +2307,c5082c9a1a2474d3ccc0295a25c804eb +2308,d7e175062cad1585ee893cbd7a47a539 +2309,336fab813a0893f5eeb4a7d1287636bf +2310,699dfa3f471559981965d5a9ebca0cc4 +2311,a7f53046546433948b04cf568be4ffac +2312,2f56c896ee402f1ccc44f33231ba377c +2313,99d51280b6302f576acc3c932cde3c6f +2314,aba3d3640a109681ba401b7b026b06a5 +2315,f0b46a4329f816101cc282fc0f4486b2 +2316,f17a4121f7896fba44162ab13df7fe97 +2317,0255b2de261e62483de7aa788164e9b2 +2318,76c06d4cc6eb1d48f2ed19c498dd0a66 +2319,9e59bf6453764eeddf4c850a6ca23407 +2320,f1a4da681807cce77d95af70a00bf2a8 +2321,6686fb48b42a38c0ce3fe4072c73c2b2 +2322,93ff99787c44920f5c2f35ac7ba9e416 +2323,8e51ce0103fb0abbff09aa85510099ca +2324,3cfeb8b247f4bfd788342933f8af62f2 +2325,70c321a075ef3f3ad0b06e85d200a29e +2326,4d984bfc050641314c52b820cb225f9d +2327,0c13c4d7f33894ea7022caee09c3ec15 +2328,b8261c5241bb3ffc969a353a756f8a1e +2329,14a614c31d100dbab57b9dd14093a29a +2330,f8074bd0bc60af8eb9ed9bc49e56303b +2331,f873f437ef0e46847e51e4e79cbdb9cf +2332,011cde94bec647c167b3010fe93d63b6 +2333,642b43779d771f295276487613643ffb +2334,0e3143130f840a48d609f779e04108bf +2335,a96cc99934d420de68735168b051bd5b +2336,1f7a1ecb7939fbcd0e272abb8eb03f5c +2337,43f45b45a83f0b52c4095cef362fa601 +2338,fb7b7eded22ca6c478541d0739cc1f9c +2339,978eb4a24fe02f3d21819c7e02cf65a1 +2340,2705cf4c42bce2807912a8e02575abb1 +2341,f37d33314629ab7145e69a721ea79410 +2342,e336cbca7e2ff289717ed2e9711e2bc2 +2343,fbf958896a67e929f1620322f1ca03fd +2344,d1a9058d10c6a153fad231eb93576461 +2345,5fd492aa0d10af00da6497bfcb709abe +2346,e3b2f70057be4abf929e4b59bb6ecdb2 +2347,379f961fd8646681df6c35c720388f1a +2348,3e310539cfcf697dfb068db36561c0b6 +2349,e0c5760eec5d6853205d17be8f5f821a +2350,2dd33252085573301eaf7dfa12417f0e +2351,3db482febd156a851a32f94d45f99277 +2352,4cfd9cf79f263fa9986af74f3c02b8af +2353,0b62cc367fb7808e3b5ae97902eafe4a +2354,51aed07bce1615cac8db2512bafe38e3 +2355,9593a312dd0130c851f51a95bfa7e08b +2356,6f423fbfd822e2f4e9d7ead4a386fdab +2357,80fb5797bf5f000c8ede1af691c57d26 +2358,ad1da6a76aea50154bbefc42849f0a53 +2359,48426a0c2f353838d6e462a1e4aa5483 +2360,ac2e72476b1b6df26652ad5e6ab1db87 +2361,b81c8b7964bd0951a8c7f2c812ff60db +2362,283e01f8bf0acf56cf33f07e718ca881 +2363,71ca4ebc2cad18579d81bfff7a46f7ad +2364,cac50e21f77a606365577576d70f408c +2365,a0e208590ae8eadef957cacfbaad10f9 +2366,9a667ab4107859aa1053657f8d7d22c4 +2367,3a042c74fbc4fc8a8de6c264ab4d450c +2368,e370517f3880d43f8f521ef6602640a7 +2369,b68495f98e7a9cee2d9d38b6c577a3f8 +2370,c04840078c306f8354fbac504bf494c0 +2371,c8f0fbb96d78645ea885e9be92d8aa59 +2372,04079b6f26128585deafa41cf35a4187 +2373,4883ad23aba42ff461336d566c4affdb +2374,124b8a15f375c9767878c09f13136c63 +2375,7466ccba969be59ea81fd10646381c9c +2376,17faad5cddb512339a7f7bff6ae64b06 +2377,42151aff8594130a889dac764f31c532 +2378,8c2fce9b0ce1ab900b7fdda0628f3b75 +2379,34e449a070ad370c84f589ad72a1297c +2380,c1e3aee2eeb02f411f7c5a2fb37ad9a5 +2381,71bfdc0b0c080e5f999db7567f48cdd7 +2382,2cf9e8bc8d1e79524d98623ca3f68a71 +2383,d29f14478f3d710d9918856c161d792f +2384,308e1145ad2c57ed4957abffa10a3834 +2385,fd1d2b4b21d3d4fafc84c82c89c6f54d +2386,558496e5aa460a8fe377141378d129d7 +2387,398c250d53d25b5f434a43f1e235d7ff +2388,ac4164e37824acd6b09e485104e79263 +2389,f12df15f5d4bb592450da690aae07b0e +2390,86414adce70dd03c4f849d2df952282a +2391,e22ec61868c13c66e4e2e31a9c6437fb +2392,c25782eacece5d6c7730c43dd7ea47b8 +2393,91646679f7ed20767a2ae2e47abf998c +2394,33b708fc90ac2625fc6156f3f6011e91 +2395,b63596dac0b77d010ffad6b6f8c5a84f +2396,3df22d899b717b754b66487617a5ef36 +2397,b11faad4086070cf02a19313352992ca +2398,bbe3a00172a14236b7e45a47e796301d +2399,318bf0c947cdcbbdb3e25dbd51adaf0d +2400,bc841c4a8e2a84a12b0f2597a3a6f723 +2401,922ea21469899913a94e47053a3e23d5 +2402,edc6a24b8bc1abdaecbac1bf58bb6db5 +2403,d3817ce84ad5afd35ac34f8a7873ec79 +2404,c0c6d1fc1176d908d95d417285a934b0 +2405,0b4d2a654a1833f8e719dea19773c1ab +2406,b9bb075077498866f22a36832c8687e8 +2407,1bcf39b30396826ae3c9f24b1d34a18f +2408,48793cee881be6801ff418000bdeeb4b +2409,4cea700450539c58e8502aeecb05ab92 +2410,9563d0edd3f1346f99f3868e7d4bf339 +2411,ff86d5cc8bb6e458b9503fd0d6433465 +2412,ece37c22dee07dc38bf28fb20b5743be +2413,cd3e51760caab06e293ea42a02970b55 +2414,8b1ef1db5a4147eb87ebc0f49fea2f97 +2415,9fc8e90a917de915a5d3c02e548144d2 +2416,5f98507cae1d41b8ad60b5128f9b8cc0 +2417,bb7315f0856477fc430f52a356fa80ba +2418,33a5c7f04e59c9db1b65e009db01f097 +2419,ff1141711e99626ff34f0dcf6f3a5571 +2420,e61ddfea3201b6a273fa27f21d274d4c +2421,6facad2340c2fe83d42dcb0cbd93e354 +2422,1aa3252b9f7385980cf20cb07e47cb57 +2423,cf01c5b14796829abe4f9e815ad50076 +2424,830c8993b8b117d81a8bc927009faca9 +2425,0b73c8d44661030aedaf50fcf4c893ea +2426,348a6c8544e0bf73a3fd14fe5a0e4b19 +2427,a46067db4b240819005839da79caf0a5 +2428,15b4ddd2429531a991c571442ca6bdca +2429,59f184f6fb4349eb475582f1664417db +2430,69dba31ef3891791211224cc68fc53f1 +2431,e6e18017f4594901fdde438a2e7ccce4 +2432,08828887e6c20c5996efa684a5ec0289 +2433,7ab5c647ed62036b633e16e8589c8e79 +2434,747e4034d7a292f662cf89081d4fb548 +2435,be301d01e1647550c4e2e5ffe6a0cdea +2436,f8daeab2f9fa77795306bdc0fd269d12 +2437,b7311a4afbbc7721cd4d0699f7b43d22 +2438,61376cd3fb36ab681454cd2528d4bb4a +2439,c41e83ac6f5204ab76c507be7f588b43 +2440,0d0972b0c19117e81ab81656750eed60 +2441,d587ba5e2734a549b26ec36ca96a6510 +2442,f9caa22ce2347b6ad0625d4061e6598b +2443,f3abf0227c8292c22d1e961ec65b7abc +2444,1cdcb65fd69800b3a1c2af78d1538d86 +2445,0face6720c8e4c9f2ae27b69a03cb3f2 +2446,f4bacf7c48918dffe7a812d623c5ba3e +2447,30ae6986b4463806a69492c74114f254 +2448,900024d9125e6464de8eb3f31cec3202 +2449,acc79183ac6093c336f6fb71f74f182f +2450,e7cf84b95d979e26c64963b7c733b15e +2451,1588ad2ebf8a8deaa1b20177975d57f2 +2452,bd030714d12534c6aa777511824636cb +2453,34b829e66c417317f49df16648613204 +2454,1e69fa38f5658b3004ad3af6bd21dd5f +2455,7da325a319390d252e3032ecd14aff75 +2456,bf51a73ebdb6fde55acf8e6371a0278d +2457,5ef0e53a72b74637fdb472c11b28c309 +2458,d365bf8f6e2e56f30475cb6f42d6dfe5 +2459,611390baf5e433b2eb6f24ff6d623dd6 +2460,d740b14b38b90bbec59aebd2a2a742d8 +2461,d469421e9f50c9f43947b27eafcf0a37 +2462,83d1682b2e681ce8aa3a2e701db013a7 +2463,6a55a205f4a0c18f25687593cf2baa3e +2464,8c0f5a67c7f03dca67354c75cc9a6b86 +2465,e04215a059c94d210a7f3465fa83643c +2466,4ca5cdd9715a0421a8facabedd1f809b +2467,72f2cb8911672b7a322b72600fbb18ca +2468,b2931f79b47448493a0cdfd762314bc4 +2469,0e6c83b4f95d1d441cbf34c2279f201b +2470,f7e13c03eeff9ddc2312e82962c83160 +2471,e7cd6c6ca4b550238cdc0b7d52bfee69 +2472,4e88f1e9cc9f79c5454d0d7908365c51 +2473,62f4dd770f2db6985ffef1cfc4b7ae5b +2474,85644fcaf33b788d96791a641905104f +2475,80aa53ff731aec29de26b175768ac641 +2476,d7a8183bd89dc421a2de7f5d1be7f10f +2477,8c070777c24457ada102a9c1603409fc +2478,1f3078a366c8e0f35a8c038b46c8fb9e +2479,63774f9a13794426a91a3d37585ae58e +2480,96f67aa49f89601d7630ffefe43a2794 +2481,edad8edd9b9c59e6d64a0cfbb054c9a1 +2482,3bca79ca5c2cf2e795574abeae355bce +2483,ee5e1e56d70e6929f4406e9e411935f1 +2484,f4abc9316760dc304093074d393bbdf1 +2485,5cef7b06b0418d83c7969952f2a31788 +2486,91ee17a133c1371a694dd2eb7f67811e +2487,7d69be2f41a5a6dda79d6dd65b3b5861 +2488,78c7c5a8beee7f52b5bbb94de715deb7 +2489,3994886657c598372c7820cd8e150214 +2490,103ec23cd96d53508e4cd8ad070b2cb9 +2491,4c74a801c4c3f971f5b227e94558fdbd +2492,b99fea6430e813dd627cf0b7f7c10083 +2493,d31b80fa94a8c811b5984dab6d662d4f +2494,d43e14eed1b7eb82a2c1eb6c5fbc6ce6 +2495,5b841aa3b14d1937f872638317f87323 +2496,eded0b6ffdcc1d5a8e080bab9def2597 +2497,f0b217b4343469a911fc89dc7b698e8d +2498,f65d549b6f3b56e4682661b920dab34d +2499,9995d0dbfc00b7a7caaaac39585c3a78 +2500,6aad46bdf5fc10b40504c004faa099da +2501,b82649bd42c4163662651abdb0eecfa2 +2502,cee6a4b8f1eb1eaa47cba5a8c66cf2a0 +2503,89c436626f055972d4642b26f733b065 +2504,c4476bf228d83d2df0ed6a5961aa86fb +2505,179bb55a5e8a6b84091cb945e3bb570a +2506,63a0f66b61ddb18a05e5d873f7f7e8b9 +2507,05209152e36b82140ac08ef70770f602 +2508,e5f134e3e457486d5fc8d0b0513ad3ad +2509,1a655a3e816c01bc692f3f14c4f31ea9 +2510,843bce1c59e2eceb3d48f8b3d0ed5ad3 +2511,2f4cae7ffefe68e304053e8348762dac +2512,b06686d1135a95a92a4cc0ff60eadb3e +2513,d915ffb3ecfe8763fa33908f6560cdb0 +2514,a4712b1109beb4a1a68a01ad00c7d254 +2515,98d855d6d60985e0a125198d1ab22ea8 +2516,35694d6580a9044db602f79001c3b2f5 +2517,37f5f7be10d1bcc182af624b0cee6e69 +2518,ce12c6d18817a1e2b07a075545f72dce +2519,7ee1fa3228f7b5621313f79947caa391 +2520,3647cdfd12b32ec7dab45ca7c06ff362 +2521,fa229c8ae76f287286c8d07424711013 +2522,4f6574c99797453a9ba1351c7dc25fab +2523,8f9298978485a42e8b879d56c2041a4e +2524,d42d8e5e5167bf1dc6821ee6385b0346 +2525,aa84bb17adbb3909abe64006e5707e89 +2526,8a2efa3439a943b0a06220e5ba9da532 +2527,289493df86113a5f23cea0ce87b71ec0 +2528,9a033cf3cf1f1311a027b6cdace68f0b +2529,18c97fbb08f6593dbb98d67c5a456491 +2530,6470e6bfce7df86568502748cb96d770 +2531,9080856fefcf2b8e13105f31fc4baac5 +2532,c8c47f0a6de07a8810c13951b21d75f1 +2533,359ed3535b9555c6bbaec8f43954c167 +2534,6e4249a522caf1c35f4e9e58956e9f10 +2535,6126343dac2906b243a2541be327844e +2536,585d5970bd236936b140b83279f4914c +2537,0e32a33c8f624494915a2969950e12c6 +2538,9d1c33c22c2f066791274bb326739ba7 +2539,650d5f4c4cb16837a0e99dc905b99534 +2540,a4c03bfc052d85d3ee442d877c4f9bdb +2541,12a3e3d74f4d460f57d7ffbdbd90077c +2542,7f741ef2b51b2e2142cd55f91d087b1f +2543,1455a5a5e23951dabd601d8c6a1b0cfb +2544,44df9643023f3df6db6097c859f5e39e +2545,ad24f4fd95dae93e0815719ec111d271 +2546,4f62b4c7d0f53e300df62b08b5052afd +2547,fc1e29ab0507956f8811c86b74ef8154 +2548,b9d27d2668b8e85d69f4adf98e5e2dec +2549,de99a4e965b1c63d08bb8b1cfc26081c +2550,5109c462fb82280e5e0215555a34bd3a +2551,9fcbe34173e8d2c18dbf09788ce6fe91 +2552,24020b94c75543bd848b1d9d7a639fd3 +2553,ce2bd8e4f1bb95ca53693a3b7bf28e0d +2554,eefef691bacd6987cf4e9acdc4a81573 +2555,76c3582b1f3fc061961009bbe9134585 +2556,8186730831a6442f57f42d0f4e51606f +2557,052e505942f205bf44bd71905fb0746b +2558,b1e616a9c596969c732c86e42ceb7085 +2559,3597bd17c1f6588a44826784ba6cb5a5 +2560,72bf4573c97e9baa606c4b3ed40099a2 +2561,a1d3ceb7503e2866d9c27ac0990808b2 +2562,d876904077abd53f065e6ab319ab48b5 +2563,3c0395944caf890282db1989796ee97e +2564,b39714b5d33531931bbd3108e8280e74 +2565,84bf50a1313767d0e4150ce256db4957 +2566,3510876651c116d95de367b5d0a34751 +2567,9b3426248ec199681cf8c15cafd5a832 +2568,c60fd18fa56c230868ad1f7e02987bf7 +2569,31d43977c23b5109f2c7b81acf411e5a +2570,1ca162d3fb6e2b79b685e0610d381cbf +2571,1f127ff5e8803e507c9dad7d5a980fd2 +2572,f4bf065350bb9b16809b2769a3d745ff +2573,00f64254df1a04d6f4ae501e213e0e96 +2574,722217a78f75d34e8badb4a10c21676b +2575,104ed34c83ae98b3fdd9775e08fc0871 +2576,16c1d862dd654fe5fa1272141a853754 +2577,1d65b60b7c864748fce518057e601949 +2578,0661efb5a72506e8b42a8f843f10deb2 +2579,b463617940a22285b4373cf3bc77bd30 +2580,e62b1c494318cda928eb981c8130daa0 +2581,2fd60508820bfc838d7e5468e6355294 +2582,70f3eb51a562b71424e73dcc13baa735 +2583,5ae4957fba8894c468bf632fb10b62f3 +2584,87fe26dfad047d6afc05ce548f3edf89 +2585,7d7a8cb681b462decf41acc3eb2f8bce +2586,67f92be1daf14fc0cd989f833b4f7c8c +2587,36167f41387a407f7f319ce58b077ec8 +2588,d09f335013852f7ef1ac3c2e05a1e75a +2589,fccfe90a520d63e4f809d1c431408855 +2590,1abe4c34b456b6fc604bfc40b0b0fd28 +2591,2c0b3724f3b976c9202d9cc3768fa52c +2592,5f1156b009839638d817e5a3da592b08 +2593,8825c9fdb25759c024799fcf5b591a92 +2594,7c06b14c1491ea443dafabae47220263 +2595,0848a03be0b2900bf9028dcf771cc6c3 +2596,4e6a4024785f5fd1686aebeb1c090ada +2597,8de16a1e5f87de3d4b89bc951b0022bc +2598,2589ff7eca10a8b4c7ecef96cd0422e1 +2599,4fde1fbd9d13a3e2fef56dfa46eb61a6 +2600,7edd9957c45671e050ee8e6b93ebf08e +2601,4f3f172ccc92b3972fb893a5447bf996 +2602,80e624cf0246b5cf04bb4f2bf5a3233a +2603,18ba4c620a41200c40d2fb6c656f1a10 +2604,2e21d169b316f8b13c9db225a0c9dcbd +2605,fd4376d77207d629e50f40d97a04f7f0 +2606,8cdaa1373eb332e96471c0df9a5a4315 +2607,9294a61344326d8876bc8da444cbc414 +2608,cef8e159fdeec38519bba4d33082dc92 +2609,cbd748c5ecaa38ced0df02fba53187e4 +2610,40e4d163e8bf851ee51d526d7c4be086 +2611,0b7fcc3d682e4d9d18a8ce5b4dc5c07a +2612,c6555ca36a9bf2b21acaa719247cdb2f +2613,b98d3bdfe01f449b9bceec1b7137cdd8 +2614,13d52d849dda499f7ed81c8c55d5f7e0 +2615,a3beda0ddb5f1b30661946c8b9ae3fa9 +2616,7854699f56f5e663fa59e5509d257292 +2617,8a9e168c917b5a9ff3223642b634dc8d +2618,25adda43532758d2a6fa0b2a66e5609e +2619,525b68abd7cb07c05265b34f048b17ab +2620,e941668cb71c8f8bc36905aef7b9f322 +2621,32f85c3247fea74ad25c3cbeafd96f26 +2622,ee6392af574206328be8c0555a8b20fd +2623,744121e4ae2d28c0f93f8d55eebc7d40 +2624,be41c931f918eebbca1f3f5fc6b2efb3 +2625,98aeb80012124d9aa5cbd17ed8af0f9b +2626,0178d12b94c8afed45fb7748bd80d435 +2627,a4ea1bce6d23459fec91d5f859fe7589 +2628,3e00bfdfa41dc299484bc70aee99fcfd +2629,d7cad5483aff29680a4f0eb41e9a4c66 +2630,4a763027f38691ee52747b146af9ad5c +2631,c191d7ab712f1e6cfea208af8de5326d +2632,69401a21067d1569bd9ccfd9c545d037 +2633,ecb37b1129890b24fafb9aef65d50d0d +2634,e10aa5c8750f06bbfc81da2ab404a435 +2635,87f6acb948e456c4925d68d6b9342d34 +2636,e326543bbe5d6840049ae2c2e28c3d57 +2637,0ebf2096306ea8e07dc8d9022db7004f +2638,768d2c0b6a4cfc8a24956384054cba54 +2639,6dfa782e548bc55998030328c175af00 +2640,97552a86d9080da6f6a7d6bfa253b34a +2641,17cff19d4c69b8ba14114f38ae824219 +2642,18e92eebc5c6b151dd59fd4f0417ccb3 +2643,c5c2f6918b662bd35675808256d12513 +2644,20d69c5965eca95c1ef0e070605836fc +2645,aa3fa51547002f5ec12a35c298554fc6 +2646,4d0d1b91e33e176f267886c44698989c +2647,3c2b69ab0ef4a377d587738833516559 +2648,7969b28ffcacb7105b8a10d19f7e85df +2649,17bb484cbef855d07f39400e9edfb52a +2650,d8bacc3ae5da546a9b1c2239e4f80f2b +2651,1bc1d835ca699ba10b67409cdf3d62cc +2652,9329d39e7fb4629f773d6cc7793e002d +2653,ed552433db1271765f2e95a1c97d016d +2654,5456784c028584e877bfc329309f8bc9 +2655,7441278ebcf472d9044670b5295d649c +2656,a3487787db5cfbc4e957bb800d7ccd6b +2657,4ef340855d098b749cd45a705f43d0d6 +2658,fd684afff59cc7422712c445e53b78a3 +2659,e09d3174e82e0a5dacf749dd4a00c59d +2660,31b32908b18041ce9157df208bbda243 +2661,93b18bdd294b4b89030dd9a88df93ce0 +2662,f6d63dae90629299f3964340304d2537 +2663,de3849f92ee899c470bed4df2700bb92 +2664,4f65dcfcff4a19e2094deb476468b154 +2665,8215f227324fee9dde12a0488cd93dbd +2666,db67321ef73c15079ce2a6c97ea98925 +2667,70bd3d622dd05a0e2128c0813888fad0 +2668,3db820f07e7b03efcce2ccfe41b51798 +2669,7a923cc80568df3831d004c8f36f5ccb +2670,6615352f3c7bbdd771731553d8a633b9 +2671,e53735dfefd8afb9f96cd33438ef8d43 +2672,be9326c157334fec081fdea8723c1f20 +2673,161e19ed4de8cc4bff167999113d80c7 +2674,9bd96be052fdaf7935b64ed7d6104d3b +2675,8da5f86715957bbf49cf94963f9312fa +2676,434c9341642a2e7d0036bcb38d50817d +2677,afe95e304acf0c910b566bd18601f1d1 +2678,cd19ce0d97443b552795f58e363d6146 +2679,24bf9d862ccd38e81c296d83c6152a91 +2680,b7e8238f7c6bb7358ecc6999e8ea6a5b +2681,adb1f3b0e21fcade0199e37e9d0cde3d +2682,2185243a97a784012b30b0361acec582 +2683,04f2c558a9dbeb7b200684890a79dfd1 +2684,896bfde16733012311caba6e6aa38648 +2685,073c71c3c61d0f66e4f1ce166a088619 +2686,40aba0415c78e39fd1e9b08f33753396 +2687,3d99c6c639f8d1fcce2db93a0d93c0df +2688,3752ead8d365a4298cf9679bbb5871ce +2689,a4ff87ceb203f89e9ec93d6fea8ab681 +2690,4df86754241d187568f9b7c0be35c32d +2691,7dcf57e8a11e19e8233ba41cbb498d72 +2692,5be959a4bfb45e8b7e325ea7cf464927 +2693,6600edbd952053aa3c1bb08480d7b23c +2694,919e024f26b571969fa4c4942b9e79ed +2695,fdadd245216220da018892bf84092fa0 +2696,3397b87118665ff4bc233debadbf3e2f +2697,f4eff266017af104d63aac9a5c6f2216 +2698,d222216b483d134cec80eb56e13e46d6 +2699,2cb4a7e3516b4885e39892d0280c2729 +2700,bf0a3bb641bb944be8035f6fced0582e +2701,34baae9800cc0676a7a51bac51a8c886 +2702,4ac0b7ec4b2f554b56979c7d5d907416 +2703,02673d3d53572ebfea90db1e9c342786 +2704,4b5a2dac7c6dcef8326df13db3f4417c +2705,79d7bb37376952a4a6ee8ddcd55d2375 +2706,e27b9f388198be6217e1484299f071d2 +2707,f5baa31d173af1297e5003de316a099e +2708,90dbb27efba6bf8e0f55ed9b3191193e +2709,a78b6100163c19e5c111a5036b830e7e +2710,e4c29b00067eed059c07586785e3b2a9 +2711,a988681866ed513e207bbcb3aa4dfec6 +2712,1b0da0edec418cc537f61b55255766c2 +2713,a9fd8d6f749877d7a3098e4d32e75d3f +2714,c5ca5b040bc48a39d393ef832132133c +2715,4009d4701fde90713cf8b0f5c4b4519c +2716,384f109318e3bf8911f0ec4450f9dd0e +2717,1e5e3a5b82cf2aeb516208cb34594d37 +2718,821001b4fc055af25db95f59ca611c74 +2719,933ac08a46a736dea8d8524bf38a3ecd +2720,47d6adc56df2eef8765be5ec6957327b +2721,2e7661689f5a0cf759050d39b509dc44 +2722,5e00f285e663d262a765a80031ec8a43 +2723,71fc600b6c4bb548e05a2dcc87c402a7 +2724,d41ad0bb5fab92969fd16f19bfab91b4 +2725,846f06902eb7ceba4058b70c47f4c508 +2726,24f913c3c3310a61890bf58aba554ad5 +2727,f0d9ee706443604401f45b5d0ce63d41 +2728,5cb4abcb88f76ea633057fbfc569045f +2729,8ed5a10de242b4439e461e5b66dbfdc6 +2730,ea829933dcff94c2c28f1250a582547b +2731,260c0fe258188cd97b900d585a788822 +2732,2ed5d28ddbed529c2ef57e61cb3a662c +2733,837a1175b53af287f895e4eaf9e62bbe +2734,23eead35133bcb9ec0fc95995cca8d47 +2735,0939d7a6b2b2025baf5f1fee1791c50e +2736,b567942ca163f582672d6aeccfa94a44 +2737,68da88fd183f0d0ef593aa10f56f93c5 +2738,ef62cf14d45137be53dede044536b7c3 +2739,7d1072431877b2bee4a68ef489d5d080 +2740,3476a25a49b188ffac4a5b876c1a6b79 +2741,3c3c4322060c8a4ccd99250d96d453f6 +2742,652329e5b01ea447ddc7118deddb4957 +2743,dc67f85b17a5fd789e368f927d5eebee +2744,21bbc7456d85ad5f8fd0517707d4aff3 +2745,1be7a0e5f53db9bc5aac3e4f9760f323 +2746,4030edd3add95af3158c44977feae2eb +2747,fe251637685f8c65317537c85d182b1c +2748,48a3ff9a34676b65ac2f91381704d3c2 +2749,a8e9a567683fa3b7bb291ba7bc82dbf6 +2750,540b92012e3d07be91e059a01a21e84d +2751,3802ab270cecbf3dbe041c54e11c9426 +2752,80fde70d78f3bb198119ce7d91ec2478 +2753,a3a0438d26beae04505d2c8bb0710f78 +2754,b5a8c730f043731e153c1f84370c310f +2755,8ff530a5346eca80323a9bbefabe27e0 +2756,00b9d567d10473e7ef27b16b9f1bc969 +2757,437bdefca8d5825cba242ff2bfae9c11 +2758,74fdae3b69f16a96964f7972dc3ba005 +2759,a39467e14e0a1d6bbbfefffd62cd18d8 +2760,f6950fe1baf5858f085a73d18a49a29c +2761,0235dc6fab1a3ce9f11553e45f4cbcaa +2762,1f540f49c707bdd895655b45e0e7d06e +2763,066e521d5d8a3978df87206b07ca1245 +2764,e61c7c5dd26f38da5aaf8bbdde0fd337 +2765,f5d754cc4f1a93601bbbeee88a4ecfe0 +2766,39acfd51b937373fc5f565b0c6f4d20f +2767,10d4ef25b755f690630b6fe69da3933d +2768,b714341662fe4bdb2d2f69255219b763 +2769,63a395aa1af6dacb7cea6ec61e180b60 +2770,6d9cdcd3123c827f8872f8e195fd32fa +2771,081b3169919772c737a160579a1ab1d0 +2772,c6cf4600e2e5d2a703a2d60b85b0034f +2773,443ab2bcfe6fe171491021d72d55e42d +2774,b82e5b652905e67433d6c1fbd699e4b0 +2775,88cba62dd7099362646236377a5bbba8 +2776,256ff6e5ef472cf0900660f67a1d3227 +2777,ca892ad678017d7acbb7bf9fd6723382 +2778,77d3fdc769d27acb8732d3820551f6bd +2779,f740b362a91960664462f6ffb9377a84 +2780,9eeb99f8e9049d55c442def2a4ce6315 +2781,5abd2ca1cd36071406f88ab76c8e99dd +2782,a06077f3666c19f31405b7c491f2e3d2 +2783,c9e5ffef2be20e7f57a5e2496e208343 +2784,5e57a48b3e63f1623caf519873cd0842 +2785,928d718bcf05d707c88df81de12577d1 +2786,28bcfa51f63bf43e3c7d94b202b07fde +2787,15a015c0bd7c9f94d6f40a18e120734e +2788,7ee581dcb5961fcbf1b925c63a187999 +2789,f53821e62085cec71fae7eabac87329f +2790,d6f2ae281c9159eaaa9a2ac311283ad4 +2791,c49e7b64bba59396fd1f996f7f5fec32 +2792,7efe3f533e402278d28e692109c8e938 +2793,44662bf695c53c0e3eacd8c0d93e6978 +2794,45ec920553836d0d23ad68ff1813a329 +2795,712313e9ba03f58a081491716648a583 +2796,812ebe34a104bef080c134816bf552c0 +2797,c890901f818bc568c62e0d4e18fdc672 +2798,e94c81f60345c651487a799154e6f9c4 +2799,c0a8e3b3684e63d07a3c400c6d923203 +2800,29383d308a95c62ec46efb9e9c03b5b4 +2801,af4921ed67f2f4ecc8d374366ba30a58 +2802,d667f9c828da11bc0974c2b9b3ab1bfd +2803,92756853293ecc8cfe5a24f8e28f8607 +2804,ee14b7c4ff4ff67d4ecf7e6bcd702217 +2805,39691d375dc318eb3fa290dc54d46a11 +2806,1cb87cccd23736ac0c030943ab6e9240 +2807,4e9ce2d5237cb772f8fa1f5b499066b7 +2808,13a473de7a2f5e846fdbf0381ccd47b4 +2809,08304dd21af585a5cc444775ace033f3 +2810,62cbe47985f9c4b39cc90e4e062e0c2f +2811,0234c6ff8fb1800655de9a285b2cfaf7 +2812,ef53fd8614ec532c032890664afcc7a7 +2813,d629fe38942d71647fbea0c2cd5955b1 +2814,97ebd435306cbb89b74ca4d46928643a +2815,91ae27cebf61e9daa801f6cd66cdb380 +2816,45060b4ffdfd671d2bb2263f9f86f9fe +2817,a2e2442611dec49bab2efc429b8a74fb +2818,277de42027e65c149444d2de8026ac35 +2819,2db1a01b3c97b4bbcbf1f1114918eeb1 +2820,0d75f76085ada1935cd01af41ef0d27f +2821,9bb90db16956d198b871803861d88c6e +2822,410c7e1afd4de0675617ce81b6e9cdc8 +2823,2562bf953a263240831bd145dd306d12 +2824,7179c4484895f2e63d8513c6c7c36f7d +2825,bc8a5ca0a93703a8542ddfa46c61df0a +2826,8cc4a46e28a30748de4633e982b02f57 +2827,82f9d67cc6aadd45e4ae105f42db81bb +2828,3ad22bc8f603595760fac14f9fd63f14 +2829,11d0c2c354a316c590b7a02ecd719b6e +2830,524f3bbbe91bcb2a0f891d791e4b2e6e +2831,04cba8d7a4e67e9b96e9f314630f3e6a +2832,9f9e18987d473063600fed75b006ada4 +2833,9e3575bcf7098ad4998358096616aca2 +2834,321a05817d193c672232bfaaa2dcf434 +2835,a0149a416af091ea16b0e71f849ebf37 +2836,6ee9b9f116ec16e5e0e463361ac9b078 +2837,a0c10803970a2375ec560f0e249ea4bc +2838,463bd4c3cff40482ffabdf5e7da537f5 +2839,5c0c7761feb24aee59430ad4c371b82c +2840,5421d90b6e0b875c841fd8150bc2173f +2841,91c9181ce57a1ade2bef399c36619cfa +2842,7e45a9f918a0882b5037e7d20a226055 +2843,41de652acbd78a6f455fe70922f7e037 +2844,93ae16783df2c010650e0f1b4ff25271 +2845,52272923cc2d8c7ee9c2ffe6ffb97c1f +2846,14c64186c50eb976cfa8f145a9d8c598 +2847,e2140648eb7ce8bb4ef25dca242d6974 +2848,e433eea3a005c53db306b28971e5b837 +2849,a5371358368e98314336e0cba72979b3 +2850,8be6cd47f69d79125cb9d0a0075bb281 +2851,9e8c0f3b358a31a395748ff70b1ff155 +2852,61752010aa87d57cc9dffefc89f3f0e5 +2853,a9bcd2f0576f01649004c977fbcedd29 +2854,f03393034c79b904a55b41a55468d77f +2855,1bb1417dc331d1ea1c4fe74c9f0e8b59 +2856,dba739c182b016858ac30b882e232a4e +2857,781a924561ab6eee3d6653d8acec0afc +2858,e1127276758359722ab13d7afe1091f4 +2859,055f4e67af2a9e1c56d7b826ceec4087 +2860,fbab9029e6fe034c40ef531220fc56ac +2861,bace4d67a23efb59e954d4ae9f163147 +2862,3fc55ff069d510096f6ba11f78402153 +2863,d829f1178f0faeda0cb60d1e9ea354a9 +2864,ea0454ff637262fb733c8d503a045328 +2865,9e131ad5c91093299bac6772e1c755e7 +2866,3c8fbc4934f87ca9d62223978c12dfc7 +2867,c4ee7c320a6c285d7c88e86a7b93fd12 +2868,3043ff8613d177edd90180cec3451c06 +2869,3bdc7cea29c8b3659d0519de14d0f5e4 +2870,6761670d840dcfb590f0be8f05518b59 +2871,12cee4fadb8b9620423e2bcb00cb592c +2872,75e36cb5140210ef9cfe1410a8fd6323 +2873,615857e7aa5dfcf39fa57112fea5e193 +2874,2b6a16fd69c049a653a5317c70c4bd0e +2875,b8ac05c150bb367149ba1365f23d1a89 +2876,00c489ae66e3ffa5ea546a3bd7685c9e +2877,d7802ae9ff8a27670a741b690498c074 +2878,89aeea5517d769b445bc6ef9bf739c3c +2879,b7196acf0cef4e8d22708aacf5c5903b +2880,294cb8dac04751a1f56e86daf6065c02 +2881,385c35f559814348324fb251b5ca6c28 +2882,bddc8eaae88111d2ef3fca9d4a1c255c +2883,8d68b010dd40a236984bbde2d92abd2d +2884,91feda3e4dc4649e70ed56d64bb650d0 +2885,1ff94ce6cdbac1ab0bbae4e5c622b9d5 +2886,1bf63b5ee24c4cedc53c65f511819856 +2887,7abead91c439b64b5f4c68bea6661a42 +2888,8b644047573271b80bf86a808d0d86ea +2889,48b4af3a7452fd0e179d993fce98ad0e +2890,a2bec2b37c5a6238bb4657ad170f3c17 +2891,1da9de688cfc38f998766a6c3428df54 +2892,aa705befb05439d8d14d392e43230e9f +2893,a59905841d4b89479584aeabf15f18a3 +2894,67b5e3a852ed2fc360dae7351d87bfb2 +2895,6227087946b71bdf1e63e8e530e559cd +2896,ef72dba9b04403e081853004cf28bdc0 +2897,ec8cee2f26dda9515488c5a5f1c80e96 +2898,14effe2ae9a43c682fe8413444bca63a +2899,bd91b7fe8130feeacf2bec4fc2e35e53 +2900,24882d70e00d213000dad544acb51177 +2901,38ef73d20d5d548f5675c0c934c5e993 +2902,577339f9feac5cc602c9032f4aae22e4 +2903,da5f38921953a54d76a79802e4038ede +2904,d2c950c7fc7048e472f3dea40870fde3 +2905,eebf2ed8ed7389fd03f3e3de476dcccb +2906,0daa6d495e02aafb8cd52e7093b267fb +2907,95bdf9e53fd51ab7d4e1c2ceb762b486 +2908,036c320afd5e9e3bc7499c53bc6bc1cc +2909,94f8b9b5e02abada4d38ab524bc75722 +2910,8f9002747ac5166bfb9181fa6ae96752 +2911,bdf74fbf02a35d69163304733ddff8bf +2912,ac6ea0267610cd44c818b9c111713b81 +2913,3ede709442824a6135262ca4b1886f48 +2914,f96bd8fad2cb927c275180b3bb9c72ad +2915,c9bbd9d9feca453e8685324ef1440326 +2916,bbfbea574119fa5dcb2e6dc260d2e7a6 +2917,17001f0c94453da63bd0821bc0badc64 +2918,06afdc8986a5bd0b37ab66c081fcf124 +2919,b863631d337202ae5c28069c891fdc9e +2920,af78d0bd1527365f683e5ecba8506178 +2921,3fce9eaf96333be20c23489b18f5be32 +2922,3379ca06824585e07e37b05dc214e062 +2923,c1fc79fbbdbdceb230b7754db6692e0c +2924,f1393c2b280f9c11cd0fd6e5e6830525 +2925,b33e81590e8fe50f52ea1014db01c4f8 +2926,4bbf114d1f926fd4462c097794668f25 +2927,7fe47ab514cff212dcad3695d56d6292 +2928,e79180cda5d67fbb397d1dfadafe9812 +2929,365aed6dd959bf7e40c482c1c33eb4a4 +2930,7523fa0a23eb3b8eb0acf6487992e4c8 +2931,33e09685934d03ffd7c5883cc6eb53e9 +2932,acecc5e83da7f163816bde3bd42c6539 +2933,ab6cebd41849ed552bcc788082a863c5 +2934,c7bbac8a00970f91f427af575263a98c +2935,1511e6dbdf8e3c4030810cf3a0bba137 +2936,2ddb99b9f1efe8751c3e825ac0cbdb19 +2937,78677fb9ffee44c58d79f55a8b9ef77e +2938,f69fb484b9e5a5fd087d5d48710c9311 +2939,164128a142717cafbcd1fa7b549b1944 +2940,ba74455df2fff1994a9d710910ac7a24 +2941,5936a5a6d16fcf3813ec24a7e2331b07 +2942,14ed39b15c4c107c699305b688c70b58 +2943,0aab1380d7dc64c5e18e331c38b433f2 +2944,fcc15834da21ec18cd81296cf3ca8c33 +2945,ea015bd23061c3b44f3978dedf1a70f9 +2946,b793d13c75aab55803436d57ffa62b52 +2947,5cf00b61f7c70d1da1acb6dd8ccc5721 +2948,eb45cbd353040a0915367a7def3a012a +2949,9fec795d8f1833d883b3c871f35921fb +2950,9bc0eff392caef6e1812ed846dd017fd +2951,9ed49d42e72a26c7aeecf5f5c9b9d640 +2952,c61639a65c746310fc3e3bb25abb5ab3 +2953,dfa39ef628caeb77b560a69372c1c3a2 +2954,dae8fc868e120ca064708e2fbab03169 +2955,cdd1bfad40f0a9f9607443a1d7ccdafd +2956,414459645dac0157977c11f03357bdb5 +2957,e51d005d66a5ca3a3eaddde323d577cd +2958,298843492cf4b0a6d402cc79da756a0e +2959,ce7fd77e6dd9f5ae05feda56ea3e9bdb +2960,14a371bfec02e01f6bf23f052d11e768 +2961,6077e7cd8340d2d01b66994127baac9c +2962,5294f744a414104b099980655661ab65 +2963,ddda297015422dcfbb08e92b2ff05953 +2964,508b79744fd09f385e1021b90d8d920e +2965,de82100f61a6772da9fbe05dd7c0c65a +2966,63f76f01af583cf5ed861a0944ee4699 +2967,290dd9de72cc9167f50ffcb998be9699 +2968,36541e64ebf5fdae7753eb07cbbbb463 +2969,cf43757d038c330ab881ddf3092e1602 +2970,a1db2da23b0fe9485c9714a7e49a3b69 +2971,89b0f81affabd12526ac485efaa358c2 +2972,28b2f115c2777304f01235b44a62c1d6 +2973,5eed9a132d20581e017fdb8f36af9342 +2974,d8e598c741b4c34ef3313e8c5d7bd10e +2975,eeff2347ad76a8f24d32e56f432bb049 +2976,a8e5d8ed4bccfdc7baa155074e7fdcd4 +2977,f0b6e25a9a5f98f4765ed519cc168ed4 +2978,717fd24a3cc8f391e9add07708b6a4c8 +2979,aba9db232bd422dc89f1f29b9cc2683e +2980,5c4039a8e121c26851683ea0a2fa62a7 +2981,cf32adb4b24fb1a700e33842dca7e8e3 +2982,16688469aa6d4caeb24835b0ca2bf8ae +2983,61d85aadabf766a5ecc8ef6ac3a1ecca +2984,98a6f2ad22d8d562fa2da66810469914 +2985,07562d042534b12e9c899b5bfa18725f +2986,4c60d765b8b7c6ab1f033ae94a438b1b +2987,683f6ecd5959129704cadc18c7dd6326 +2988,f8ef4233347f68265d8846e7966f1fae +2989,abc0dbafb5eb12171e1a0a650af181e9 +2990,2e95a123155b10b9655ab752ac7bac57 +2991,497408be275196ca744cc73919e3b854 +2992,24100b57d87b3f32ef2c043943f88b12 +2993,89b8b2dec3889da59b13c1effff55b45 +2994,411024b5153365c7f0249e812096f2a9 +2995,1ce9f5f132713d042bc0c771cb4b3558 +2996,c242eb61eef2310011a61f9b8da44cbf +2997,90baae4e0adbbf56ac963c10a4f12ef6 +2998,4cb312644fe2e3a39565c7336f6533e2 +2999,f00e12a172c80ab6138201563eb7c616 +3000,cafb27fa389f8316ea6786d8382a5902 +3001,1e0601c0bd17fe857ac869f1adfa377a +3002,646f6ac57f46cf6334af92dc932050df +3003,4f10747832635a1302bd810811cfaab2 +3004,ec6742a4f3c516e3534e45ad8d07cf8c +3005,7b57ba6df9f8451ddc93e2b1624c4a43 +3006,61796144fa7ef5c9daa29e715ad478a9 +3007,204e0a7f99f0123a3952bc703064de07 +3008,c890d174f9029c45d778f0f46373fd88 +3009,1585f11308e39b9765cf9701c5aec124 +3010,afc153fb3338aa7c107197088bbc83e8 +3011,d60fcf016977733e2b64de1627b1dc46 +3012,8e30c648f191f98655229496c99295d7 +3013,50c1c4e29553dabd0e411ebcd5268603 +3014,8ae3a5b15e9b48b6c397bb8e5672cb4d +3015,51e52de2d51187e1d497646bc943dda0 +3016,f75bf05a231df0beeb02a0a50a27264c +3017,d1f3ec10e438272d539129b77566ae82 +3018,37c58550579b28d56c714c69990411cc +3019,ba9ea295d07f6a3fde10745fa2f6e3ec +3020,bd9ebedbbd1a8fd977bf6849fe420682 +3021,3a3572a95d73d8d82fae6ff8ffb2cdfe +3022,fee3792145e67e2b2cc1c3cbb4173bbd +3023,d60b3939e7c5dfa1bea083a18ea17f86 +3024,40a84123db8a6f4f86303a737a8a38bb +3025,2001bd4c68e9580999e57c9125161f1d +3026,e1444410de150ca0153e4922809e7d54 +3027,4439799ba84288809aac95e2350c2823 +3028,2002a8545d5da9ba6b4bc5109cdbbf85 +3029,c67859f70fa02c5a51bf6e6aad3e5816 +3030,ee6e57ffd10cebf353c3f2b5dca0bb00 +3031,e534e6da957345bf39b64c0851dcc95a +3032,98948339f4d37361ef4bd530ba126cd6 +3033,b69b228f65ba826f57061ff075cf3bf0 +3034,e04c34e21a93be980c5b95463421dad3 +3035,723c81ca02e78b6e6cf41009cc070371 +3036,f4cb68ce892aadabd526e0efd9f95ef2 +3037,03a619038785e347c965efbc1fcf3891 +3038,84b18dfcc8d0deac571889fb6febd8cb +3039,b5ed36a870c150e57e1008861a20a06f +3040,193c39ed8fd5a37a6db037b8158cf95e +3041,25b9d27c4a8b57871d629d0d29b11659 +3042,eba0f4ce46372e67e1a84ed2b0b42ea2 +3043,3cf30ffb8b9ca8fa3697e1dfa44d1466 +3044,f29f7a4c4ad25a52bc5280a6b33ef6ff +3045,c28627cbcf1c526be8ce422b8cd644af +3046,a2ec7c26249d69d6f9619b79a725271d +3047,8367e708e478b2df075f3c576ba3efba +3048,430b079d5e08fe6608f6b5974942c9d0 +3049,d3fad83ff580f1d262504981fab33f46 +3050,dca24e72c92d41deea5871a211e69854 +3051,9f877c6cb69ab5c623fe9c31dc4dac75 +3052,5aec9ac85934e1b881ed0f2fa00ae16c +3053,9cff1d90fd0cec2a01979637b301f2bf +3054,af4cc4432e0f897e0c31df284810eb16 +3055,8e82d0019582242291d1152c55e2d00e +3056,8fd57ad807b69e144d17323d20bfaf84 +3057,48113949d252704a24f4b0836e1f5f88 +3058,cd42ae93908daf9759366b0761f279fa +3059,f508c4344185203abfc79419a0740e37 +3060,3665e655672e9027814e740963707040 +3061,fb4b7c0aee647a5f2828366c0879da93 +3062,b9867dc5c5d2d08c0d9ace88b3c311a8 +3063,93ecb5ba1b083ef25a74a0336649f280 +3064,2c24c5dd121a11aae1859d0ba35fb121 +3065,31c466cc5ab4aac4439326641914675c +3066,81b5c9a1092d4a5e0f6851b0b01d6a9a +3067,2575914456e37ecf40e0977ba30d85a9 +3068,d4230ecf6042c8c08d4d4ae11856eb6d +3069,f560e9ca0d1c229907e805b1d4ee7ae4 +3070,e303ddf60534443de4d223c63bf02df1 +3071,cc0ee2193c88d72c1f7299f16c0ef45d +3072,b8c7727483bb03056266e07612821b0a +3073,6726d902f2a4173e7c7db375ca0d55e7 +3074,75a34d477d238ebc4d1ee959f8a97d05 +3075,ec71b6dd282af33be8cd85713c5dbd02 +3076,77dd4176448661fba7da22d66d2ec92e +3077,f590f278c6a4dacb9b2c5bf8c9df2237 +3078,4801b81bcf16005d8d621f4538bf4429 +3079,d395a0231f1d1a5386d785cc09ecea78 +3080,98d5ec5a7abebdeff91be2a713629ce4 +3081,a0422759a74c66044e5c7a17d019ac14 +3082,b0cd5c5ddd3f78df2a56797e1a5127e8 +3083,1d636fa7a96a26e0c43fe1edb095ac45 +3084,93bd5f884308398ee299954100e33370 +3085,14368210511dd2ff07475adac1f0c510 +3086,e9b0ef917e02ea14433b9164273d47ff +3087,7d51aaa9d6d6e9bb49a7ee0dc6342d3d +3088,3193fe23d1fc4d178282cde74135d8c9 +3089,5be5b374fb713f15f0ef928347012d85 +3090,36447e313ff65f1d1b981a5e5300c812 +3091,63dc293aafa4fe20ffaa40726a4191f6 +3092,081da66a48e116ad2def0a29c4e09f8a +3093,f1bfb81b65c9401842055b76cbde92ed +3094,5d8a0a1c42613158935fa54982e81c69 +3095,15bd75b7f67279388374ba4e8d5c34c8 +3096,6bca777cff71b56a5c95c02c9cea92d3 +3097,22de1f962d67f6fc6fd5e7ea39dff020 +3098,4944333ddbc0ee655327aba14b690a1e +3099,037f939804bf9ca77ff0e0f420b28ba0 +3100,0d177531b564a1868b6a47e5af581986 +3101,22c6e06ae0b6797c35586a7c9153749e +3102,ade6d45e95cf0fe3413e2d2b107f6e72 +3103,63265603c2affc23813998fae9e88cd0 +3104,8100399737b538f72165c80c4d83b110 +3105,2f6fd3a60982fd8c87ec0be060f0b44d +3106,08946a6dfef8620e8cdc5f7cd4841d8a +3107,6e125c22fdf7055cc8d3b7691f5e60be +3108,0b401a5f0794aa03397ac1849ea5fbc9 +3109,6c49ed26283e0d5dc0c3cc2d9e41ed17 +3110,4ae309fc5fc878c347f9019297eca040 +3111,17cf7cd705c1c9841812013e34984b00 +3112,5542300827dcda1e837c63cf6e6252ce +3113,1516de0646e313d5e2098d76c915ba78 +3114,17efdfe9f659b80c9377923fbf28a803 +3115,2474db80935ee6a29b002c4128328e8d +3116,6e4a846ffe7069776e742108fbc7ea21 +3117,601121fe4c37c0cc31913bf33080da06 +3118,58b212e26783b5650d3dabf66bdea5ac +3119,016f2d0aaa781b5fe03a9a413f6f7951 +3120,c343e1705cde5f3d820fbfb778052a9a +3121,6d42a23a76bd7caffeedbfb2bc4f8ec2 +3122,8a783bcbe3d80000640c3f90af042d03 +3123,25d8cbb8eca97a50299de515dd7ea62b +3124,acc7c0df8ec9020e64db8df6d29b2c77 +3125,9885d568f7cb88743ef43f28800d4d7d +3126,2df6d63c0034a5ec7d7330a308525b30 +3127,638b91c5eb6b867292c9610cd824c81f +3128,c80906f3f4760e4c564104182a516d8d +3129,a27778fa6a0f5dd77c81105ebb5bb592 +3130,a87ab8acb5cf9b1efcf554c1acd724df +3131,a95083f5ce0983c207cc3c5b0dd1e217 +3132,f33105fe49d155ac0f88a9216c737282 +3133,ffbb9d7cf5de835f6292eb45c3887095 +3134,2bd881a01c1244deec836a5159697539 +3135,e743f5492f3ac62b942b0595064f57b9 +3136,77a60799e9b673497b0b6b39343a2ddb +3137,6b97e940064badf994d08284c8968240 +3138,d78dc4f3773c69d06f7091ca1e769423 +3139,5f3e249cce1d7db0c660e29f4853a31c +3140,f0f52ac22462b9eee07b736b4cdc9d7f +3141,bef09be71da321a7e87e6b2aefb07dc5 +3142,27cfe5c35569389c9118f283ed23f8e8 +3143,8dfd9acf2476652b6af1bdb05414a855 +3144,1954df3ecc19a02efe16289f2e0427c4 +3145,bb191d879a5c356c13c83ee753c328fd +3146,38386dd70c6abf4f233f89a60bae8b45 +3147,02be92b5498fd8335c143c861c5a5a33 +3148,38f630a417736e0ea68ddd66268eddb4 +3149,c911261b104f3095f531383f44947514 +3150,a70c8e1ecdc5d74eaf4ef138fd6137c1 +3151,a8e4509a71e186cd3f3d486fa37062b6 +3152,bba41f05a2919c8a774451cda8adf048 +3153,0eb3cb86b8a2cb58692144f920456baf +3154,60ab137496c6148dacc8f5eceeb1fc38 +3155,405c470378bb67d5c3c8bd299aa138c3 +3156,b18d0b9306522ae80a1988fd660697fd +3157,43a70c8cd81cd138c65350b20098069d +3158,2d6ce2b77d92a9efa5a3b8d29abd62a3 +3159,0b2bb3eb899faa04b0974842f9f4ebd7 +3160,b44902c41c3ac1b341a87087e95a3115 +3161,942866344066e898a47034bb4ff13495 +3162,945d6579e0fc8368d52a0a8305184774 +3163,5d714d0237a9aa803cf1914b5ea7f4b1 +3164,68202eeecaa40165c945544777c5ff0c +3165,2fb51f984c5f4580875ce77b64ef789f +3166,f299faae9a557022201e90ea2d828b12 +3167,53dd0c0bf3fce56f38bde4ab0f77f2e6 +3168,a39265903f0fa0e394bac85d4e479ea7 +3169,70da862836974953e87f308e39062615 +3170,7ab3c82d67e8773ff9be513fbce5badf +3171,e57c30d5ef54156623ef68f656044c8b +3172,4b97f6f7d90e8775adbfa94281eee632 +3173,a52bc8b6dfaebd2f4c6a2539ce580da4 +3174,48505ac82a0e439d4fc64d9b258dd93f +3175,6abf589a92c26ad3fc85bf39cd049430 +3176,98351cf879cada41f898c5a3bb29422e +3177,6a57e42d7afd15bafc3a82c602e47394 +3178,b76eeb42fc148041bdced8326a844f73 +3179,725f12f7ad80ea0ef0aa35ac35786986 +3180,85b2fbaccd364b723d33450f258a73ef +3181,5db9a5b9b60d44c29e3a23ca173a3126 +3182,5d486e8df4bf1350ac2847a6a5affa51 +3183,3ea4a4d6f8b13eca761c7aaee42c7568 +3184,47a85977d9476dd5b493dbddfa6acd32 +3185,b6d1d0468badec4a32514cf5934396af +3186,036f85541e2b952f9c78b86ca817207f +3187,27907e39084420783abaedace25939aa +3188,0cbd4a85bfe0c4e38925b374230d2041 +3189,511ebe70ff80d638f1386f8511696b66 +3190,15be845663ae1f9bb73caa4230d7f1c6 +3191,e41353182c2076b536a22e0fa1374655 +3192,6cddcefd8381939d642d25946f596d85 +3193,f7ad0aaef77d948b761ddac6a30d3f70 +3194,891c9b57dbbd4ef9b6d8c036bad91d93 +3195,9ad05caea795f760ea2cd7c1f1b20883 +3196,d704d7a6a2779fa17e226998775533d0 +3197,9c5565e2849106492cb126f83de19879 +3198,16fa346a91e8a0976e8fc2d0a8532a9e +3199,8f27e7b95fc4fd8693e60f503e909f90 +3200,fc40dc7c449af0fe4fbed078c4c03fe7 +3201,6e72a7529894331b6014de2bda91cc3b +3202,0765b04754f394a07d497a51dd83df42 +3203,52223910f880fced8902ba7a18a5022a +3204,44c0483fda988cae7cedeb91ac7c69bd +3205,a94c28873e4451f70609916aa4a41419 +3206,049575f9e49737280f95e441e0abe3a0 +3207,a0673d357de963e7be3e848500b31309 +3208,cd1b538ea8d1e6ec592a8a90f7b9bbbc +3209,de1ed4816f8489f11511d49b2d8064fc +3210,5d881f5f45ee383b3e2c6020cd92f739 +3211,969bbaf401fc08d78b177f74ab1599dc +3212,ba66127a236654f619321af7919f008f +3213,fd2cefcdac88191684d8ef5a8d9fbc82 +3214,c1acf84fe24f305ece5a8d61ca2ca423 +3215,ad8740e0952f4d675f18a1e527d93844 +3216,2e9fc39b92d0b02fb87b13f5667297a1 +3217,1dca2c66851a3a631511669de3840adb +3218,cb79f3deee218b674ebbe2188bcfde57 +3219,638746691626e9584dfa1590234f7298 +3220,d6405ac9d29f860991e52d9338fddeb5 +3221,dd1d7f1ad99ba7dc149f7a9b1622f3c5 +3222,d5f273873485e2bea945144ff6e30e3c +3223,1d5962d83c1778f1af092dc6467bbeb3 +3224,415336fd790f31be2d3c8c224a7fa916 +3225,19b7c3e18b204bba765c6b10a002e3c5 +3226,39be51e639c7fa95d23bbe86a17bad34 +3227,a11b356ae99d5918a122a400fdc4eb39 +3228,a86b91016b57d80ec0c7b2f04fc07701 +3229,bece128d0640ab98b1389ee4dc041172 +3230,f4930b9cbb057cbd38348e8df4b1629d +3231,48787584978bf97b13754d15359f6466 +3232,71e82eed81a4d8eb4aff38905af1b8bf +3233,0a0c593d11aa331196ba2aa7a60e99fe +3234,852fc2ef12e1893e040822dd2859c772 +3235,b69fcd94752b92bcc15cc00011a3eb2c +3236,cf471f3a95f13b181d3bc67fa867b1d1 +3237,7870379f8779c4fb4073dbaadd1303c4 +3238,5cb2a86657455ac0017df378f10c1690 +3239,3f5df4eea44ac5bd95f564d6df8151be +3240,f28333bd61e93b1133b2161a162f7ed4 +3241,f1d70c0c986e9ef9e4d4e991db485021 +3242,8ec64daf2e26eb5730263a2b567097ee +3243,a52bc13d85de893b071f477634b372be +3244,3a8a5d10853991abe464d66f2f6e5616 +3245,db0b38a591e014f7d4f912393b89a986 +3246,ba23976dc6a85bcdd87591748f90306f +3247,2f78bc0a26921d47ab8896285aabe0cc +3248,296002b9e41333426223ac71c09b12d0 +3249,e6f87d2a133290eea9fd81c6077bd3af +3250,b55eae55e40c2c55cbc3bba97faed5c6 +3251,2a0e0185a28c159627a42aa576cd2898 +3252,a0225f22d9c5d4dfbfd6e92345f84d86 +3253,aa78fdf5245a1432b1b73626d43ad486 +3254,797e97b269801201b271edb7b4f9f859 +3255,9cc41af3fb6d8a66c9d7231ce676248c +3256,4b8b6512df2c6b1bf722c96e82835aca +3257,02511bd362b81cccd3dd672fe35fa32a +3258,356013492fdfa95a42ca565f26b01894 +3259,ea39353ec5def03c1f3c2151367c738f +3260,9144a0ded3127fb1a4787335519c9f44 +3261,1cea801676b926db0c4798fa7dec99ef +3262,5dca2e0797eeab5dc90e256af474dcc0 +3263,a0032a3dca65d8cad1b822e1275ff9d0 +3264,200a106f54f5345c960b61141b8d73e2 +3265,c7f4feec73d720a38653a8e37bfe9bcc +3266,495f9e1285001b7c6b325fed8edf686b +3267,0871b2c3f1f54cf20fe7c9ea78f96496 +3268,d1529094b86d9bf26613ba1106dd35d2 +3269,7b3829d57951aa4fa282723ff11c269a +3270,ac7c548a2d81ebed92479802ffdfd92b +3271,e36285cc3ac4305350191a1a4101eff7 +3272,c7b5d1e3df4a2b75df82de8d7a62d466 +3273,b24860ee290d8f5a487bad8298dd3922 +3274,36377bf5468c40988e38e9cb04a8d5c8 +3275,45f8a4e541131e28152c206b6b5d36e2 +3276,5f6159907f433c29345dfd7c85901c5c +3277,82b797c1c6c8b2341dd29abd4ec35514 +3278,bec8a55803b036351847aae53b211a1e +3279,1627710eb24cf67c7cda26cb001c46bc +3280,89ee1165a10725a71b81bfc30c74ce5d +3281,f5be92d00a33d9f866a49fbf5db5c291 +3282,6bbdfd019aa85ea86d2902bbc31d7091 +3283,f97ab6dfb905b74c9e60c85f2579e6fd +3284,f68a1c1b219e595bb28671516ac1025a +3285,2e11421aef825f444f60da1be4d414df +3286,147918b89a8781247fd8db72b4290e2c +3287,310973b0dae3718db77b707d78a16598 +3288,4003e3f9a875c7a2d71e6f26f9f44ff9 +3289,54236dbc7fa9c535397b30002206ad65 +3290,aa64a14f2c390b0d4fb1cce2b50c4531 +3291,580576d7cba8e2432e0f9c21616f3252 +3292,a1c3b5ed9eb2a591209994f543bd8192 +3293,3bbbabb3bbb14301fd5d7d72dff243dc +3294,4373be8c8f5904edc652c3ca9e97b69a +3295,7b8a80d06c5c0c977c826ef72f82ca08 +3296,73c69705da92ba57bc06a54a68e61217 +3297,78ec1e1db3a6f672eec93d3c15e78979 +3298,66145689358020353606897678a0878a +3299,b2d9c376fbdad9fb2952bcdd8ebe0a47 +3300,2cfbf184d59f91b61d9fac7d97bcb8c3 +3301,4ba7ac323712036de49ea87bb5e7a020 +3302,2d53af6fc21d27967afb3ebcde51b980 +3303,54baf72abef214925b37b9f06259d84c +3304,c62e6a27b5d022a5e6d1e48a8bdcb783 +3305,db2f3b8a5f84028bf930969f06de81f8 +3306,77b42d5c85b0990181c74e2e6012e9cc +3307,38cba3c2416a0247653525f4e1dfe8a3 +3308,6745b644ea9f258f1091e45ae25a722e +3309,fdadf22f0dabeff11907b0040e3f678f +3310,fb3cffff45b5688d123c97a6f4a18f28 +3311,8bd3777487dc9310ee547ef1700e629b +3312,e409db0f9cd759cec679c2c452b688bb +3313,33350b7c6c9a82f2eb5bbbc1437b272e +3314,40107b9d1ea446056dbb909c300025d5 +3315,ffcff0ef2e2448b2caa740b14f1b0092 +3316,8c0c17a00165a37ac1e8a3f238eebff6 +3317,4bf31e6d4e5ccf7cc5f94b3f396b7f28 +3318,1b90a32cfda5e24eff628271754181b7 +3319,22f6902477f27bd483a1b0d5709ef3d7 +3320,6564ab3b99f77ce14d1797b1dd5b0381 +3321,bf1c365d0a24d7b0993dc0bffb52ad50 +3322,bc68bb52f8c279ac38878f0d3b6368df +3323,396270ab6031c2f9f3258c8867fd99c2 +3324,61c894aeb4223d836120e13342001eeb +3325,6c0ecc6dd507c951e4711fa00a82c864 +3326,64971b20f40e060ee270f888b88e7f14 +3327,c0b0016fcea3506283f07aaccd43440d +3328,261f25ecbb6797c9b1dc6c3ec53d16b0 +3329,5aa597446bde1550b5c623d931185199 +3330,fb9fa41d5724b66233b87752e12ad7aa +3331,0520c4930b407379bcc169c268522f7c +3332,991dbb8ab1f7a878c73441ee46f0f691 +3333,16ea50646a3345d41357a70dcff09561 +3334,493212e60cc2fd0515980ac3516dd499 +3335,c5098231489b512f654fef311e611a27 +3336,96e22e3eb6fc8f000f0ba8e00aefabd4 +3337,4a0e959ebb2722c5c8942928dfb5a9dc +3338,34bda5a2b8b172e7111d00ed95060f80 +3339,6b46dea7bd467fb947997e13a6b100d4 +3340,691c9fdd8669d280481c79611bf48adc +3341,6bb5fae18b5e1dd6258e18fbc951c9bf +3342,d37e719421bfb9b142157687ffd80080 +3343,a2b9ce65b8a0181385839903436b5a00 +3344,0e532f67160a845c6d3de077c3c947c2 +3345,015531319655ea7339e3e00f4259c154 +3346,795248be81552ffd031386c6b8491f86 +3347,7c1dc6daee13841de8ed7a6b8b2b4a28 +3348,30af98a5da90978774ce8de7dc236340 +3349,148ebd1ca63566e3dfb82ffcdda6a3e6 +3350,4b1d7e7bc05825b4c81ae449ec93cd9f +3351,1bdff091c718672c29cfa2f3b54fef2d +3352,29e23f53473adf96a0de4a68dcf551b0 +3353,95829267d3e26b53526ad2ac0d313705 +3354,a2787ddd5cf0120a71a94e8f172c50c9 +3355,52a6f47abcc5269d533068fc03a95207 +3356,72903e245604783ba6f75591e9c1e728 +3357,4b497329821214e0ec96aa6c41495953 +3358,5ef9e96832453cdc78efeee05b7f7fc1 +3359,cb034bb29dc710737d9bd6a7a8713042 +3360,826e199c298beeb50040d5dc8a990445 +3361,c5e7b976a84dd605d499091940c83557 +3362,a80165389fb2e37eb4ef52939a249b66 +3363,b5b918f7e448d5756cd6ecbe5e373cbc +3364,297d323db4df4c4bef84799593f6211d +3365,32626e37dc87343f31b62c80ff6b8040 +3366,b9f648417403a310bb6f8348f09b6ded +3367,324764f775919cc6ec88c082c95945e8 +3368,40bbcad1e5bb9d35e23e11cdfd94944d +3369,f3e9dd8c586aa895e3f78be6acd7da6b +3370,df2f9cbf1f91f850234caa576460d8dd +3371,40677a153cd342b48b951ae9da228b89 +3372,f1fa286458e76adf35cd9124cebc7f79 +3373,65128e2bcbb50680afa6854adba731b7 +3374,62678c2ef9535a0e7b75fc590b28b79f +3375,067988793828920d92df1ba5a94aab9c +3376,c1e90b163a810470d1ff83c34ab9a3d0 +3377,5defc463bd1c8ebcdf4a1951fe1a3326 +3378,e3bf193adc81dbe16d96e09611a403b0 +3379,529e00e812cc4f04ae2345102f3195ab +3380,5f87608f293f7309749e91c479bc2cfb +3381,8bfee764b705c8561dbf5938e53b0e13 +3382,a08fabe8ead0644119eaa83767f3485a +3383,d78d0ce53e9dd3316007d4b963044e44 +3384,25951b372430a6c710c4cc0d55747b07 +3385,196bfb76f049c700fdbd96c688a27197 +3386,997f038577e6097324a4206549495f76 +3387,7d3fd4bb42457d3d925749adfde11369 +3388,1b91bbb8366932d4b7e0fd896a6bae07 +3389,8556bd97021ea291ed5aa0f35b866406 +3390,61e8f5a8f520c1cfa5fef8083a8d471f +3391,c1867bf493e42f60d9a516952d3ffd44 +3392,749b30139324280d77b4af5604728df3 +3393,d44f4f54cf06c4bc8c561a2996fda511 +3394,2db74f7020c1db3205cdd5bce86232d6 +3395,71e9604b30a932d345f055d32a1ebca1 +3396,570f81c2f98cee4b71db66ed15c4402b +3397,45c807a93cc37315f7c18bc5b3fa5798 +3398,69894d13703a25d47822125338737ea0 +3399,85fe8cb12a275eedf3c158a9c5f698ca +3400,2f2879d54d1a11d75c1e74bbb98fca07 +3401,2d63406c357b6481cb8775011a6b8426 +3402,d6e5bd03a0d24148dfa1a62e0482fb28 +3403,571bd0b9fae234f54fccf9e7b8dc5426 +3404,0ec73cfc23a3e8987521e63e9ccb268d +3405,17b6527c18bd2a2feb806b4f9747acd1 +3406,03fc5fbcc88671061b0e9817379e6bd0 +3407,c829a8ab0d4e4dd1bece843a9efe9aa4 +3408,b1e0b94c0fa5c8310895099bcccf5715 +3409,d7e0a825cd46f547f3a45fca4764cd18 +3410,85a49d0ecdb48e8107bd3368abbcc6c6 +3411,ecef2f99e6768f49141555336307ec1f +3412,c9c0e51da5b771383d984a735caa8b70 +3413,48b397d4b78e1ec084e4f7b51549137b +3414,bceea44bca518b5c5e16b52a35b63a29 +3415,e7ada092f5f9b42f99947b1788c078c3 +3416,93a6a521fe3e739b635adfa134473240 +3417,3ffa913562280ad32d687e9e56b40fa3 +3418,905d3d2b3dd21fe8b71003a4e80aa986 +3419,c1a285050fe0faf481a75661c1a34a98 +3420,5f36d24f7ea8d6c697e3eeb140cd0aef +3421,27e473f18b5ce79d26879e96d56c88fc +3422,2ba0a0bceef660390897ea35be60e6f2 +3423,ca74466fbfa3f9fd72bed730ca0e0b02 +3424,8a39babe4d26422f6c8a67844057fbb6 +3425,deee7fc2068b9429e0729da3baa08094 +3426,a044dc97398a4fa9b96253383931b8a1 +3427,74cf3fc0abf282941a027cb9495a7a76 +3428,7f0e987e2a6b11fdadcb5528269b6a68 +3429,6e3a7d5db52d9148045bba9bfe42b9b4 +3430,faf66577a454afb7e3bc37b795817aa0 +3431,7f65272ffc94654a18ad02493bae237e +3432,8f77e1ce594ea3c0d6925f8c08009c50 +3433,2c2d1f71ea897ce46fb4b6e76a3d4732 +3434,ae03211a763bc337fac1546285ed3ae9 +3435,f4069594d9dcac93edbc271d8bfff151 +3436,f96f5d27182ea29cedba0351bd394c4c +3437,022a08a58a1fa33b6e4bb5bdc1bec3de +3438,53deab7408af07acd724b4fefe9d75dc +3439,99af1d69e0adf035f50b10d4f12aa9e9 +3440,7b56e17a531d538ca482213fceca9f70 +3441,59a1c0a4867ae518702064c280a9adb2 +3442,23783c1867b0b4131806f6536b05751e +3443,06035a830065f3ce7f15436c52124703 +3444,3417eabf61a360eb86d764a0355d4989 +3445,6c02ff0084c3ba708cf44cfee6af0764 +3446,806f1e51aac512e397033056a5d97f27 +3447,6a270b16647fb0b342ef86fa148764f4 +3448,f980be9681d1ad961d9378bf0c0fb0f0 +3449,9a43ea9ff0bc36ad44f77d810d909d9e +3450,98a003c2e7c89fb104156d31df7f0e4c +3451,91fe4cca975c1c58adfe71c9b7ba6440 +3452,a0f23d7806aec2737c10b9e3bfc01830 +3453,b5945136e89bddd406920bab52e68220 +3454,807e2cdbb25d14f59fdca365f6185ba2 +3455,fea2c785cf93e0bf86e8d6fa4cf31df6 +3456,713e2c6fa299e1362898bb878fed9b61 +3457,2baf8964549f228874185e8f1260b1d7 +3458,e627f58c836f0622eb2a149ae9fe7d13 +3459,972ef8d6ed60113c46989d8f656ed3d6 +3460,0272fb763225ccf30a80bace685eefc6 +3461,b0b3cec9b4ba89aa897e1ed64f457dda +3462,2c628989754b6fe957e9304aa007ca0f +3463,77ba48630d33abe71a3a175be65f37e1 +3464,f2276b9a40aba1e6e76078c6d3e92541 +3465,8419761aa25bfefc4dc29bf3ae3b1c05 +3466,afee8211b361264bba56f2da33365f2a +3467,ef3ed57bb3a1811f58b987db967d4768 +3468,c1a466199209d005908d06552661a4db +3469,6f10770965d9364ac9ac6567ae790787 +3470,55a74e17151c8fdf019596a5647dbcb2 +3471,a57cc40263534a3e9bfe1a6b53fb6b93 +3472,ca1c271b65a6b6794ed89427f47f28fe +3473,7e89169a0005d4624c45b4ca9a90febc +3474,600bd8de72ee1bef03633d17985572ce +3475,78d7b43c90aa5819286fb1f4e1f42870 +3476,976ac66068547197a8ddb1e5d05ab470 +3477,07e35c232c0f297241fdfd17d5a435af +3478,149f26ff1c8e32368bc61286d0fe9430 +3479,f04afa39f9e5b36fa9af92055b25ba7f +3480,e18d6ca4c881c4331d5e13ba63230713 +3481,5df44c72837c3088d574c0cd1f577f35 +3482,00b8046207e84af06ee14d48ed199817 +3483,0b71818408d6c7570124e8bc71fec8f0 +3484,d6bdec9119d23406c65982ca31c0764d +3485,e12654726c6f469176e9eb17041be21d +3486,e1a70a08a1e8b48d04d7cefd2c3b07eb +3487,bae28b66c7ad7f8ebd180c42078d6a1b +3488,9d186931630445e368649cb52e280505 +3489,f9c94b22733eaeb5148481eafcb58c76 +3490,a0c967aadc28cb2d3f7f90f0cf4f12f6 +3491,8c789d90996093bd9fec18f45908a2ef +3492,9336a38cb3a79f450a48aeeb9db04ef7 +3493,f8e4288b4f5a3fed01756833ec6cd124 +3494,9f3f661eca61b5e0a8c00300d04a2575 +3495,46c7c9a313a9ac05f6bf68e6c8ab09f8 +3496,42820b7ac3a2a239074b2f9a44834bd6 +3497,19b937899042e6465909170db0efb665 +3498,456b3ae3a2ed48ba2996ac1ec5dd7073 +3499,d330797638359acce9e987b161b11fa3 +3500,7e11a7ca6e2a8266e468d1b3cc48c76f +3501,43eac85d03f94f5e591b4d571efb0391 +3502,53802d4d090d216bda99563bd1f0f863 +3503,38550baf5cd310dbba86ea8ace4c4b66 +3504,c0691e5cdf8b3b2c3f3f5647a7850768 +3505,6d1abc60f426599fc1994f505237bcf8 +3506,14686f76c9e42d8de23c9d5437bf59d2 +3507,53cda55f5eb2de28f46cf301aedad170 +3508,dc21c493df3ff3769e7883b72b25fcea +3509,dee2f9781d787bc441f6b285ce4ca8e2 +3510,3f5453610e461082972721e35d988ac9 +3511,d2d558ed54f5ffec9c093ca71cead5bd +3512,85c32b9a31586bad14dc6e4e16cc86dc +3513,eb9d98dfce0382230fd27e8435a0bce4 +3514,ec1d50dd0fad4bb34f9bc71a4d467738 +3515,257a1bb7c50a0ad02ed8bdfa15822ed7 +3516,5284df8ba61cda54d9cdbcd6b75c3d55 +3517,d34946d40920b0e31d32436ec3b439e7 +3518,7ee41514644e58a38e042d2a1d3c633c +3519,e270e55916afeee291bbbe90a19f3578 +3520,9046c82b9ceb97959caff53c8af332b7 +3521,a932c6b41cfcb09ea549ae0cd16f46d9 +3522,75b078fc31d296f4751002e4db31bd01 +3523,9d4af636df6e0217a5086344b257e961 +3524,44d835bdfdf765fc19a9d591fb948d0c +3525,4aa6d47b49daa3f5f6b86a3666fb442d +3526,d125adc0e43aacdd082bde948ed444f8 +3527,e7e2a5590e0371453f2867f013c7299e +3528,7198a41416b7551425acf0bd088d3a21 +3529,a513554eb8024522f706a797f5a6eaba +3530,61c950138f5e144efcec5ae3050026f9 +3531,250968e040d177d89b70c63b2023b2c6 +3532,92cd6d866203133dd2a9f5d242188690 +3533,2ca6469b8d554b45807ac127d1e462c5 +3534,c6385fe5900877b4fdd5ac09e9a646ed +3535,5e22be2f65a1ecea03bd6dfe753628e2 +3536,e303b9a427cbcd577c8203b914ce0bb4 +3537,b61dfc4996a74a6b40fcb45e1faea8f6 +3538,5de92f12ac6d9df095528ae074aadd49 +3539,003908cb8b3d394b38893c003f0744f3 +3540,a9c6c90cf7136ef6e3d25308d3964144 +3541,b9727b52717f7618ba888f44457c6567 +3542,40a76d8b625c2a005d5edf636f481b75 +3543,8b3f9b3ba613acd18f08aea8b58b314d +3544,5290968250ccf4a297a893cecacb27af +3545,a5d6c821f2fb00be74d2064fb861d882 +3546,67574a9bcc832ecab74795aaca64b430 +3547,58bca6b90951087e790aea584ab48c26 +3548,8bc306a9cf4e633499b1e6a143b15554 +3549,b621181a5673108fabe9bdd15e3388de +3550,a3a2eb5dec7965c313025e9449a96229 +3551,156206f52976eeabfcb4254d80283926 +3552,5bd97873f0e0a3a0e97abfbe648cac99 +3553,067611b703e94e18df06054fc4a4f9fe +3554,bb7af6f25eabd8cf74ff8607b1c10cdd +3555,0be0d7c5c87143e38fe8ab545bf29f9b +3556,603ee6b7f12768b6f317807fe090356d +3557,e308c08e50cf360de0bac8d9e859a307 +3558,17bd3fe079faf701531c94dd77e2adce +3559,289d5cba7c50c81b7241f91e05cf9773 +3560,0366742dd97cc70ba79bf6283045eef2 +3561,5c8c3715b55d34fc7e1089b1a6281815 +3562,ebc901216d874f8bca568282b0ee8113 +3563,934499c93dd2d275472aec7e5ac01852 +3564,2ca03bc222bd0f04d46bab6c733bd234 +3565,cce483efb2efce74772c8b464c3dded6 +3566,aa99b9ad82d6f59b56652689a29c1937 +3567,ab245032258451754521551293c5b496 +3568,602fa0cd3fe250b6f29a0e74510b691d +3569,89aa86eb1bdac46acd9d14d31c5b48df +3570,9b0dd37f9b862a83076ce4f2816ecb7f +3571,2f223b749a199355990e9f41f2c9b2d7 +3572,9ff392118321a93138f69f6a671e5efd +3573,9efb7f3302e72ac9d0f8ddded4063232 +3574,36fc54f5e985633fff7c06a1c60f2feb +3575,ecc769b653704dea3229a87f6e277061 +3576,6b38748c7817e6729297330ca51be07d +3577,ab8d4b6df91ce53df487455389ad202f +3578,08aa22614054a82240695023dd0965b4 +3579,f1d4679c1361d7206b5c9c1aedf2565a +3580,c440888ebe1b81589a664a1d3b702cb4 +3581,3416554844eb6485a41e4b7e3c0ffc63 +3582,fcb96151ba83875d704ad1fcb0ade2dc +3583,10fb83674c0f477953ce5ea17f0f38b5 +3584,641390beb9e81ad2359d79b57dc7471e +3585,336ff8e2413a342a5a75b19b87f55104 +3586,f1110dbdcac483008650771d73d5cccf +3587,1e3d46130a8ef2fcb61667c526b966d4 +3588,c3cca7bb22e55d188b38760aaeee2333 +3589,871b7f3db2c15dba1b2fcc54ffb58922 +3590,f45f1252b6591945416f57c66cd8398c +3591,2f5a6a6bc9cceae892a2b90d10b180a3 +3592,51ee06102b1cfe9e5bc544929adcf950 +3593,63efa97d9feb8a047b8209f23c409a9f +3594,22fe675298c97abda347b6d616ee36ee +3595,5eaff7f6ddd323e35fb56269808aa234 +3596,a6a9a3bbbaede0420d73d81c07f3469b +3597,841fbba268924e7def9bf9b7bbf488de +3598,b0dc211a63577f0e134bb5aa53c088c1 +3599,e7912fbe2f069d1d5bdc815f2a7fc8c9 +3600,0b06099769cf57cac1fefb9c5c0e6963 +3601,ccecddb81e8db4b15c50eaf26d83e6bf +3602,4e93cc96bd1caf1cf842cbda585e7c77 +3603,0d23f8ad0cbc1aead914be10f9a3c377 +3604,693195903a0fa52e75a713afa6807cdd +3605,8d3882ffb5753aa73d2230bfab281e42 +3606,1d049060d51a4055344cb6c63c3d5415 +3607,8bf447261b46df3fd6e813ec1ee379c8 +3608,e914f12e68b80eb2416063c737a997b5 +3609,11233c0b3b0bd29a2439c6ae2e5a79ca +3610,04f3b35c58249ab0a45bcdd583745c52 +3611,b89bc652111db35d16a4d88b2955b2db +3612,04512c1aa5c06cf204aee680dbd1a260 +3613,54e45fc071ca87a4ca0376697deea40f +3614,d5eede85c351c2fb52f40640e182d69f +3615,84cf03aaea664060526d36d3455233f5 +3616,0082ca0abe0a5e7190600c8485d94a5f +3617,f71b6c4871eb10be45783baf157826f6 +3618,7f728a6f2dedb5cdefceb1d397614d31 +3619,c3a08e831bb6eac366e5440c138a6766 +3620,f511820c2eac33ca06bda7e591d7f71a +3621,d3d467f4cd844087bb3e0dabc82e7f7b +3622,c3524bf76d27fc50d43d09319c808536 +3623,b98d702be4794ea64a73a4f1cacba330 +3624,fcba5d5fc86a60c009185be29b20f9fb +3625,71fe8a5978107825253029e32c11e4c0 +3626,a124af9bcc3d97503b4ce9e8d0ff6897 +3627,8d4e9bd40529558df9c00412d570eeb2 +3628,57d6b84f48de6af58929fa15662c4739 +3629,571df751cbe8bc56b9dc4df32ccf3b91 +3630,5c50af9a36328c892fa61c414b8b7832 +3631,d37d083129b5cb7025232b7f2b471d63 +3632,b0cf0b4a7ae9bb42a2ca4331c37f402d +3633,ef80fd97cb5c1c19060eb8ac1e957e15 +3634,202c48d6cf19ddbc14154ebfe8fbd210 +3635,79bec2d34f517eea552c802fa61564da +3636,e075d5eefd616145f1d526e979fbf330 +3637,d8c4e63f9b27b9a6e057799eb1967240 +3638,afbb8bebac74bd136546014cce759853 +3639,595dfe4c28af147e383309720f338347 +3640,4377f55f7780a159b09a7663726a326d +3641,44d41431227dc6b25c2e34af1e47df03 +3642,0465c760b9ea56cd434c8a8cc6a0c969 +3643,8dd27dbbb44a2854ef89b00e8d5fbbaa +3644,752c27e06933313780bc2130b741bc69 +3645,085f767f640317559ea4f72354fa41a5 +3646,b70143557f5e35f7b3ac4c41303306e6 +3647,bba962d0fdceaff5a8100f265160fbed +3648,d8ace07fce924696b3cded842cf39e39 +3649,a27974b6855b3558b2f485ccfb5de1ee +3650,43d36642b8e525933daca91d8c294dc8 +3651,68d7ab018163fd2fe6d3bb095dfa475e +3652,ab5bc7589cc164f84dea05cf339941ff +3653,b5cec223269d2e8fb250bb9890de4b35 +3654,95a0193a99e0ae77ba89f03958a408dd +3655,4a0869760957ffed93327814522192c3 +3656,e77d251e5bff8944fb2913371408669d +3657,468db5ceb40300fa1d98b55bd2a6009a +3658,c7b9741fb4a0d578bb468ee01594b8be +3659,d36e2c4844b01c6d9a4e1bd5049218d6 +3660,c24afda088bacdcc7762433710ffcc91 +3661,c0cdc6c1c02686c6cf7bbb0841e26646 +3662,f6f3d19383db54d245286ef1f3ab57cc +3663,a95361c4b97817f6a8325b0632412797 +3664,229bc8ecc7d3f58457d02260cd563724 +3665,0e7c4cf0cc60954433fe4f03a60f3ab7 +3666,666e61be1f012e70167c17e1dab487dc +3667,93a71ffb09f0d6082db90968dc136624 +3668,5d0de05a0ae028794bba1015f49593ae +3669,1f4066984b188705bf10d14f422d9b25 +3670,86f6964f6842f8b0e39731849ae5cf3c +3671,4a6997b0c01cd3461c1df4a5dabce2d1 +3672,460748a3154cced5d803e79c4338b7b3 +3673,87714cd4467613024d18e52db7ccbeb3 +3674,acf003ed8f27ca125c743012e42176d6 +3675,f01d662155a362e537dcb85aa1028547 +3676,6eee64431bf1fcec81c1940c477f49ca +3677,c6a4c39ff9b3b3723bc25c3d06e9dc5d +3678,2fce65b5a24f1a6b0b3f0beb48f23069 +3679,356361628056c99dede11863d4c94f2b +3680,02782f5b726a90e4426966d4492860c9 +3681,a34aaf82f23c32ed6611fa84cde833f6 +3682,0c28ea30276650d914d6614afff0e735 +3683,aa54274c7407f836759c4da3bd1360a5 +3684,abb2baaa3f9f4f4c3f7e4407167737b9 +3685,b3cd089ddefeec79d8a21dea944a312e +3686,739a3745fac5963f8fd1f9d4caf9ab4c +3687,8c5b301af66628dedac4d101b903acfb +3688,680ec977abe8c85cf97094513429be1c +3689,720ea0c92532427f1f150a2bdab05318 +3690,adbcb78f7680b3ce92aaa6f5db11a4f4 +3691,9170902b622c8cfd5ac7ec5e5dbff229 +3692,097214490698a8890715be5746d9eac9 +3693,d36585840fbbf303a437bcf5770d1086 +3694,2ceeb9ecb00f0128b36aab4accfd1c17 +3695,a173b94a0f45b44d65af18ca49838234 +3696,1c996aa7827deadb9bc3e4c1595217d7 +3697,6edb169f31c0e13aac6d9c0122a33d89 +3698,23e29dfad667fe589b2fcc81d74acf8e +3699,9546cfc74785571a2e3def89d82da120 +3700,7a327e08fc4474c5129f302d2d2f7cad +3701,e01953f5e60a318be84715be877b4885 +3702,a40b18f81f6b5531c916d2a9fe5f65f9 +3703,0cb38f3db57b23ab120d360c10fd8dba +3704,898ab152ce39cf9a29b73155de3fb5fe +3705,058bfb0684270d3fca5eeaff6024d8b1 +3706,88d0376368d4f69fc6f68cab1117d70d +3707,e64e197bf3e8c039e76b1e6d09d4eb9f +3708,dccc4c283e11cdd8e82d9da741794b9e +3709,ddfe53e0b3c48cf837da45cdd101c5e3 +3710,78de405a3c85efb01aed5783d4fc2879 +3711,2b670dc2b25c17b4b196ec4185de6812 +3712,537cac33bb73e0df4bcf4c4b4d6a602c +3713,33bc0b31f50d1ca2c2fca3d5052d4e3f +3714,97ecf38f3bf8f1ce55232ecd6e476dd6 +3715,ce32f1bd131899f14508aa986408f3dc +3716,6ab654d88a7a87a700868fb364d653f8 +3717,e228abfd53d2c813eb9bc5a2a9ed5b9e +3718,fffb56d8dc33c845abffb091691f2ba2 +3719,7087c98bbf9bf1a0fd9953c549d5b1f3 +3720,2b553b2d2b6ca40e1c758896c88a6f38 +3721,534e64a853133bb55f744333c84ecb0d +3722,edd6a194e46ccb4ec38c9fd20a6bd344 +3723,fc503fde2c41ff675eff45f1c5b239f1 +3724,0c4831943c981078d4439bc2efa99c69 +3725,50b1e8a1d04cd8913197bdd36b5bf7e4 +3726,94dea9259b45b0154f8e805d750d7c44 +3727,0f3874474e7d06cc24c09269f67f56eb +3728,e6b8f8822885811d99c375e1e6ca2384 +3729,8c2b7c7c946365c928eda79472ef03e2 +3730,6ec0327ec988c7820e77f9bbcfe22270 +3731,531bace50906b71358ad808a11081586 +3732,ab2754e64d644545aab90597de58e8dc +3733,7b5836f2f3668a5bd1f1fdd9b6c37252 +3734,84d737eb1eed3dab8b38abc0173a5532 +3735,8bab6dd2483e235c0283a998d3ccf292 +3736,98ae4a429d90722dc3fbce9e203f3027 +3737,d3cf8f9d5d2bc1f3d93c5efee22314a2 +3738,92c1bf338417244264366c27c0c12519 +3739,ce6980e2023b093d17781a274ccb6bf4 +3740,b4f38c9e370627a5750fe1be5c128150 +3741,9d1907a754754886335446e326e95c56 +3742,053e6d54a9c18781dd853e0c0e22a0dc +3743,0d0e55f61dc3189bc6cc706dcd7f91ee +3744,4c861addc00b008928b421471b681405 +3745,8c7c358e56b63cd0b8fa8abdb80f1479 +3746,42e026080e2aea5132e68b24c04f97c0 +3747,26677ab4fc3c9b469ee3822617a1151e +3748,558038df908e413ca00a32652c7f84b9 +3749,fed207b91bca7035e8b64ffc2d244d58 +3750,4e4bc374ca5d824c81ec68ddbf3cbed2 +3751,f9de877b58679471f7a0399b699366cf +3752,a8d6fd4c314ab91788b0871c6b324bc9 +3753,01d44abfd3e63e8c22ab1890d8761e9b +3754,6f9684d51d476d955800227d7f43928a +3755,078a1863828f6bb663619d227a7cb526 +3756,b3c4fffbe499149cbf003bbb380b9be2 +3757,511b61b9c442911ccede34af3685b47d +3758,890a3e902e38b918863f9ba61f7c642d +3759,26945e2fea9025eb7bb39d50b89dceb4 +3760,14800b17e2eab2e29f8622a960133939 +3761,c3a658ea05f16d5acde5131f4ecebae4 +3762,e80ae3073944f4e1a34602a6ec9696e7 +3763,8b53cd1fa0ce2e6017a46071b4bfa21d +3764,1cfe5e8593719839dadc646f192ca294 +3765,61863d70c99f383e7b16615e4d6805cc +3766,9820ba57dcd5a05873d33e12ddef5c35 +3767,7230fc2b0188cd2d696e86b8cd388a6a +3768,57e0b368d52c9f797d32d84ddb751454 +3769,9ec4a1c27e34afd921ef8b9a053d4a94 +3770,62d5b34c062b320597e3e837b6abac66 +3771,f5883a6a3de911603b80d8231c6db32b +3772,35acd071119f678ff26cc3d9c9c60c04 +3773,505ae94cc6212327c8727031b74fdf1b +3774,a4b01a6d4770dfa971d8328ece0333e9 +3775,e859043a3e6d92ee688f1d7ff47b341e +3776,be984c4bf0cbb2fae14a1e88024d6acc +3777,835fbacaad8e74c74dc0e048c5605faf +3778,1aa85c4c9bd80c049b6029d3d265cf30 +3779,87f0aba339e9c269b1c560520b18964c +3780,d890d546eac8de241771ee78388f8e60 +3781,5244772758162704d5f99cfe246bf840 +3782,5512f3f27f066280944ec6d137a92659 +3783,231aec23250190bc50905d8764e648ae +3784,b85f552aa5e27762e534127f6c5fa486 +3785,d80f44185a514d77c1de38ec3a7ea3f3 +3786,17c999457a85c7b8420767acff00cb69 +3787,c5b8ddd6c79bf5065f2c9ca6e5315fb2 +3788,0724a73b61122fe9e2b7821bdb1464c2 +3789,75256c7f4b5365d50ff337950eb0de59 +3790,f10a3e2c0d62a6e12b1ad2ee1d502561 +3791,bf7e2811c2443a3e43ba7409e2d4d455 +3792,a5ed67ae2b1de9ea50943ff6f7620b57 +3793,9a6c09389185f0aeaf28789508add966 +3794,c7d8b6bfe3af5858d41d523051eea272 +3795,d44ded03182d2e60fd3227a05377f951 +3796,97a631c9a0c44758ce1781289949289c +3797,e69d2d7acf54e99b877920ad79876a3c +3798,887861e7083d255ce408fe9d2550b01c +3799,acb9d7a50ae668b4a56831a9bb4e0bae +3800,d7419ec8abb9a3a7dfa7689814903e5c +3801,ba9efc9d2a15386cd2e6160711469b2d +3802,1824f2b3d685e78b64505ad79d175f41 +3803,dea5b0c207fa7317016c6d7466f96ce1 +3804,364562f783c461028ce21036b04b8694 +3805,6176c315c5f1898a61200c6b2e719531 +3806,560ef0bf4d9707492292f2cbfc21dae3 +3807,92a99caf68d95f6e4d698afa8b18e837 +3808,7cbebe9dbee7e4380241031b807ca64c +3809,6994859bd0a9ec09eac7251122a54269 +3810,9606292c5aee68d1bbff756ca6151a6a +3811,fd5a0b70d20bfe8b2bd0e26b2c311d83 +3812,33f739363bb057fb1647d9ee18b908c4 +3813,3adff4f594413d95791e16bca49e27bd +3814,d8c896d91a5fb62a0dd43e43b027972e +3815,2b4972e29d57e30ca083ef555d609329 +3816,600ccdafa1e1e486257b3f66bae96627 +3817,ad82177f044de36c775966da50496bac +3818,bfea9c23e8ea79fba3e630463e2d98f2 +3819,db954c7d8fe81de49f1d7266ad7cd04e +3820,7633a042693c9033253a3f52d65d73a2 +3821,873e309d4fb047cb240ebb501070ca06 +3822,b3cd05602652086287d694d4dcdb487c +3823,8bacf924bf37efeaad53bad3375e703b +3824,fb29adf5807d002b1e6c4f5e924be65a +3825,af20441a4c7f37ff8fa36a7074cd5b33 +3826,9021254e6ec5d06ca63ac48cad5f639b +3827,97b8a95d6bda6fdf2d97c3f902133b85 +3828,488b10fa1788ec6fde7903ac3947e5ce +3829,51ec52dcda3d64c460a988bfc42c01a7 +3830,283d05343e357a262add1f9c533dadc3 +3831,12867dbbf90a86f98a2cf075cf5faddb +3832,8e74e2e2c059a26142c1bfc0f9e9abe8 +3833,b886dce41b94488bc8a4774e9781b598 +3834,816ac01ce5f4a92621d5c00f9c386d75 +3835,bff7ef51d49352295fa0dac507e87221 +3836,ecd36c779c25f4a2b4dca46a99174659 +3837,6cfa9cc4f4ad616373c2a96b4322bc19 +3838,4dfe7bcb13a68dde24dc1f23ae64120d +3839,9833c5ec9ed34abb75f00a226b548b49 +3840,14e1d3fa65d23b58a1b97280ef26aca3 +3841,f81ba6af9be6d60ee0c387746d362642 +3842,eab7972c4e2d6ae45a429ed378201ea4 +3843,1425f0a90619789d4546c074b5e0be5b +3844,62c3514cac48e2ab846dd727bec9a524 +3845,99b8d2a8d371f3c03e7bcd344668ec5c +3846,86dbe2c893dab388a225a18f3e999ecf +3847,83ab583a237b15404417ca3c50221f40 +3848,f54239e1093faf7af1323793f484a678 +3849,faf2ed6d1665f09ac920dad58181252c +3850,3a5604a916ed0a7daf0d502b24eae634 +3851,4223bd89e66b39444980a3c6cc5ab6fe +3852,8c3ea6fd08284c445d190f3793e84f11 +3853,e58b61301993d376c3870747156b3112 +3854,676cbda49b7bbd7175a0d501826e8978 +3855,36517c170b17afcb154051d782950631 +3856,659578cd2b54b826441090eb6926df35 +3857,66a9e920b0fdc1169541cf922f5ef464 +3858,6884a3ab61921612f94ecd0cc5e33fee +3859,0b3b717204519d43da934b6ba95b43bd +3860,ae83c77ec646ad72b1b834142ef6b1d9 +3861,4c232e889ef2645a2835655660de53ae +3862,b12b0ccc1c082b54732625bb906ce80c +3863,cddb08683a1514d38116808853f413b8 +3864,a1325fca3645278fb16468a2cbfbcc9f +3865,c3713a0462826d421df22e951cac992e +3866,7d1cdc44b184e439e8e58371abcd5126 +3867,41c99147266bd5c26cef1f8ecd7fc7f2 +3868,765cfdd73bb3f98049e6117f2e084338 +3869,6648cc030517a20b98a5d1197125dabb +3870,f00b7de35a4a5a70b2505208c575b022 +3871,2d8caad0872126d7e257139a1b56a501 +3872,6627dc01b5bf559812a67e9b0eabab6b +3873,e61e9aae6afe6df522b78801f48ee0ef +3874,21545a7df134fe5c1bb5331b21fd7a0f +3875,524b7182fcfac4db85cc69e4bd49dc7c +3876,c1a30e279b4badd94ac0c89e99a2d6e6 +3877,33365a3e2ddadf685f52777e5c872e8a +3878,df64dc16b4610728a28642448fb5c013 +3879,68af3ed6315d5bfbb7abc78cfc7404ac +3880,7c57253394b39618b5b6b8428558b930 +3881,c7469350753e48715223b9f143483721 +3882,2a24d926376a14563076b497390e851d +3883,a51de23781d1147c20d1a3d82da7b8c0 +3884,acb23831462c2542c9f4423c4da03179 +3885,e0e8aa4ae3ef9603a829f29a6c8fea64 +3886,4e7ba16f862b606246310e81664ab895 +3887,db6f29cda2ea6bf4e58a1f019ddfdb12 +3888,9651b1971cae624ff2b90a082ff54383 +3889,5f9eb8755eab52600e82e0194b5f48ac +3890,ebdb51dc9b4647c0c315125c530101ac +3891,3a55e2575622962a29e4227bd4bdc8d1 +3892,8a5ea6cf5cad1d853cb300363419bc3d +3893,82fe5f3ccc0158545726ec847ece8f82 +3894,1eefe9a38b7d8c1aaf92f2aa9b355be3 +3895,12e13a1f9702c166a28658ee811dc15e +3896,e092a0e95f1dc6b46d6c5bcd73038ddc +3897,9726d5e9361d309420bfa6b0fdee1170 +3898,687e1f39a0065b0027bd480621a0019c +3899,7d15835bb725d4726a1d27e4f6494ae2 +3900,6dd4928b2cac9fe50c14414ab5bc8006 +3901,497c7648c3f6f3eae460cd3f205ee2bb +3902,8a5e84f91f6e285b08acd53704593963 +3903,66870635c651583cce3b774474d5ec4f +3904,929af630a6ee6834fe11133e5f1dd42b +3905,9dd869ec890be9b12811f54a8461f04d +3906,63b66344fce018ddcb06279ee2a3977c +3907,a8d3f9a34facc624efa0becb184c716c +3908,fe5bfb19e16541b8b7ddf912f5692e3d +3909,431182a8832e54bf0a8b93b1f78742f6 +3910,c7475b2ab9bbb042fe65614f7f6c9c71 +3911,f241362ce7e159698a4797d0ba77cb84 +3912,561fa6e176967766bdb459167abf1f56 +3913,27535394b43416bacf4cd61408f93e84 +3914,12414ca94671d7f084027eb44399781f +3915,6249a0434f2ac2a7a5481ba3d7dfb328 +3916,f9146ecaf234f8db4ffa307aef0a95ac +3917,55e77c9441123003a511ed3b52731257 +3918,8d434a0182d720c648441094ff94d542 +3919,34ce05d55af35b30ecccb401d9ffe358 +3920,a198a77ef387c9a41658499a412c242c +3921,1827bc35665b310f602c646c15f2661e +3922,c48c229d8a86f532e11eb412a0cf17b5 +3923,d90db5a0955f73b97f5fb0e732ee634e +3924,883221d59dedbb66c7cd2110f6970121 +3925,f321e3ba0bd044a816e1468c1f04aa9c +3926,25094a9a51f030621724281a3c9a58e9 +3927,e19a3c64738988e7a6e8b894e1874fe5 +3928,d46dfa08ae2a8630ca7c1437f5d662e7 +3929,807d08126b772645a9f03aa91478ffed +3930,649b1d0026f822a0aa86d6051e488638 +3931,724e013385de4413c942c6aed3debda6 +3932,df3c85db19fc26ddff7074f480911b02 +3933,0a84d5207d70a18f28de31c240a5d8aa +3934,e66739a04a32fd98d97280ca74eec414 +3935,2ff3b9602b9fa702e14551965c873911 +3936,20083a3cc8a1d4d971875f152f1cb39f +3937,fe68be11dff913af5d271ca9d77fdb41 +3938,98172e3e50b159b655744f881a93c7a5 +3939,2de620df7acc822a1891da08c916b885 +3940,f2e1d09583ee03c753cb0b527bc64df9 +3941,3a48742a549c8108e1637e69bd941608 +3942,2ce70b1de0655af72de3915740b1d5ce +3943,fadef0c400e337c414734086b3c782f0 +3944,fb2779d0631a752a50434589642c759a +3945,3d153c9b2ce8fd1c95e20469721688f4 +3946,d8bbd13e1c801d0cc09ea44cec8badbb +3947,9bf74ee3956fe81732921704c2f0272e +3948,f390e933bcef4060d1769b38c5e0ff50 +3949,b6b2935062898675d0b7879edfc8edb5 +3950,cf665603f870d1d1d64c7ca6a89d5a60 +3951,118717ef19f3c36e623a6afab4037adc +3952,e2297d829efef054a2c2ea7712e5b3f9 +3953,b957344ec22bf69ffcd35f0321256a4a +3954,769c3f71db7a5469bbf8e452defcfb6d +3955,f7c9d8dc5fa8ea7145bb9992321bbf8d +3956,61b90f7035c52831eec118b2329dba7f +3957,5dd3430b1f5621cfd036179a0cb1df76 +3958,fcd54f7ee84476bf305401e084936c8c +3959,6fa6ab013321c08d8c9d916e21385ffb +3960,0903426c3407054347f5bbfe95bc8d0b +3961,4b3bcf6dd2219e0a85a904028f12ef58 +3962,bad3e66d7c7828db785446bdbfc3b9e3 +3963,6c322355088226faff5f5a0dfb86a470 +3964,c53f45747ea497be70e7e4036852f65c +3965,99b08707469575917ab25fde761999b4 +3966,1879cafe3ef180673806cb23d4372bc5 +3967,b30978fc5ddfd89e8e62f4524d92495c +3968,21af0258638b8928b7e5756e43ac20c8 +3969,559d8c927325efe473156ac8fb139cc0 +3970,2840cb75a8515b84336e564318f1a403 +3971,a166ff46dee13e07493a04f5e1417417 +3972,88f69aa0f1722b083e94ed3267d41de0 +3973,1e7d33dc900cb35bdef77c7d5b78ef4b +3974,7ccf56931100cdebc69c3611c3b20746 +3975,fca00007cd29df99dc2f97bafdbb5070 +3976,69db92caccbaa2e7186d34fb47134f49 +3977,83b8c3bf39762b10f830471f8f2dc1d3 +3978,ca98c472f78f9cc4ea96834b054abd80 +3979,34e221a9d3d95f284f426eaa19bc85cf +3980,4bc9380581e5790d7bd3b3b69355987a +3981,62140d6aa75fa27412be4d1a98c4ae14 +3982,11557f514bfa34d95973fee84a4819c0 +3983,5421f93cd012d80e5d453dd35a36a483 +3984,d8439348de83934bd1484faf21430a3c +3985,a60182bfb41063f29b669d8145a1fbe3 +3986,16b4cf8786c1ae21df4e6ff0bf25a911 +3987,0cb4f19de5640fe2e6a951429dac2ab6 +3988,55ab50d0532eec405b261ee2234f658c +3989,12130bbfed3a8163eb71e916bc39c044 +3990,e5f2df9c61a774e82b97e0b9ded909e7 +3991,f53ae1a861e9880a88442dbfc1b07657 +3992,74610918cb8533462edf564c6b73fbe1 +3993,970f46e1923f79d20ef783aca1ccd513 +3994,be847d7a8c5f015396d823761b4771b1 +3995,f3575395beceb6ad393fc52093f23608 +3996,2d1e6bdc83c4a6b534eed40ecd89e33e +3997,e3ae7e5a56516ecd386f0e191680dc6e +3998,d88007ab23031c87116b810ed8bcf71b +3999,0fb0558ffffad8e4c85b18aacc9eba3d +4000,94066c1cf969b0b4ef83c63e8c87ad3c +4001,b6f58113afe585368a09af6b9c9ba4b1 +4002,19a7067fd48912a298eadcb64d709b96 +4003,e1ac5c01841eff78da4d3d322d0225df +4004,f8cb0b21ec98585fc3e34e4aec06b251 +4005,9831ad9a1ebe3269ab6da0d0fd988e88 +4006,b1c5a19b86e4d49b239900e95d872a5c +4007,5caecae11eafc52c68c6d2290d072a2c +4008,3a1d5f4b793857b95f8c29d8d75a6a76 +4009,baf4519970edaebd210026f763b24c39 +4010,a2316b9662d2ea3833df3b4382cbde66 +4011,eef46234ca55193934497078582ed946 +4012,374122fac33058bb8c9675db6d2f81e4 +4013,4e9e8c95b41b934d872ae5f60147cb0d +4014,f1bdcee3e5311bad5cbb4137cf2fa2b6 +4015,facd66366087ad81a52ff89e03c82297 +4016,64627529274adb8b8113a4678dbe732c +4017,4ee6e1fb7539eb9127c17a7491709770 +4018,2dbcd4999b9501deddb1c2738751e31b +4019,4797361c9f62111fdd612f32ee6f1a92 +4020,2276e50d48587733b6d7e269c99c3685 +4021,f2ea1747b298e9b6eb9b3f246a66d9fe +4022,6a47903def884a129ffe38ef95047475 +4023,873884d7b4b984d964b19a7c4a46a10f +4024,7a0cabdf1ab824a8e3f3bde5ce96b2e3 +4025,876a7f771c8971aac26c595ab8079ced +4026,03a12ae95cbd4e828790313f4c1df63e +4027,3abf8a567d7b2a16a6477506fb26e570 +4028,c64f74363d20bbb7e4c084dfacd88c83 +4029,95478b468058a0e1877fb042bb6f2884 +4030,9e09d3e0d4daae27f4c779604ea67527 +4031,0de17c9b411b96b20be015bd8cdcce5d +4032,493f9384bfe3becf0a345f518c21dd2f +4033,6c71974bf467d6ef485008c98554be8c +4034,2222835ec2ffdef61e39a911da9bf232 +4035,88f13e813e4325fae48ca9dbc86bc1c7 +4036,d851dd5d455a46c6a96f1647478b6672 +4037,f91fa65039e352ea8170646360dd5ecc +4038,d87292d91c755dd37b6c1498026a9997 +4039,d63f343c9366865d51db179c91705b38 +4040,e1321be50f5c74e51560f1a29cdea204 +4041,cbfa58b0b9512c3d7db1ba7f33a39dc8 +4042,34fb516a76656a58a9bcf1b60ac6599d +4043,607ba9ff7987d862a21d7b2fe4c8e609 +4044,b9b6302dbbf40708d46990d23ab85568 +4045,26e20786f6b6dc33257a1e31fcc2ee20 +4046,e4c8712d4630e7fbbe7933b2f22ae461 +4047,b182606ce2aaaefee621f40b7b7bbbf4 +4048,c919286729709d3365d0c298d119d768 +4049,da4aa928fd69842c9486780715ec5475 +4050,0bb48a15b5dc56ef1672c127945220e0 +4051,cc3229396e319b8e8b07d67c52118b01 +4052,db8c84bbbfa91ab4c88ccc547355bb3f +4053,3e7a7a63f17a593baded24d5cdace938 +4054,85f5ee458c1be8777cd69a6b024d0c2c +4055,adc3e3e025e82c62dc40625c017ba828 +4056,991736fdf8e18406ecd5c4a0d655708c +4057,89fd3ad00e8f3777b4e88605f3aeadcb +4058,a68bfb69ca35fc6a326e6a41fc4b589d +4059,e6f96726aa6e36037a4056c13491f0ae +4060,3c463257a669bcf42df08e3236188fcd +4061,a49f7943d326b75a594d4d16a2730697 +4062,64cce6f01d83e78313137856e33d6726 +4063,3bad89f7c2e7c9dba57bd9f87f14f09b +4064,b20ea0b44b48eb9f76652f35f0b87966 +4065,aae1ac508cdaa849f18d91ca192726af +4066,113bf1be26747493de26422ed54d48a0 +4067,011b7e794e416483a7d2fdb7b40424b6 +4068,6550780f9b70dc027773fc181e5c1e66 +4069,e440f3eff85e001f0f69c0a4b00bce9c +4070,7acfec34d01e1649a4051c6d9d5bf98a +4071,5b41377c2aa24ee2ec1e4a4a1d8ed6b6 +4072,e8ecdab23a3af7daae01ff2c2afcb17b +4073,7c09eb864b2a6ff8ab1553cc15d384fb +4074,1b4b271fad9be031a83cdc1a30eae687 +4075,a14d21ccc85fe86ef2f8b31a2b8304e1 +4076,b9878bdf976dcf48684733004f0e1870 +4077,04fe956daf20bcbce96be756c5c96287 +4078,2c9a0b6caac5957582d01d0de133055c +4079,b4bb0671eb91ebaca815ed6fafd6d0d3 +4080,3209d01253c689bdc273b92e686a7f5a +4081,3521856bd690421db265c2dc6e25ee33 +4082,99903d8c2be3c41c735e72b5afdad1c1 +4083,46812265164ea1c6fd7fd4ab02f1c772 +4084,e21c438d72c2ac26ab57e6d19c8ae378 +4085,7b6a51f52c4d268a278b08c1dd43a8b3 +4086,c36441aa62e4ec76fba6216e6da1057d +4087,a27ca9c87fe3f445908d6d86634e691b +4088,a3bcd2334571eec0ca082ee22a83eb7a +4089,e658bf587159693e1f6ae21a7f0b83f0 +4090,1fe1f0d85b2618e5e58178aeec02533f +4091,8d2007bb48f052160d9b89e99fcaa417 +4092,bb373430e9eeba5b4fddea9d3a51c5e4 +4093,d7a384525c93673268881fd90e1ef2a4 +4094,851f8e62754d6b0c3d2ac44ce26a5434 +4095,cb5e2b94c18864b6da440c157b08d277 +4096,4cfa81b8134fe81c7841f956ed8faefc +4097,6f9b9ca6b93490d19752f783bb0ea480 +4098,1e061b562a2ea9c425b0c77e5510f96b +4099,95d932eb1e565c40c23808ff30372505 +4100,a994ad3561a42a040a19fe556b844036 +4101,c446609a8e1876841b7319a3403978ba +4102,5a2810c7770c8f54a21c938e437af4de +4103,fdc8bf4557524ca18a6dd473c2b3f35e +4104,7cff36476d44b3abf73b2d29cdae9109 +4105,5d6640f0d507b9db084f827e9be749e8 +4106,f7eb84e9a5ed7a94ecb3faf98452caca +4107,6a9901f43d81246b3701e20c5a775415 +4108,c6bdd9c0f23893e7e5e0c14087d9875a +4109,f0363c6dea75cc2707bb498abe33b360 +4110,2663caaec7267031ac27f6ea7f223140 +4111,7d58276c269f7255fb8663854f03332b +4112,1087839eb408ff3fcb55841c50952add +4113,87bcce58e104251cf52c120d4ce53dd0 +4114,7938a6721eeff42e9bb1a9b6ec69c474 +4115,2b2430e0c4f929bc24df92b1b395a161 +4116,c907e8a19dbdfe195ff95073dfd1cc5e +4117,5a427c5c22203929b4d02fb34c4ac1eb +4118,9a562b92ef45a5eef801eb5a96edd441 +4119,c5e6fffdf49913877f11a5bf785e49eb +4120,2e3a106ad3f8284d4e0f54014bf4db16 +4121,908734470c7f48735fe883a60a302ee3 +4122,3610425de00ee881ba0c8d185a51b55e +4123,5e8e85f1deb84675c0f8be6bcd5ef6b8 +4124,fce861660172f76c95632a9eb0115c5b +4125,4e48ade9cfeff7f14e6a567cb18657cd +4126,b8ead534fe4788ce1f0ee899973b4574 +4127,7bb9f849d08e21be2dc3f1c085952e79 +4128,e2e2282cadc177ebfb23f216efc5f330 +4129,e143611208952ec003a61438d5b923fa +4130,826523418ee65280ac9de4d8384b1f35 +4131,dc81a21eb37a5b73615b6302b5116b03 +4132,19745f3f5a1221dcd56ea2c2f801119b +4133,d5e46c3159b100d75fa642fc8000523e +4134,2783097296c95abcd3fa9ab188c21f76 +4135,24376d7cde9cd7f2e132fe11c041ba8d +4136,161fc7bb02f8c8413eddbce42f0588d5 +4137,141d42127a8a73d27dc8dc9031c69e90 +4138,8ff5e7be4caf7eefd1fd9321bbb2b6c8 +4139,de7b4a16a93fda08a4b5c9aa281a24ba +4140,f163f79bd98d74ac7a83d21fed44a646 +4141,47c0ee4d3be4eced10d84b9134c696e8 +4142,a9445a2f6a6333db5cea9252fdd97da1 +4143,7caaac613646f6a54708b4abb1bb79ad +4144,983cf4c104b21ab467ecec75d69e2be0 +4145,c2a6cb73b3c8e8cfe87ffd41c1747adf +4146,71523dad97366d05b7aefea7feabd667 +4147,127351437052389ee9b37b8b7f22d437 +4148,4571f4bbfaa85d0dd0a445348d10e305 +4149,991d1fcd4deee82011b5dc24183050b1 +4150,24ccd94161cdabdef847977b5d4122bc +4151,1f1b5c5f57cf6db110c5c70f3907790f +4152,9663d239370694f968065ba51c9f8efc +4153,b79e81d8e02300cd5cc46425cec4687f +4154,c05363e39656b432aa2542a6077b3e3d +4155,6a9a8ab2c795bdd00f158940311450b1 +4156,0aa5ddb1bf67a770383a73ac3d2cf244 +4157,542dc073b40ca660a6ec41c37a7bc749 +4158,2f42c6138f4aa8d8e83459b6d410ac0e +4159,5f6bb28330a388e5e4f8c93c180898c4 +4160,bc9fe3ce4751175039b8174e1ff2ea93 +4161,453a3753d045c808a1b98791cf910c23 +4162,8faf9c0ecefd040c43651df6ca0f81f7 +4163,ae29aab0e5f5712fa9b24474462e3732 +4164,0c6a94cdf8900ccfdceede68a393084c +4165,5bd6495783831dbf1521a627b0096e6a +4166,1620bc2dc2737b0b278bab6bf8ee9c23 +4167,9c3aa571ecc5f905e9fb28e65d28a601 +4168,bf718814a5a90ac325b6eee14d651e95 +4169,d163a231a25f56a4d7c2a34460d9e2c7 +4170,dff1a8f63151404f1a9dea83d2f315ca +4171,d866018d2390ff8e3ed8ed03bbb83760 +4172,81a97bbb25228970a692b3112864d20e +4173,593b85a7101f4134f43e91f63d24a61a +4174,7e50208b992c7b3b650d0beb345998a5 +4175,1578ea764d11b08b9e6159205ae3800e +4176,912898ec7fd463e09fcf02e4c2d9ee09 +4177,06f95c8ce23c52ddb84f0f23a860762e +4178,89a5eddfe1a39becf991795d02a80d27 +4179,4419542175694062b27b618d67ad62d1 +4180,16e2086876733eaf385c304d6a4b38d3 +4181,155db7579533157f02e1c3ecf64bd3a0 +4182,869b58fabd80d5181736b33ae8ae01b8 +4183,7a5d3a213d86f0f8c618d6c6cd11b057 +4184,d62be2c4f46bbd91cd1d3d05b1a26109 +4185,d25c87edfd57191c2f7eaebedc49f31e +4186,f517be14004aa40120a1e03fa4564419 +4187,41703fc012cc3cfadca3b99eb140a473 +4188,aae583d585cb173a190c16a3c7c0dffb +4189,dd1689faaa8d08c5bf839e3790eb124b +4190,67e48cb617b7982969308de96e062154 +4191,136ee7658a67e87a21537c8793d72ff3 +4192,82e299e8b667c4c889234e97cc0d9875 +4193,77c92d4f1b6260ad66c2d04a7e06dfc6 +4194,345e616de9e5dc66c6847bd24cbe776c +4195,b0fffd26b26220714912ea3185b5e513 +4196,af41a6fe86d252cb0fc6e192196d679a +4197,9cf3dc61cf48b310f6f576e0f583fa7b +4198,8afed5bf4216b9e47f02f3f542a947fc +4199,d0384b504b80c2203bec84e55d423cda +4200,67b9d55e0ed4ea3b6425bcfe531a6792 +4201,9356ed71fafa484772d1c06cf6ff2207 +4202,eca047c1135323c1e40be10a51565259 +4203,311da53ae6f6c05bd395814ae49a818b +4204,afaad2c1c89fdf8221e7fa641aba9615 +4205,07c5748cd4ebfcfcec59b2e1b4174521 +4206,66b1b8f206f2b5e640763d24133b0f1e +4207,d8669b56ed90f314198e0bd994368b6d +4208,9fd14ad772e9d0d0bd2bdceb25f4b27f +4209,eb00d9109e4d19c146324c6f226092c1 +4210,8b097b4501b7eb4e4ad48f868910cf2d +4211,6a1acac0fabbbcfd18c1cc34e4f093ba +4212,f5a5ba897a7afb67f0deae0c629807e0 +4213,afb541d799dfc92362bfbaa8d331d6f4 +4214,c4ae275848b81e2045293e21edcb972b +4215,04cf17bb21659335c836fbed0c4134c8 +4216,4955d9a540753ddd803af8b9dff0d955 +4217,945ac969e010f2b8dd17c0c6b0d9f262 +4218,999e9f3e35257bd3bdde070cea9c42fc +4219,02e9ef6e62fab88401b9805c7eb4f65c +4220,8866d92f3aca157467e086790f394f27 +4221,843b5e7575ea0c5362d378e1e377b11a +4222,15029b0a9e024074aedd1f1efb965520 +4223,d6bab7e10171596df83cc1199fbff558 +4224,37759192cd578967fc28ba0d87c75b8c +4225,2d917e2976ac1400dca01c2672c707d1 +4226,466fe55741427cdafa3f65c78b15154d +4227,68f6e99578c509c1e62fcdcaaab4c04b +4228,6a307a723d257ba4b77acfc2f20f2fc4 +4229,ab52480bf45a917840907e904271bc68 +4230,cb58a74d700e21bb21a80e4789a547b5 +4231,0cf52ca2808eb104d6755748ae08cdc2 +4232,b80d4b690b0db8af5612928cdb7d85d1 +4233,e008ac5d28c7a7accdd6d9b135e74197 +4234,81e4d6f5babb92bae7001efcc07cbf79 +4235,c274dfba09bbffb7dc21b584484f96e9 +4236,bb54bf9ea039a5df158378d08be1068e +4237,476b7b1f1922ae3bf71d8cc7bcf0f73d +4238,05cc7834f312f58e2a14f9fd713171b9 +4239,27cbcff1eff42dd4d7ed02d3e4899a8e +4240,7667b82d2164c3fd8db3714d8dac3f27 +4241,e71b00e8e6c979bba51ccb9fb263c614 +4242,9994e4a02a444d91b4732a2648d950b6 +4243,04179f4434dc1e81140cf32e352bbc1c +4244,d97da905b38fc32b5170fc734ea1a3cf +4245,e72d677a74617feeb5ade8e7cffc0674 +4246,381c55e2c64293c8bd770a1d1fe42827 +4247,a786c3cd3454bc135a115e3e895c69d0 +4248,1375557d932810795599cdd1e3088aaa +4249,6877c402c51aa04e0656add8a511b717 +4250,e333d0ba02decba243a1e74a01d96f47 +4251,001806c5ba363db2a9f13ce3bbc7d23d +4252,db1b975d38c39b00300605972413a046 +4253,edbd003085ab7777ed233a9519ccec95 +4254,8ea419212c7e15d3a608be0edb048c35 +4255,d7579b1fb428a58a7eca41ea6820dc70 +4256,c8f66979d69e1e581607fb25fd2042e0 +4257,86006868f639e50a3358524789c0a91c +4258,1499a7b89ec62f4ee0209df9f1fe6a5d +4259,5cb7eb225782046677cd0b58b5cad16b +4260,03b2c06c23fe9d0a5225b9af32315295 +4261,f1c06a96e422c67984dd79e44eabdf1a +4262,9ae89e7d32db96866151ff074af283ab +4263,23634518628cef8bedca47b8bfb12235 +4264,769e2e303994e8e5d5796c91ddd57f9e +4265,e75fc809abd4755fe55dc13178b799bd +4266,cc5687a998b39241d74c7c198b36b83d +4267,61eff7cceba03dd02828cf74e2c42281 +4268,fce7742bfe0d83528514ec172bf78192 +4269,5acf760786b1c65e06a3c4916147458d +4270,b9c7576e0339eb5ba59bc2d380a01a20 +4271,e4cf83cebe67846ed9f8d8c34fb6d35d +4272,a7a927fb279f9bcefee654099ff505ee +4273,9647fe37463a4d49d52171dbb925ed7e +4274,6332d32886bcb884f369ab76a2f52358 +4275,5100d5cd52112345225de1aa415f8d34 +4276,441a0ee743b883d65d8d629b8fd20800 +4277,16e62a6a49f3a8f0ce8068e5c70dca80 +4278,15914eda2c316c34c1614a651d53ad3c +4279,eb7a046e09fd2f2db77e02a0094ea004 +4280,b513e9cff48cfaf1ec609e4f4d8d637f +4281,fc5567b9301d2aeeb998e2d5500f606b +4282,94193cbcbb48c9ef8cafd4a71732d89f +4283,ff5da7ad3a121cb759a95c5f64dadf10 +4284,041d3900705cd9b37cca59495e9b8259 +4285,b9432b2728e1d6823f8594c8312593d4 +4286,f7dcf8f93066f293d177fd8b538e96cd +4287,ecfb0e4d859c1c56fdf60566a1576794 +4288,d7896dd30785b81dbb1bfdd5c84c5f04 +4289,ccccd9239e1e11a2f74b8a61c4496291 +4290,4e224d90063f64388d8887207993359e +4291,601499f875b9e1af9176bdc79a67e02e +4292,b3015d7ce2cb21d805fb20b7bc391a4e +4293,58aca052e8682b5ceb1ac61b78b17ecd +4294,8319469e5d57bc8a207aec282c6b9eb9 +4295,52ce2f3574d091653d7420fa4d736b61 +4296,434f981d881cf509d7c8140ee57b5093 +4297,b96fcfc7597b9a1868796434f5d63a5a +4298,3bd87f37e08e4a98e0e0ae64e762b0d5 +4299,43f05f63d177f0685933d066eb8672f8 +4300,44786abba6d572a2a73bb77454d72df5 +4301,f29032455b26aab98d7001b9b5a132d3 +4302,557282fb08e87e1f4d9e49decf3cdec1 +4303,38edb9b4a05e7ec5e6c055b654c00162 +4304,a54ba76808eaa2bcff48ecc76135f27c +4305,accef71b2b40a40a594ad1b1569fb35e +4306,9ba918fc11592ab089a4d2eef2b99900 +4307,c2e4024db2611f6b6ba7bed4d4230f00 +4308,9b6d6aabf144b4133c60942f21f26f0f +4309,5f6136eadce0fdac00e0e89ed0132828 +4310,25cdc44cec56e458d5f0c60ddab48898 +4311,9f444162125278a5b5dfe4319a9ef054 +4312,dd3b4ca4b639d3f2370aabcdc8ec7110 +4313,ff56a1ed946715b7daaf5c295edd52e9 +4314,0611051a4c5cd435bb76f85c40a36e16 +4315,dd76150031a737ff7fceba4683d202bc +4316,fba848d50121b05fa24acc2d4dc96879 +4317,39b6a4cb3712965261354ba2bb7301d6 +4318,c8719c580ad41ebd3d19cc2d8a971ef7 +4319,63d587649565ddd046b217cfd363b51c +4320,0f1a3baf2996a7e7dd4ea7f7f9804091 +4321,a431b8f33fb7138d4d1f392ef506754c +4322,01e20105b5e4597c0d61b9a9be0b6416 +4323,fc4ed0a2adb8e61c5e620c4e214511ac +4324,b0d93222d6c3882eed95546c55026f94 +4325,0cead715ee2aac720c8106feec93ddb6 +4326,c5859b36fa32284425117d561438fd9f +4327,fe804e1ae0a3f6c901acba0c0eef07cb +4328,87934ee09b33deb495286c55b52b1f29 +4329,0c64ca8c8cb87edad2fef48d80323d01 +4330,a62ce353ad706075794aaccf2a7737c1 +4331,9fcf771a9798d064b2a0dbe28b5394e0 +4332,7029d70924c93765cc4dfc13e3293300 +4333,f5f86278cb3d30c62a14698304bcec9e +4334,7b949b81c81d8af11b556c14e0ba1239 +4335,955447aadb5fc865ec16bd5006096d22 +4336,ad6f4e196ab4e0facf0dabe69bda8001 +4337,6838e43d16f0f0f4c82c79d0fa24309d +4338,0483adfc9e65056c6ca3a083db538234 +4339,3c199916b39a924b7b284054fbaf4a67 +4340,4e94ff798eac016161bc022cbf82e331 +4341,bfd39e36fe39851474e423275f2249f3 +4342,6c0f1e1f493f7a7a603bad819813f5de +4343,91898177dedf8137d0c3b29d0cc78ab0 +4344,49b2b25adba4afaa1cf6c559286c3ff1 +4345,daec5abf03f9d3ad9fd8ab0d36ea94f0 +4346,310965fc15e71b16b487b112f8c9a464 +4347,93703ce2dfc08e43f239a91ea45b83c5 +4348,f5aec51a41ef3fbcf89487da8b0cb7a0 +4349,8bb621847aa3a5ed460dd22058d06572 +4350,0241c743e24a7ef07238a403c4cd9a5a +4351,5fe65dc37bc8ed9382fd4fa802da8d68 +4352,84e9f92d3f2c674e0fbdf4a616687cd9 +4353,5718150f10bfadffa019690e32ff0f9b +4354,f5b7155117dca0884ca73d587a32acab +4355,7451b31b4430ae520b27273ad2005561 +4356,f0fa2f4eef004af6038a856c4ee7ce03 +4357,2b9968a3b6c2ab52e93354a755067296 +4358,bd5ed58e8a56bb726abf7943cc4b3006 +4359,6440ca010e2b8a423ed7e1e372765d3a +4360,e0ac53e2f52871e8ffa4fefac5bc4d5b +4361,8b133de0c4f540222745ba1c8a15f679 +4362,44a4c58fab8ea0331029b15cb51c6c6b +4363,f3a41e48152c8762705b4a9b1c39906e +4364,8c2ca9e3c58046c972d9df186e39ab10 +4365,0cc6ee1af81eb63c675616e2fda7864c +4366,12b16c3a79f9d61479826ff07c7e6123 +4367,a8a6294ab30a9a8ff6b6917112e2c46a +4368,699dcab4108c51093b74c8c1cf962dab +4369,71a4f1360c63a6052c57bbb0f6318204 +4370,9ed3d9cdf975a683aa229060e384c197 +4371,f74190eeffd2e2541d1020761a54aa86 +4372,ea0812ad473fe2596d7c97dbee9c656e +4373,abc24870430063acd678fa7cd03ef739 +4374,526da7cead9ea1d3edf25df9f4e826f6 +4375,9a65a40a83ed35ee1649eadee5131e1a +4376,d174c1081dfdf032d94afac2b18e5c31 +4377,37995187056012bbd4baa4cfe6e767bb +4378,5f93e9a248638646e01c0409a9222203 +4379,527536ef9fafda880e7da1b726342a27 +4380,3deca43112c07eb77223c33aa0b6ef60 +4381,2b677b0b6eb6b7068c74574f764fa486 +4382,3df4769b3f12cf4d3be7a8e2b58015a7 +4383,c85eb235b0f96feafc015ef779ae6488 +4384,5da58d71905ffb26a719c41a8f8314c4 +4385,0c5a3d9d32ccc8e41732749bfff76a90 +4386,3e3c837c7646155cc97c0686f75979d2 +4387,5778fc6786edd9d9bd88909cb7932f0d +4388,4bb4f72684ecb509b1bd4857a1ca6f20 +4389,8879ddc17bcc198e462fd86b58ed203c +4390,8c9fba4a9381ea2b2716262119a7e174 +4391,db0a14ddc37f2d35006f6be2dcaacf5d +4392,decb9ff0a738caff383029f46eda73c5 +4393,ad2f8a99c43c54b99b32d1253db7c750 +4394,a4bbaddc16f4426504f93875843c70fc +4395,497843db13d5fdd598145befa0d90c9c +4396,ee33c0e8d996d90d198582a98301b394 +4397,a98e1c3df378275cbacb7a99f7bb5374 +4398,6213afc0ee01e7c3b975efa5fd1da2c2 +4399,ab2b4022aa600a6c82615262066de6ff +4400,6bd6c54657342092076a8ed4908404b2 +4401,e228e518b84197b57f47a963790529c1 +4402,b6889809a76c4b03160b59b5d08c9f8b +4403,04afa7c8ea16f3ae3f37be15b9d74a64 +4404,6c9d611204b46b2ccd3a2e41fc7bedc1 +4405,e2c712a59690c1f6cc2029143e960d19 +4406,e7c5fc02a62179b84b4859366cea4160 +4407,1609af629b3aecccc8514e8b78bf013f +4408,0782b2714d6f8e49bf8e55adf382e8e5 +4409,761cd00f783600d9ff397a56d1e99525 +4410,ff28f309e84a37a8bc4c29b44a799186 +4411,262dd215475b88ea11926f06e2760ec7 +4412,cef77832779d9099084ea138d1e6ad33 +4413,ea1d88d2a350bc3fd8dcbd591a0aea71 +4414,f7841154f7547b0f1b2aef0c6830ca81 +4415,25c23cfe071eb04ff884725bb9b627a1 +4416,3595bc86f92712a569e345ae82b61b5b +4417,999a3b5d7652cdd485898832b59fad9c +4418,d5619692d612ee38ef835e57ab6675c7 +4419,55db76fd906b5e6899ac0494e54f174a +4420,67d7fe346f12db415c52b2346510197b +4421,681156ed29e0408221fb310009d8605c +4422,1fa3db45e18477a5ddd37da880157789 +4423,84394e3b56cf9d2f3a94c4fb442b7c41 +4424,d32c37a61ea08b67376826fcfa133c10 +4425,970e62c9ceb9c25171cddc4a792954f0 +4426,5e618a265d32736219bfdf218f7062a6 +4427,56c01f910695c71075228242a6bf06f9 +4428,a01ca0e8c7b04361f973bc724eef6db4 +4429,e8e9deae85f39f9605784c48fbb9a38a +4430,c2e2a714226837a6b401639b6da61b01 +4431,e4aed9fc81b9fd6b05bbe114d6f99bf1 +4432,7ea4d0a23c63e92222d3f6b89b4e0ecf +4433,d1ec86d4b94007a6d04d8b829b13027a +4434,44718a7d351935f3113e6214e113fe92 +4435,2ae1bbe4b57697da320876ca67eb6e33 +4436,3a3214c6e5fc5408e0eab61e43943875 +4437,9b1651eb37774cb349c5f1e17c5daba0 +4438,46b11243e5689bdf25952cb3d8a22a98 +4439,30b9f8e6863de719cb3ae23661b39e31 +4440,19e68023dadeee9d612e0e798ccbfbe5 +4441,599a7bfbfdf03ae2459852b04eade418 +4442,65ac8c9116ef480d05c7d96f00803287 +4443,ee22cc6b66e550ca7a7ed8c60ae16b09 +4444,5c629976b921b3327a00156d4d6e4970 +4445,3deb5f8ef1432a6022c93544c35a8aeb +4446,2e17d98c00739b60e5ad4f0e651b981a +4447,cd648baeb4c9a8048b66c01768f31f55 +4448,3d52361a6a160d693d96abcde20d304d +4449,98f630bbf027e3a750ccea621317312c +4450,1e6e48022900b5d659e9a0d75a24c997 +4451,a8432997682170db339f98e442e813cb +4452,6ea1c354603760042367636350066eb7 +4453,dd9254d6820a704b50751d3ac7096e9e +4454,43e11ddbc1bf12f653456f1cb42a331d +4455,b50aa8b49f9be3cb74253bc6e797a273 +4456,422c54846a16f52d74db826df98f5e58 +4457,6d86899579ce9d153013955ea4c5d491 +4458,6cc237e34b1cdeac0d1e787f13e4ea1f +4459,f64ca374458d456ea3c5a748fc883cbd +4460,e6f93b3cad561f700d0aaa47e2142430 +4461,bfab7a168877c61d08c38b5ee70f37d4 +4462,20bb7d5b7d6d9408e8b2b8880922e87d +4463,ea894aa37f1f77f5b365c783e9c9d72f +4464,82fe71037b84b84929c6e950722c7f78 +4465,80db31f082b4f381a86a3d60be829b68 +4466,3530db9382e2ba06fd59a9325f1a33ca +4467,8e8b2596168cb21e5f24b171efd29ac9 +4468,dc2d6a22ec06d02037cf3e99a102fb38 +4469,bed9d2e369bc16e1fd59e03c5ca6b42e +4470,45d7938e3d73d11cdf1b959eb03ccdc2 +4471,8211edcdf8f6466ef7f48d041819ac6d +4472,ea43034aeb64455d016508e853b6ac7b +4473,da90e87d64eb9ae3d8065ad2b8dce74a +4474,828bfd85968566ddd8f7211797c7daef +4475,07afb72428907d99864a80220458adb3 +4476,a59ebb3e07d0b07521ebd231e3b723b6 +4477,f8d0b292906c55cc261d43f0f89de5e8 +4478,a2e752a5da3c2b19a8cc90f2490964f3 +4479,cfbc6fe331e2e174058ed31ae128dafb +4480,f2c4e678018fab0070943352dd10d5d7 +4481,49537a7eb004a36f0d2407a1f29b43ba +4482,ac7c5a3deb1ed53637be7409bd696e32 +4483,ec482d0992953ee5ee93df06e84b5561 +4484,da92b0ebbe142ccdc1fe7b3c37564647 +4485,064f2aefbfe2f48bd14dc0eba90cf594 +4486,e4fcd54b89d62db26a5a3413a873e465 +4487,9e0efc43f02dc055c31903c2c093afdf +4488,ee04b0eb8d6d6b531f68898202f38b71 +4489,1d08fbfb43f5d9df07c1a4a5d213e683 +4490,ad5637ae04a79e95c30faa92fa3ebdae +4491,b3326731e5c879c328e337cdd334462e +4492,1c963ce9b0fe004a639dc596c3b29755 +4493,50e1e54f9686cb7d316348f2afb70215 +4494,f5a6051e755b73bf4ca650eb8e164c24 +4495,926b1a697b2b45d52bd2f88096c7208e +4496,f0eaaa5632ca1f206afcca5ad4704391 +4497,cb0b5eafa0bc367c61d1f503f4f180c0 +4498,e36849ea4939f20fa5f20d0cca75c0f4 +4499,3dd8501ca9a03d65d884a4b16ded6458 +4500,013ba26c1f4b8a0dc8f9a2e790f55a20 +4501,702c7678ba05251360183c3f5949fcba +4502,ea3d8ff799cab3e57484382588df7a6c +4503,da49a774c0d931138d3a5d3f55510f72 +4504,bf0bebb4bfde33180b5374927333468b +4505,aae9fb47a3a121e0b11239b81bcd7621 +4506,3c0f4432dbfb2814c33a7b62fbee48e3 +4507,cc0e8a65258493ef284833f0d8328658 +4508,153f5aa84a06179cefc31ddd011398cb +4509,6f5b726ec00b4b7e3f6780108ba99b7e +4510,dd7d9008e6c2359031d87d66227df0b8 +4511,632d435a30abb5c6db97a86913e51155 +4512,40316b05f9330fbc7fb652c02e2a23ca +4513,a8263263711bae55de9c9324522c430a +4514,a5926aa99bebb945670d2b28f62c3c60 +4515,22856b68c18dfa177ef562049a93f886 +4516,70cce1a7f060d3e3a2490fc7a27808b0 +4517,fd93eb294a4d843ea4214b7f0617381b +4518,a06da896db6c192143d87a0d444c2e99 +4519,d22c2b00b609b0aa0bfe6b58ef5fe16c +4520,5ac348a018b13d30702e5b2086d98129 +4521,154866ac882bba345f850902ead92c33 +4522,be0d042a99d3aa716ff60b40d3b2e946 +4523,4ae78025ce9d5cfb4d33d63af1c5878e +4524,5139a28142587a0e32cecba4b8a6059a +4525,ab46f7a7b5663df7e96d220b58d659c4 +4526,9e8b3985a0c4267aca4c0d56741ba185 +4527,511cbeedf32a31e0b41434ea8913fb9a +4528,5f8b6d109f7dbe65981779a62dd9660b +4529,2f8b5ec230e79b7024bb0cdcc79331d5 +4530,4861edfbb3e1791eba2e45c1bacb9c0c +4531,a7347e4d266f1a125146072842bf1b16 +4532,65a82840116835c1700a49a3a2959640 +4533,41fa44f6d3c1100dddba3d547027ea19 +4534,e54d08616e113ab51c4abe18d1def7d8 +4535,185f68b9840fe3deb01f6cc525b8d24f +4536,3f3d9e18c4dc7516fa5508ecfe4f9a8a +4537,99afd3bc1d816b5d14b8ae9418eeaa49 +4538,a92ce1533a74bc6e12dbc8dda4ca4d4b +4539,4676ec8a037a410620986da2cf6948d2 +4540,a65661a29436ec87479ff063340ad532 +4541,df2f37c13d9d9459479b5be0fd1f8545 +4542,b6feaa07d3a345a769ba6aeb76ff8693 +4543,8a7634c5bddf9a2ba8102e00ae0d64eb +4544,5868e3842f377fb6801e2a3df8ffd037 +4545,409050a7eb375912217b3ee9a55619a6 +4546,d8ac02571b643c8a86671355ed9a7b27 +4547,711c22121578e72b059825aa0ad6cb22 +4548,493bf27f2402fa1bf1362992c085b3b1 +4549,359f3e66bbd51b8206bd35007fbda2e7 +4550,a04bfd695ffeba87b11a010e3ef73f27 +4551,e31b26ee00046d9f73e1bc1c76261f89 +4552,75c87576a92f8c359b015c7bb76567b7 +4553,6f448831abe716cebae41eb10048afc3 +4554,dc24219200210e96f8dd9a25072cd140 +4555,73004d77caf23a1eea0ca86cce801a62 +4556,fb2fe4ec5a7e9cf2c60f31b18acd032b +4557,42d82a63ce60a179f2e232a3d15fd2b0 +4558,025a99cf9d9f6c54c440aa69ce897f59 +4559,0bb12aae326c9ef8bd597ef09828e790 +4560,06e069a252fc4b1a05215809ba1cf2ea +4561,b7df9d4ba727ecd2e9dc98c4019dbf53 +4562,42a0ad14bb06ef3455a31ac14ca9e055 +4563,cd7df1708a6921156e6433a7a18fe82a +4564,b6e1cf5fb152b33839fdf6280e861406 +4565,e51a333bff6f5b1a5582005f35c1b38e +4566,2ca968fd4b943ff7ff313b6286ab7186 +4567,e9a2e12697ea0c1bf24feb560e4d18ee +4568,6b5927563527e61a84145c91fa2adc04 +4569,39a42a56c5d850694af2835ae1737760 +4570,37cc72ddd62faee1d346a14bfb7a0484 +4571,d99e54ed134eec0a0e1f4d541d24ffc7 +4572,11ba2ae6a30b54048b635f67a956dcec +4573,a0d1672a96afb02aa448cd75e7b93539 +4574,164de616c421206c19832ddf5a13ad05 +4575,423b1ba2cca288dbf76a4bdeb9360d21 +4576,5df9d0972f283b9443122cfeb16eee9f +4577,44cbbf13ca8cfaf191c53ebe23602b8b +4578,d5bbd5cb36c393b70ce84f610c8b669a +4579,de6717a27b5626ca9a5c5cd649201f40 +4580,ee5afaf87a23fad9f9091d672fc2c064 +4581,e9cf65e65b19e2b8e84a491eeb6b973c +4582,c8acd34b81b42ea8cf8121814b65ee1a +4583,8e953b3fc135f93273215fe32ec117b1 +4584,dc0eb6d28acbd20ad6014c2f9f09efcb +4585,2100a3eefe03715d293defb5644c14a1 +4586,212c1d07fc2f64442aa9b69ade482b37 +4587,923dc58464b63bfe55b063038876c536 +4588,0e8ebcf1fd823057612442995cf8b6ba +4589,8de2d9fd377e0b4f7db8401ae16b1b30 +4590,ff4042e3f02e89034525f3d57c6117d6 +4591,32fb005831f8d3fa592ce53fa84a790e +4592,8358e37d9425a6b7b69e99a0d76cf8c5 +4593,12c643a2a1cb38c7b61b4edd0d45efec +4594,8d78293771190165870ad0b308221491 +4595,873f43fcde2e0ad881eaf4cc0ff1750c +4596,2676822f168e145cb369f3759994fcb2 +4597,b42b313806bd07fe9873f4dcf89d4d61 +4598,179c23a2ad5f4093bf0c0b18d49fff87 +4599,0c92368f87f606a6886bc85b12a4f0f6 +4600,d01742396bd4a7f0d2e96a3fcbbec76b +4601,f8140d4e5b0958e0cd18a3d4d0919a82 +4602,68edd4a3e22b6335a1c8ebb4cf56df97 +4603,0096632040a8d4a2185bfebe818cec41 +4604,91e4b2738e798f96f4b5b58fbaea66d2 +4605,0f4a6f88d1c1ef78bf55c8f7b0d67afc +4606,ccb0c45671a64fb3a705ffb0df68be2b +4607,eefccf29ae080b97de6498bcc03e0b43 +4608,e487da4de1a2a7185c3d8d2cc3b3954a +4609,10708ea76042c22931e15cdd67d92e10 +4610,18e1c6d195b48eb9c3d0ca39ea9a5d49 +4611,5d3384420917fe7bf1754b2f82ecac0b +4612,d5eced6809087e5ffaa1c0a3d3c1a6bf +4613,01aa080b05dbbaebf727ff7ee0d2232f +4614,6ba02b0b2c5de0e52bfe6b68c3a7c69a +4615,7ba29f2f8007b6b16a05fdd31601c420 +4616,04c9603b6c8df3d3f5420184d6285be0 +4617,628c03c7aa6edda757d113437f77f91a +4618,d113f788b61285896afeb8431865ebfa +4619,786effaeffb87d046b018dffdeb4f6a0 +4620,6f589f71659fe439f81a384ab6ebaf38 +4621,004b659dc11f5caf9326cea4f8056d2b +4622,dfd43c5fa38344a3a5c3bf00ed681bf1 +4623,2eb4015fd95c71761b3acb06590a61ac +4624,8848814939e2f9ec4b20424bc54c238a +4625,5341004e6fa4bc4b405a03b1a0221c7d +4626,ff982bae22e31bb1b9c1e91fcd75e438 +4627,b308ea309b840daef8afef6e2454e86b +4628,e0ba506dddff59b5d76e584ca51f808f +4629,e98b6b0702f7ac9ec15311abe7106e92 +4630,c33c8045d19f0bcf1345640fa9ce2326 +4631,9e7e39e32a7868d81a74542622b91943 +4632,e4dbb2e7735a7bcd0b6f74416a140f12 +4633,5a4cbe826efab71602b7824b1b23b91c +4634,57339fabc7cdd868a2d9493bf80e2e90 +4635,fac4f9795dd1d151d7fcb8e65f1e08e3 +4636,4ac4ff31779da17b14b0c69aec8273ee +4637,75590b21dadc5e5f5a9cadb0431993a5 +4638,11356d256c33ae9a10524a63641fbb2a +4639,017b5d49f07aa7a3def37a1b3d9e7be3 +4640,8d6da0b913f81a43db23cd99a880b108 +4641,1b0c4b0e7e24fa772daccb932335daea +4642,6a36148a3ec7914f4f1c0a5be4eb7516 +4643,ff9fe7cbf985890e8a5752ab009f2b34 +4644,a83a202fd7e41f14f256c5b39c206006 +4645,e23918da7756a5d2cc5e569a47342daf +4646,c39a29c9480b7fb20501520e1b2e8f03 +4647,a149798819e22bd50b142d7a8cb93031 +4648,38861162e69bb5282ad4c1064ae70dc9 +4649,8a26c4d56bb0af45ef7d81561bcd803c +4650,7a09d99f63a30b4ad4ec8db7d03fa8ba +4651,5f1ce4a08e41383ea337c6bdffa0d928 +4652,261583336582872dc40a40e231177d5c +4653,6b3e454da98c50a2abd0008b60f8e60a +4654,65644503f47f247126128e20bb4f82ab +4655,291952bf2542b0c57d81b2f43a441250 +4656,b9ae8299ddc172cf81b40791b858f0f1 +4657,4ba6cd6ae0d5c35b103b182fae48b2d9 +4658,614f74657c98e83182d75e2640b76dbb +4659,78f8f149512321c51e78b634e917eba4 +4660,72973147d89b0424fc111c234631e8b7 +4661,712b802dc0b7479a0ae711d7c7c9eedb +4662,36f8f3a2ff2942ee38da3e72f9b91f38 +4663,f1d0e38990bfde0a6f8d1598c5757a88 +4664,23df479b92795b1201bbacf46ec6906f +4665,756362e94927f95ca84ba889c03d8eb9 +4666,b74582bef62bc412d0fd5d8271a4d822 +4667,fb29c96599b0f877eec279a2c8ffe336 +4668,014b54d42af5c66eff026696697093f2 +4669,344ad054c0c957995d5539370d38a3dc +4670,f96dde1036a0f536ee75202b256ad37c +4671,387cbf1a059df7e5b971ee7c8c1fbbee +4672,4e6b50831e553d958bba228ea7ed8d50 +4673,a83b72bccd65e31439769d154620c612 +4674,6dc45e5b800f69ce7ca4fd9d87b87a27 +4675,bc0b0394636a6154873e523e1c945812 +4676,981c1e3e2a8a6cffdfeb8fd163aeb6dd +4677,a88f923eed2dba72742dbbf6b038e22d +4678,8e24c7d0a381f1dfad177749296fac1f +4679,cc1070fb86b0a0579650d11ce067892f +4680,5a473d1cccaa15bc643a16a7e41c97a7 +4681,17990ded4e1481b2ddc12e15d271e2b7 +4682,f316fcb1ca33addb5e5e6913cc27ff07 +4683,11a6e52478711fc0dd69856d11adb1a1 +4684,6908dd194916ebb618751904841da748 +4685,2fd066145713210c1697bb20dbf17102 +4686,ca3406703583c8b798a3e8cb1566ac20 +4687,221bd34f27e92aa0dbf8535546bc541b +4688,cfe5a97d14eefd5d55be5dfdd9801daa +4689,03740bb182ad4c6c9e68d59bea6f596b +4690,4e4b010bf21116693bfc21f44860526e +4691,09857581a566dc0112d9d49553503b2e +4692,9d3fc0140b6ff85c350642ca29c63e75 +4693,f0a78f4320b453f1c7503f51e2d1c92e +4694,8741691bc8da3987ebcc2f3cd66fa647 +4695,99019a0627db0c350fc82c58d24bae6b +4696,4bc8130bea4566746e8f04c182182df9 +4697,80ddd18d52b65cfc5d06bf1c5902bdc1 +4698,bcad021cdb95d9386108c2fe20865ff9 +4699,e33bc0c83e08224b6d7ac101f1882049 +4700,c3b304f7c99bedbf4ca560421ec3b435 +4701,8c222c06473097e5fcd55fda1a7a099b +4702,7f0b91573ba32d8ccec592dd160158cf +4703,02fdb80fcea294ecc2f34cd74c7ce52f +4704,bcc36c34f6bd72ad2a351caed3dae544 +4705,dce317d6e6d9339bf9f5d1760e6c2fcd +4706,5bf7523c1ed997e6d072089aea51b5af +4707,de7556a1ae9fd36789fd480d4d998cff +4708,7d792edbf8633d679583b0f811b9ca20 +4709,9b31f48ad913e5eb09537a43f54b947f +4710,7f3f1c77c9ef11ea31a03b4c5ed0b160 +4711,9989979f9c55e304d862d38486c0f9dc +4712,cb6f69fc1b35dd7ff336467319b9f419 +4713,9ef11fa95f416b628d78bcc87d29cb48 +4714,04ca7e11de58c287d4ab1906f73180fc +4715,427e7273f92709970f1e4edad363319e +4716,c2b5269e9c8af184d4bcd7a3aaddd659 +4717,fdb705ba148669b50644da2a188f00a5 +4718,7a2c8f3169b2f5112b16b202a41670c0 +4719,e1a3e2a1fbf45f128248d49f52d36137 +4720,65e0316dc574e10e6a6e098e48a974ab +4721,a1a22ce448ab1d75146494a4ad50cf3d +4722,e5b91d4107d74c5715d84282e6526379 +4723,f0a72d672577a0ef3499ce4bea31924e +4724,cbec80ffa2d6c550a425d60087eaaa7a +4725,79d8890e7101dc5b6970bd0d971dc060 +4726,4b80e80156dcde5a1c92d41c5ea04412 +4727,3b44b43a60cbdee6df15709ab5b91ff9 +4728,bc630d751f2debd645d6daee7a81a60b +4729,1f053f81f09d6ed63d0c3399dd0b5c4d +4730,660a9dcf02a9c234ade11dc1fa24076f +4731,6eb2bc18f467d9d4d27676a353060bc7 +4732,9502288013a3f366f18d46297b7ce146 +4733,7f643f01729b41c2e2a3b74933e46ea1 +4734,839090d41f9c77c5ec2a89b7667e8222 +4735,a91c232af2fa3af7f6a77d21152508d1 +4736,0cc133742e7bebcac63e7c3741e1468a +4737,075aa6160a2e890700186e516d29bd95 +4738,143c4c42b7a2563e2509512c0dd0bd5c +4739,8e40b665591eb0cc5166f9e9a3718186 +4740,80625793d060784e6af2f6b817c867da +4741,ac0e7f4ed4890a6b78875f88241f9da2 +4742,ae8a49878a1a76c95a9ff36c475adbd2 +4743,0cfecb63274f025dd43c4209094818f8 +4744,0edddbb58e41b550682266376ea31d4c +4745,98c55ceadc540ea44c83e72157cbee36 +4746,960c8806985db0ab7d8cec55d7592175 +4747,7668a0c205a622c939c2419e06d0e0c8 +4748,4fb0d3a9e0f174eda1729ce57317dc4a +4749,8fa91d3a5a1137b3cad23d213d862c04 +4750,c534c0ff8d46cca3b2f5a52876831331 +4751,bed303138c13c3791a775add2122ccb2 +4752,6dfa60a80a3e7e36a5b518fd3cbb0b5b +4753,9e3da6ba8e52afbd5dece07fd9129472 +4754,3df36315fd97cdd9c344b143fb978704 +4755,bbdf6d69672d58e1f6bf3c93cb4152ba +4756,aeb1345acbfa6d19a610400105e4162b +4757,4a7a1e27c10e0645265746c04c3e650b +4758,90a4b7d19be98efe7b17f5f95f26bace +4759,cbcd37433e1c4ebbf5947b4dc1a4243b +4760,7edf61c44022dbb9c26d7e66e6e2fbe6 +4761,3df7151159133fcafa8556266867f9b0 +4762,e4e603c8c120de617f2c6edc63416775 +4763,d8fb40f44847ec3861b081198cc44ee2 +4764,ddeacb4e7e05d153802c1397019b70f7 +4765,de2ab0153dea2f2770446d47eb92b873 +4766,5b6c5639286acb9a44378e785230bc36 +4767,780f8902cfd6d54f2b47a3b1f4b85a13 +4768,8d1ef5c981c5db99f8316582db45ed6e +4769,e0d52486891dd522dd1d1782626bb54b +4770,7edf28ceb60d1c2d552896935eebf8af +4771,f517cd6cf80fa2115b5ed88649608109 +4772,2f5f62cfd5fa071bee39ec7eae9af0e6 +4773,c217df5ba2cd34ba6c999bbd34e84aa4 +4774,664d5124c93ebc3b4394c94a1538a22e +4775,3f3014f62a3b113e1a42c57904336fcf +4776,080cd20c4bcd2fe33832191b8dd41e7d +4777,8484626329f8479a6855cb67414c84fe +4778,7b1554ae2c9170745029d90b8c8944cc +4779,f043b1efcc06829c8edc726845c236f0 +4780,49c10b30bad6268d70f425aec7515bc5 +4781,13fd847c1d40c23832d64d24e09d56b3 +4782,20a966001ebf5c68359ed5482bc403b7 +4783,7eae4477e2cf470358ed2fee0e66db66 +4784,9ea5323bf313ed84dac8e55658a6f347 +4785,f836ae5b8573dcaffb41c0bbd739617f +4786,8e96f17d9bc9a3829ee868eefb3db1e1 +4787,4c1f45791a0337d6a7fd05d7d67e8fff +4788,ef8ffbd0a129a29aa00c225c0c26c10f +4789,78f92408f4e2894f628eba87217bce8a +4790,f28e017f66d4105d4b013543c407c8c1 +4791,4657e3755ca842b0b140f1bc8ba2b093 +4792,1459c7ca239651f477a2ec9f6adebe9e +4793,2f4831202e839150606a48355f676908 +4794,d7d546c4b2522688fbba0030ae0be5e0 +4795,aab8001a8437d237c8c63f85b99cfa6e +4796,bba13fbad7baa91a2b7aaf01facd3bee +4797,a66c5859b097b050ebba813c91fbcbcd +4798,0698e8a06fc61af4b3b3adffd834cd45 +4799,aece024aec5eee465b33f70d0643e5bd +4800,24cb45a78377a358151cc1223b1a63d3 +4801,ccbd4e0776761e36cb944e0bf33a3c68 +4802,2deff0b41797005c38b00ed80b661410 +4803,43c81e7a46052b4aa8455119e6efc9d4 +4804,87436fc752008971b6dd49ee61888ee3 +4805,208de9aed3ab17bbd3afcd3fe624d474 +4806,41b20e61400e8227a6b8c94f9b1c5fbb +4807,81a74c190e8c9edb9f2539c838a18152 +4808,3704641d3b3ad21232ecd454bca769f6 +4809,cbfbaa166d7ef26c2f73d5ac19f74ba7 +4810,b8ce4b14b79617d8aabbb555853e89d6 +4811,cd30a19fc82c2d6f820477b870f34d84 +4812,8db1c6a928bd19099e617aa423363ba5 +4813,c4e1c2e79740f6047e6dd7aba546cf7b +4814,e04cb82019df659f61ebd447ff227264 +4815,9e44e3ab7a4701f4b12324709a09d34a +4816,4083c3c18f45e92858a62158f9ccee37 +4817,736ec1d8c5e3467697035be9e3917f76 +4818,ad56c562ed686f49c9529e605e401ec5 +4819,6cb26b2e49df8330f2d9793aa9c65682 +4820,27af4c72b02cb1a671200c6c0a3cd0b2 +4821,20f803193506333484440bdf8492adb7 +4822,f4e5ea8ed2eef82217fdf972cdfe8d40 +4823,c316be03ec823f7abfe4fda8e5c39386 +4824,c1f8d9c74b245411353a8f3bc9cac3fe +4825,ab4f33720c479c0cd2d73a494c0955a8 +4826,e10412abe22961fd3dbb062c1ecc4ca4 +4827,bb8c8b9585ece322789de29220726901 +4828,1598d41f42d244964181b0fe346f2bd4 +4829,ac5423bb156e222d8fb1108376919db5 +4830,5cfca1593f3b0abc0e3c378790ec93a2 +4831,0d0aee7f68ce81c69d7700b9031acdfa +4832,70d663f78e3d544d5dd081401b1799a8 +4833,30bff13dcacd056417a8bc2a04ac0af5 +4834,e28076627f60e0e080163ae7e708352d +4835,ccc4f5f90d3d585d71e91c6f4ed1bd09 +4836,a284971f7ec7942306dab2b16cdb98f8 +4837,e290ec03f5de07ebc171cb1264860cbb +4838,caa0fcb56ee23650a8a5b08d2e96298f +4839,7f2893cd2126973eb356f80eded40e50 +4840,9e9767dbdc35317dc4bedabe4f28a9a4 +4841,6b14bc10e3f1751f8f7a926140a8a069 +4842,8c288d1626fc41e0165ffd1562020b9d +4843,db8256ae486a7b6fc9d18910180da8db +4844,0f24ed202f4dd0de510b26a0c0c65fac +4845,9cdba1a2629bb529aa467336ce7f0596 +4846,58dc3d5663a5efc431d9ff1503d2c5cb +4847,2b39a5deb3aa209c216e9bead598bcb6 +4848,f0e7b3e664e43dd06bdb248a8006f99c +4849,662ca7b9e92b6006cc118dee351ed6ae +4850,5e778a4d95ba7b7d024d3b17e41a6923 +4851,3ad92c9221c557134a4a679ae6b4a5d6 +4852,d348fdd79f061ff4c1f3cee47df1f917 +4853,d40d376198becf056dc9b5555c276b84 +4854,fd3ebec2ee32d5ab84aa25fcd4eeeacc +4855,1dca8ff2e056e1fc7b0b5d2574a6c6df +4856,84f1409e8a1479644df94d4d53d3ba17 +4857,11fd50fe1e3951a27a88fb691b5ede8a +4858,8d7bdd5a257b02f6efa234cd78fb7703 +4859,20e6d40f00e2671fbde6d0ce58316c51 +4860,ea019ec84833a9db518bc433181d223d +4861,eacb80e082c231eae17da52ab8698335 +4862,9e16beb83ef1643e32fe3795643a17ef +4863,dc03f6d0035ef7ee234b9e188d6a4002 +4864,d9e3678c6b9a9c33cae91fd682c37158 +4865,819bc30e6a23c5957d3d06b181b95ba7 +4866,6722fe9b64297a7803501e778c67a9f1 +4867,46ff196b15bad2df8d8d7f8adb1ae874 +4868,df7c665abc485b34dbd3099abb708a01 +4869,fb6229d86a1cc96faf3e2d5d27751758 +4870,0c8a49d7022474383133e1fac5c747f0 +4871,aa23c0ea522cc99f37164ba3c90bc5c9 +4872,b15404c5e3c88fea74c756536b420ff6 +4873,6fb2fd763e72e691ccbd5d35eb96e5d1 +4874,0504bbd2fab39be1e041561a51dc5ca0 +4875,7a29ccc39f338047b50d15143bca4256 +4876,1fb4c5428ee146f73d92113e513432ec +4877,185cbedcbf379da087459df27b2ef5ab +4878,7f7548911a001dc4c4254c9d0411d3a6 +4879,40f7654f53aa83c14675569b16be983b +4880,4df431f8651e4e42089a94926504c057 +4881,8b08792a129411e5bb1ae808d0784d8b +4882,f7fcfafc691404db03172547f9256ff4 +4883,4e9f02c9eaee891f3c4adf69a848bdef +4884,54431154300b40e67ad90470f279029c +4885,c75776c39b54578ce158ef419a947698 +4886,b3ad296d042cc5232d9affe974d5225d +4887,4e89f5b0f3914201c4d28889bb8f961a +4888,6c375c51d5b57cc48023d801d068cc2c +4889,815d4e2a9c08f7417349f9266ec8ce67 +4890,633eac2d4441e0e48e3eb796e039ea4a +4891,26461203f68e1f3881ee7c2a1d2bf0b2 +4892,a48a82b6432b8085f377fced60ca2c1a +4893,06ee9ddbd1b0e9bc1381ab8cf0089bf7 +4894,d8a8668cb017239bc7ae1c166842e9ca +4895,6fc817672b02b200fc950afce519d287 +4896,c54bef9c157b9f1e51ff8e661b0ed29c +4897,2855b6ec57532e640764824c6301365f +4898,a371920ddf51e5b719144e599dcdf5bc +4899,045d31a8129386b2659757b46071e4d7 +4900,16033f51777e59c9c62fc55ce25f1d16 +4901,4b5b6f33802fc9a59de0d58cf378e684 +4902,ff650a78627425211c72d5e7ef40bcf7 +4903,e458fffd6c62eb5a5fc34784485218bf +4904,c3d8246e473f33273b4a5953eae35437 +4905,abac7fd0a350cc0187dbd8a1ba7aa9e5 +4906,1ced35824c53cec93739bb87537a5254 +4907,2b349386aec7b4daa2dc4979ab9d6ecf +4908,1d5b79f60a8012bd8d54e4e0270ea16a +4909,64f68ffe841be9652e270558c3347b16 +4910,4406c2f90edc47583e807962bff772db +4911,e07f4cd8e1a3bcdc1aeb36654a5b8312 +4912,5802e65ac591ee6c7499bd7e5f21c869 +4913,4af7bf87ec03fc0348ac29901b7c364a +4914,6bd65be2bff7281887f5f920dde76f61 +4915,2fca4d9f04ac4775f824c273d2a0fe5b +4916,ee65d4926df93423a3c5d2f12f5ced72 +4917,518fa89c299923caa8597900c6a2f95b +4918,12f694b34cfbcaeaf76198f3810b8e7f +4919,6a4be0c89c4dc3450d0b5099cd0790ba +4920,19f613c0f8281197e9548a3ecb9335ea +4921,3c0ab2fcb7019d485c3164ed8374763c +4922,0155a5232b16f8b31fd5a5a8903adbfb +4923,ac9cad08c3cb75995bee4df939fcf57a +4924,d9bfd0b31f1bff0f521c360df1820ac8 +4925,88323f4299cd2ac35ca01b8d5cc9fed3 +4926,0e959aec8f9f0afdbec595b2761279be +4927,f43128ad15eb6584ca6b6434382d44d0 +4928,e3ad5db1109f73dbd6fe073d5159c598 +4929,d44a1217884a6a04063f344851349d00 +4930,519df2504dba95001d7a7b013551ff0e +4931,57fc0e6ef536bd435734eae0a943d8ec +4932,f1993d0af82055c2e969e5155d2f6cda +4933,cb39885a65bfa5d63d5c3448f823cef4 +4934,216204ab9f7ced8089900e8c92c0441b +4935,272d7b2b9fb283bca4061f6c1476be9a +4936,39a91e43a38d4bd5d20955912c73f9bb +4937,d41e7fe2b981ee78aba3a28a7e795e64 +4938,92e5e44a5df448ba99360c735efc8bd1 +4939,704eeaab3ca291ab2e15db021de42b40 +4940,6f717b97649f84c69b979d48c496d28a +4941,66abf3b8245753508164b1bfc2c6c00a +4942,3c47967c503fcc6ba870ff4fb23b6db4 +4943,2e29b38bac026c0f80b7dae2de3bfb1b +4944,d6fdf1761e568513da0b190d570dedbb +4945,3ba4858911993cf76f9475ffb12c9a0f +4946,67cacb8ec4713391d246a1831513460e +4947,13a3878bdb730cc6d72280788be5fe22 +4948,ee862589d0bc655d048178bbc5482a55 +4949,7f08d11a424a4cc9bed3f82d79e92c54 +4950,48c618b832654056238fcb21af76be43 +4951,203257545153cd481c2bbd5363a2916a +4952,eaabde7562502012992c5e4ab3b8faf4 +4953,c22337d6d4d38ba86a9648d643f42d47 +4954,3135f3bc2dc8387f1e281dcc961bb533 +4955,cbc2b7c36740a3c95d4bfdfafc588ca6 +4956,ee9f78787fc4425e63008a3ade22f995 +4957,b1a058a03675c46fa920d7bfc847e380 +4958,458a71a63beadfa7f0e696f13ff7a8c3 +4959,5b83605073d8c662732614d75b14a6f0 +4960,16111bc7c550e5da5fc7195e50abfa20 +4961,429aa1c9e35f672596087609b1ae49c2 +4962,2db562bfaa66a8ff1dfddb80628d7c4f +4963,798de0a210090d7dd26b5811e0215f57 +4964,c63f90b2498405752757cf9e994d0a4d +4965,d9c42b93bc4cdd725c8559c518d5214e +4966,15010bd80529b7e6b37d3b3c4598df65 +4967,455748833040bd47828e295b0cb95352 +4968,71025e8af9febc244de0397d13b8ddba +4969,069586f11cb18152d2daf435b2ffa566 +4970,753e061ff8ecc30ef85fe600d907ec42 +4971,ed34737540879fb7b8eeeffe02e74cbb +4972,b459abcd1819773bc5976034f7d6dc6d +4973,b66dde149cf382927832134349f2182d +4974,7132b103d332adc3adb67fb363a276dc +4975,c9c8d1e82e53700aaf4f90a86d92d5ab +4976,69d5d5ff2fe0c92f439c5f7e6fad8099 +4977,92ed57c038ffaabf3a4e45bfa633ed72 +4978,61b6b0ee1a6683b43792e29a38489ed7 +4979,1366fdd7165638c9fc6576c254a72242 +4980,ab6a8e4c0267b59ab19b1ad04d277a97 +4981,2723fd3cd59bb938bf196ef78128e939 +4982,ccff0303b0f4a02fb618080bb0be1151 +4983,83386ef41e6cdef4f1f8aabf83af471d +4984,217e2a214622a1e7d9ce4fc8b8425c3a +4985,d175a9b0e27f174e5957d453a9a29690 +4986,61dc2dd7739ed23d7b4800f0020a637b +4987,79210e94e03978a4d1b39139b804fa55 +4988,e446f7be4f6e5b75c38b72f95676e939 +4989,94e8fd725d4d704b1ea588b351cc2aa0 +4990,11367c166985b47ba8e2b9833953aa89 +4991,ac9e6006230538bc4d02f3b9ae204998 +4992,7ab829e9bac34956d96c493e8ff5bec1 +4993,81aed722a0efb678c4addd10eb8b224b +4994,8dd0f88e9eb696a7685abca463c2e466 +4995,7dd32d8468d750f641aa571f450838f5 +4996,d3fe916c054d71ca74d51af1c9aa5254 +4997,3df2256c27b711d35405d09bb224a171 +4998,6b2dd2f1cca9ceb87b244b1e24297e46 +4999,5040f6f87993e1db78d6732c7c5982c7 +5000,738a85f1e9f6b57e69509210ac9f8394 +5001,5c745cde54d4b34bf3f74e4f9a010722 +5002,dc64593a1780253e6183decd53ad9384 +5003,ef39d5b39278942e432db3cd37f2d99f +5004,cd091180d3270ab6557165136bf4f61b +5005,06d9d69876e942074cf75869ef85350a +5006,e8cda34f22e8fb0ae87aaf0c46b02861 +5007,82bace46d2798c3edc599ca9a42c824f +5008,4f3f27e7cbf5d15cd74b1309ce5d8e1e +5009,4789374206da54efa99c9820e57832cf +5010,327f13a81693947bdff3ffd478b95480 +5011,bb78df21af18e9d9b9adfc861d795b39 +5012,51fca0f61013824ae6658e7a5b172c37 +5013,161a463046fc4f1c61dad7d31fa3c73c +5014,fc440fae16fa1e267651c8cb02a188a3 +5015,3e1295ca1d72093011aacef6d8ecdc8a +5016,ea2683889ec727c91d8f28a3f3d3d275 +5017,79f79537a1b97f630d755468a50e3447 +5018,af3c27d88f4696df4cf0564d3276b9c8 +5019,3c58419109dca74749fb41fb980c0edd +5020,74486fe6a3cadef27a60d0919efdd1ac +5021,b114e4b09d15211263b8ed04a6ffefad +5022,0cd41aed40652a818234f28ec4485a00 +5023,1efb930685f175971d2125500c627fea +5024,e3d15dc265a8125e6d744a01503e1696 +5025,ea07bc41b600745d1996f8eea48850b3 +5026,11d59cc102c16ac3fe571c1b6d704fb8 +5027,3811a10992c56696b1e0e2049afb3272 +5028,52199e6614d62cb2d9ba2b316b271bc2 +5029,a03575e3326cff34091080f2e3495049 +5030,f98c2d17e5c7d30612e914a14fecd060 +5031,26b3fc96682062c5e48d11dc985d9f3c +5032,1f179dba62418e8b9e71f018c59a5534 +5033,3536d209d4b401db3bcfdce930310d37 +5034,705cff70be7629b9fb0045ea2b6657e7 +5035,7897ae741ad5b0c319d7b7259c3c3652 +5036,7bc378af53654aafd953bc672bf8bb83 +5037,dde7f44aa93d487558b1032f7ff3f192 +5038,25fcd92290837f136dccfcf95ec73976 +5039,16fba605a856991982e827417b08cd5a +5040,98af24075e3d7039d8c5cac48e2d5c86 +5041,c875aa45647655e59069c16d2ff8eef3 +5042,6bfd5b230659cbf9e73ad9aa218b2b69 +5043,34fe1698e12560b199d16cde46eb1e30 +5044,e19dcf2e3c19248d02ab95599f330465 +5045,c9d16fd2dd84471fa54a9014f1e1b37e +5046,857b1c650e9e6b9338c4e1d8bf02271b +5047,01f102de369b0eaa5a0eb44001cacb84 +5048,f1a54f19ebbddac5e8d9538ae2107022 +5049,99605f48b43dd86b6258e0a550956b2c +5050,3e2ba6db31788d8bef5723e121c6f6a8 +5051,087c5d07b79ba28172e2211cd036e5b7 +5052,549220a7008fb036c01354bf848dce21 +5053,1d6743c784d4f4e5bdfad848fbf3024d +5054,6200a505d90c6437f774c91a22250dee +5055,71b4e18f14894dd0fa20ab0a47adef39 +5056,7c2a8f3cf2d621b7d4cb384e8139cf6b +5057,abf2f862c253d5937fec8290bddf7b13 +5058,6b0ec8c2418c0f32f9a3b02f830612ea +5059,d061911d0e66069376e0928d0aa4a2d6 +5060,a072bfca5c4e2e538a9e3f12f3839b2e +5061,44de74362081a65572e220e773aaf6cc +5062,43293b9ed25664e8b39c5beb7f12758a +5063,24bf113ea2bb0d4ed084db559512a6fc +5064,0fba4ac121d536070ba6e9cb61eff2ce +5065,686e1b98de5aca98b053110755ab2b5f +5066,4b86951a7c015300f33c8967130bfb93 +5067,ca0c6d7b530347cdc808a793eca9b3ef +5068,2dc4f307aac87de3cab07fd9ed873ca4 +5069,31a7ac119c577ddb7f069cde0f865ee4 +5070,1fc21c2190d58dc6643c9cfb92f8b6d1 +5071,c161e5b8db1b0b995c376c949417d0e9 +5072,2b2c06aa455bd38f50c3dca9e0ec7186 +5073,b85a2d54221245fff8251e758f675722 +5074,5eeaf1a2c8f01fa02dd239a5f667dea5 +5075,9fd3ce52ac05bb384fac87a3f3970b13 +5076,071172dca39a39ed9c80c6903d4278cf +5077,9ed0cb0df6fa07ea71abc7c9d5df54c1 +5078,35fbe97557fe77b7036cd128d11c456f +5079,3cc5d18e360cdf78c28677d9d85221f1 +5080,5b3a6e8641cf6a4b9f12ff15d1e598f9 +5081,d04638143c7ff5fe5dadeca499d31295 +5082,6b23222d587b256e2ade478e278d0111 +5083,38a7300f63f93ea124fce8784c18b784 +5084,7dd892a3adcfd40031c8a8089891a709 +5085,dc0f6a317b83306ab226b6b6d4538793 +5086,e6232b98b69fa62a8202e0f5313a2f33 +5087,4e5cf6fd2610655fbd79081b9facf84d +5088,c0edd63474a849dbe46a6af271c0f216 +5089,3fde59e2a78bd56b338fbaf8f2020e2a +5090,e0b6d9a449545a0af7060cdbfe05d065 +5091,4783d368da80f8a04c83fc1010bc4299 +5092,c0b6c6350221785d4259e2cf734c8fb5 +5093,dbd59ca61ff293bf0cc9fa374171b8e1 +5094,f25e32520a9e25196ccd6514f4c5c8e9 +5095,004a84a06755a4a75a7963d364fe2e24 +5096,7421d5ed6af70c94b40a6d462b7027f0 +5097,742c98aedab457074e990df7c0eb307e +5098,b5dfa2e7a5466ffa3d38b95dd3e7b90c +5099,dba12bce7ab11f75a903285182a1e7eb +5100,9aa25719a326c290e4a562e69a5e6823 +5101,2bfa3f0504c4aa906584ca2def2f99d5 +5102,f514ff342241873f3523404ad40f1d18 +5103,4adae445574e33ffcb6e60078d47b212 +5104,a9dd6299d38e10916ab5de83b057755c +5105,68a2107228ef92ea9109150c862ea2b3 +5106,7aea1b96e77beeb18999460f363fa888 +5107,9373b6401007f11aa9e97ce355d5c817 +5108,0b931f097bf8f883f0c2dad271764ebe +5109,6461d35abd21be284bfcf09c94cb5c9d +5110,b471beb5bf645be9ee2f44506e3575af +5111,de81008a489568d2ceef2447ee70505c +5112,154ecc9a672fb41073210d1d0e87686b +5113,27255f761ca20a1a4c00d9c3543d06bf +5114,48fb83382d6c91e1921dedadec88fba8 +5115,18e851a5c2ca03a546e775f05d15e951 +5116,5343225ce527437aecc2b73e9d77e360 +5117,d1b3f18960d239dd691d69831a56f7b7 +5118,e01fa818213fd852e5dbb6e06835deca +5119,ecf78fc44ea12546505ed034ad445fe1 +5120,0b669233251207d436d23c512e7da2e9 +5121,233bb739ad16362a60425f3617d50fe6 +5122,c971178b40e1fba811c61d38899e449f +5123,530b0708927b4985d63ea9913b72921f +5124,826153eb473bda5d4d5c16c5d4292e4c +5125,9e2e9b3db2448feba402c302aa3de7b5 +5126,15859ddf6505d32d1b161060b1f87634 +5127,ae01a74d583114f14e3bbdc2d4ca5cae +5128,cb9199c8f5b23f603e2a3f6b3ebd65c3 +5129,0f8ae460189295f2c217da363b96bd48 +5130,a14f111577ee39baac7cbe00a307beca +5131,1a18ea82ba9cb0f5f3ecc58f350f7259 +5132,fd4d957b0f6ab9c1fad3742046ebc554 +5133,040dd60be53e76a7837305428e6aa9bd +5134,5fca4e7587f21f93824f010b1013f30e +5135,927a81f3213f4679b516ad9490796430 +5136,13f43e2b9d6e504d1af7c398b6bffa95 +5137,d58c957c1f05b2655b96132dc73df535 +5138,428bd1d0d570efa1ef03ebbe218f553e +5139,1f52594ce2779f6ddc0c73a84ee32cf6 +5140,5c6bf9ec9bb997d658a58a155f0a8ac6 +5141,e813e7ec170580c6f362bde5e4d0952c +5142,51a58481c5f83c9173478488d6706a87 +5143,384f675bda7430c84bde1f8553fe7f77 +5144,0c1a49f6c82cc0092555a3a4ebd9249f +5145,6113a747746b4d4fe8f0fa36a2f0c9be +5146,26ade76f1fbe2c07555c9f1c4004c7ce +5147,fb6f6da128106a07788eb31de7811b63 +5148,cf86e411e4a6e1d10fe09590ea835f8d +5149,6f881763a34b0e61acf878cd866be7cd +5150,ef6f3d724c735d873ab0e5a964997c40 +5151,d3a5f6bb11148b616c3cc4efa341ac7f +5152,39389a0aba456e86f593412a8a67d192 +5153,ef74136c2f347e018c3a2b85e67e4831 +5154,674775c186105b5ed7f66b4578d18237 +5155,eb5890fc52b10ce70bcb3ccf04d0d3c1 +5156,bad78b17369730343ff138d3e7225a76 +5157,6732ec1326f17ff3f30d68c2da820f67 +5158,3e1b419d3569b6f22cec1c9a96aae81c +5159,9a2c5c969d2d83d759e6398dc6536994 +5160,a585596cee30207ff206501b4ebdc6d7 +5161,99e5d3a3639c1239d4832bfeba62fc0f +5162,dbd748254956d6b46b3498d26fc05078 +5163,4846df84941f9bbe2608f0bfd304c194 +5164,b67627df6c720d4de92a53ed2db58c41 +5165,f468cee1bda6ea36c76e32f0bd31e3b4 +5166,d7a801152305e8f4246917201b6ef2dd +5167,db3377dc4e576d567604c52d24098ae9 +5168,cd02884bf4da92b6f3603803d5e9ccbe +5169,6b561c2ace00034f5316bfead4823c06 +5170,91f8501c5e6d25f2c3e7d560055f74f1 +5171,fa09ce8cd0fa232e9ec856d015ec6adb +5172,3b0f2f27ca58211424400f5a58cd8130 +5173,dcc5709e07f05e52ab29231961776486 +5174,f8bd62dac08b96c06c809a2be0502899 +5175,13d8a89b46797b3a92b4a56d77ba7618 +5176,9ffa3800eb3fb61ff834133743d8cd4c +5177,977b17335f1d13a051530c6bbd5d2944 +5178,9ac7f656b9ede759327f9de35710a843 +5179,d2c4b9aa58d72fbc006efafd5a7eb1a2 +5180,099179f80681471ae2560581cd2f49c7 +5181,b6881dff8567f4147cf9096aac00f733 +5182,a58c6532c782985372ce3dacbb445f62 +5183,112df7b7339750c537ea476911e9d492 +5184,a15a6ad4f73a501966d8538830832a72 +5185,03419353acd29e07eb5ee50754216029 +5186,d0451f653039fc7df15189fe0e658e53 +5187,52a601bda5b33487e356ea7b01f3284f +5188,bebfbeeadffcdac4e68033298e07dbc8 +5189,f7c53cdc997ab8a476b343b076c71743 +5190,a33721985940e30e46eb34964caf7368 +5191,a0c53d3a33b88cc57d2702b4babee0be +5192,2cd1894ddc070dab6bb7e0c0c7c6a956 +5193,e806ea723966a4791f032d03251edb07 +5194,31d2ad4c5bcefb507430816c79343c73 +5195,b0536393e06e91bf665bf417d728e40b +5196,58725dfb3f55da1e2bbcab92d647bd34 +5197,6b8df041fd6869cd4586ac35d01638cc +5198,1b2704cb9ab66d96da702d6e7e46a6e5 +5199,3a9ebf034fb809777f8cc94ff7c4add8 +5200,22c7bb370066c4cb2936fe22fe0e6cd2 +5201,204ae5aa8719639d715da5d8b0d8d1c6 +5202,01b6cd7a729bad2cf8fa8095cc29163f +5203,4e0709d9f55a020ba07cdd56149d6f9d +5204,57f3b70d37c364dd709143fe610170ee +5205,ec905e14a3037dc216c788e8f2399b46 +5206,dbc2b022217a78affbd68c55e09407d0 +5207,96a09fa3420d714522da1113d3f08b10 +5208,c4deffc6ad37ea1f03456a38d75eadb2 +5209,b380c6b26ad92a37cd9f9e0cac5fb2c2 +5210,f9c8406b2e15bfacac0df00862fa4075 +5211,adfba087a4910b72303b3bb19acbbd1f +5212,019661496c406dc5719b1fc362867206 +5213,12dbde305745b1742b9bdd3844158c68 +5214,b9f8fa63ba9f05e52200cc5e9a39ad16 +5215,5da5c350fc0f0f2707d69e3f2879b1bd +5216,4b9be748a1773278b9cf450a90ef6678 +5217,aefd4548ed86125e3c521850d30e12b7 +5218,c9c3ad9e46f70a8e107c2a592bd02cf6 +5219,dafa86ef6c78a7d1f8d0c774a2b5c955 +5220,075dd52361756a361e48aeb09874bd93 +5221,88efc145796f0c69a0dfa285886abaf9 +5222,822f9fb685f5f6a7e96610a2b48fe662 +5223,76bfe6e2608baaed31949b8bc43f3b84 +5224,7d581a392321cd305d757eae68ed701c +5225,f7dce025a4c0d71181365168d9adfcb9 +5226,653cd7332dc9bff00a3737ed20fea22f +5227,82f6c05b68a26b733145914d0a7b02a8 +5228,e13f4c6ca05e015d104c67671a6a0e2e +5229,24fcfa552d5b33c06c68a70ba599df8a +5230,1bca05c011199a73d44966064d3294e9 +5231,5e3e7c867ce27481bc061423af1a3fa5 +5232,97e065c441f99ec0b19b8ae87385e8e8 +5233,f7ab220ad09373964665760da86ac856 +5234,b1e53279c4424ae519d73e0b20368c71 +5235,2d2ecad835b6d5187b8f4207e4ed739f +5236,8a24f8c3b1124edcd6de9e4eae286943 +5237,c94c93a84c4affe8f853c7313c0931cb +5238,30ac1be6ebfcdfd3a90064c66af4cb85 +5239,02d041da1d26b7fef2047210462a578e +5240,36748ef0541fe628d486baf63792bf29 +5241,5cc8406c95f3f54e82f58e78bd9d0cbb +5242,ec078bdfd8809ce10936291759690307 +5243,dd313f03b9c9f4014de711f7bd1c0f1d +5244,3c56d5ef2a66dfb0fcd7a5b5e08b28e4 +5245,adf7869ec11db36daad6ca33cf3b53c0 +5246,4747a28c6400d842d31f6b5e2627c794 +5247,87d774b37092a0a6be63efe25d0d7816 +5248,84e1d322e7e51afa00ee0dc70b1927ac +5249,a788c28614799556247fdeef80c94b1a +5250,3afb7fc03855f1cae269f622386bf464 +5251,da46061d440cab1226fcf7208a4bd462 +5252,ee29a05d1d21737906a23c1adcfb32a1 +5253,5bcfb82edb653f42edffb0a84f15eb85 +5254,7a788f8567f4f045eb6bc488cc88bdfc +5255,80975f0a00f4e5a03bbc0140b0bad26f +5256,e5d3a2ae79aab163361c0a1e416f23f1 +5257,23f9b40b39046fc84eaa041a502cc062 +5258,6a023e2ab59b153cc2e238e8b549b9d0 +5259,ab9c0c24d81702e2443ef99ddd6db71b +5260,0ec787cd820bc10c7612479df56f9dc5 +5261,91da1ebca55c1b2c9e9472dddf48d39a +5262,c0aa6a55671e9bbecbc5fe46c7a8f3d5 +5263,573ad59b736024afc7adb13471a3f24d +5264,658e11b704f84f3c74e7af5a4b6a27ee +5265,fafbd6bb12683e6714b8aaf5982a5b08 +5266,74ffa53548ab8db3ce928f94a50a6e83 +5267,b1d93cf0ac5bf64eb2821ef1e8a051d4 +5268,90f95dc47997a15590b65fc82bf5cd70 +5269,1e6ccf3521c41a390dd20e6fdf331539 +5270,390b6f1dc8341700d8b5e01e36ce463e +5271,2f02526ef2b956ad8d3b17939776c08b +5272,6f89309f0c52246462374d19118fe347 +5273,10fd103b6e2a1e1777a09fde69a63c16 +5274,a322f57cec5e1278a914d5f56b8a8da7 +5275,f99704a65a95b765229d3952e322e71e +5276,bc3ae62f680cfe2e51b50df59439836b +5277,bf55d972161a4080474fd74ac444c59d +5278,66db78d428033e1ea8714782168d6c66 +5279,3d7be30296d7ee5c9ee6f87ef9dc84a9 +5280,c044bc4800bcf84f6310cc91a6be50f8 +5281,99f5ddfbe7fa2a10d9b02ac2d57e7951 +5282,1e0765943889234b09653c5d76464fc9 +5283,11e5e3b74b76c7d9bc7b00522f100724 +5284,993f0931b41995bc80f3d38cd4b4058b +5285,a8c606944f788e59e742f5cfc6a5a32d +5286,1c9871d169472e75832ff0e7f2af2f60 +5287,e7ca62adeee13614dc3b5428269a9fd7 +5288,7372b5898b37b0a9b9ce539a90e3ca29 +5289,ff8aad6af8431e048e20132c503f199f +5290,bd93f086387baf0cee6d5788d5957948 +5291,cc6347bb761476956acd53617eebf72c +5292,46999e30ea798a5e19dcff38134d0882 +5293,da9b29a8382f086d282addbd5e93f827 +5294,fe2f9d9a112585ecfd6d6f95ce038030 +5295,a0330e084364adfb8be64220a1512439 +5296,0cbafa1a9b9e85cad5fb60408845cfe5 +5297,38ebdc6e1da07f09bb15783cd982f4a1 +5298,f60960f99f8d630438a9ff36dcaf6178 +5299,3a2c8dd22c680f9956a5d1044fd319fd +5300,ce93e862524145799528c76cce341ee1 +5301,345eb7f4be88f6f2140284cb30f94031 +5302,2e17702843e2682e1eb9825c32c2af66 +5303,b8d8942be29eb429e6414fdd4357d3dd +5304,dce0f5249d21579d5fd64e4481bdb28b +5305,ed6373a1eda4a9f73118dcc33e53ea7a +5306,3ee8385e8d6b244847c598a175a6f864 +5307,5ef513e053f4b7686988ea2fa3ed89ae +5308,6814da143411c8c28cd4efc415ca76c0 +5309,2f883bcec47c1b6e6585699c70570bd2 +5310,82b35825156da3d6a83518a92d846add +5311,0b64977374d0d685e5e61008a2e3cee8 +5312,a796203acf07ef3ff03c3638bdb4ef5a +5313,46f9443dc8ba9d3b058ca6c01a353ef1 +5314,86a7fae1db1b1cacdfbdfb57deb3650f +5315,d74c47ccf5892aae6780b3dd6c9e9aab +5316,67151986c1fbdc23d2d46de771ff8448 +5317,c9c12bd8413f2c6a7385bf3c420ca555 +5318,3b832b4915ca22e8723b138bf586019f +5319,8753b7d3b08af86cb066db02398c7663 +5320,e9a0dcde61a822ce0763abee73873835 +5321,073eec9e1468deb5b42581203420f51c +5322,3841bda3d6f23adc1a41e9d96777dde6 +5323,a8f57562f34fe26eab909e7fae46de1d +5324,b5e1a3931d743fe953bdf6be6a894a70 +5325,fccccf8ec1354030a57886ed43ec0244 +5326,6194e48b5b40f81cf6b0aa96bca011ee +5327,818f4643a6c62660fb75ac107d87710a +5328,f644e88f69c6f9cc22ab9a9c8e4d19c0 +5329,391d080d809a561befaf70f982774dbf +5330,033908a1b87b1d525abfa0aa1d2aab55 +5331,44a14163866e62d5b14c0ba61c069d39 +5332,9089e8fdd701e233c4f76016e3d89a30 +5333,077fa772d7616457dcbc2acc8a2a3211 +5334,a8dc965bf57a84bf83f3903fb001f815 +5335,c942ccacb40e84c1df33eb007dadf4c9 +5336,8679a8ffbd8006f9bbb381a4fa554929 +5337,d774d20e2d297fceac9b58e271cafc14 +5338,2f1ebe6274323acbee0e1b887e79e480 +5339,f7838224ccfa7f7c1e4ec7fdce586367 +5340,d6c87f33bb4afc23c3f83e073f492e82 +5341,4edca615719265c1a9e70b0f7a668164 +5342,c109a64fc97d5c080a48ee3b78e1da8e +5343,d1b8935aa3b1fbc44041599dd2f43acf +5344,73e1f90501e84e0b5633bdd5f7523557 +5345,d753f666e62e44fdb23bd5e4f8c75f9e +5346,348e725de012b2cd2e157cd5dfd39209 +5347,394dd9fafc8e4f41828741708d2150bf +5348,9ae55ffecb76221276a16d8ac835d1a3 +5349,e95f9fce4cd1d9d9981fd09165d54217 +5350,4b76c8c9ec7e9e896bd7ddfa84906d72 +5351,52bbccfbc7878cad5b2aad5f899dff4a +5352,afb43b5ffe21aebad6c15180b49d16bf +5353,5e3b31881a2349520e8009b53fc605b8 +5354,0ee6c83626e7d603ed97e3a1f49e4b90 +5355,75908a908ba63b345984232beea0b6f7 +5356,4fa662d16a6c3df611409a0562a0b8df +5357,9d65d5e8983065263b6355fcee1b9192 +5358,f883abc01224f0cc00a9573e15042b09 +5359,c5a28e0ad524b665d0dac28998ea8dfb +5360,a722dfa9ef52f39ec2fb006f6212d89f +5361,a3d963f8bdfb74d80a3ff0dec6d9f7f0 +5362,a9401853eccca06054e0a96a70be33db +5363,e1439d1519fc65995b9a8fea5961e1ac +5364,9ca19bf4ee0a9818fa13deefc590cae0 +5365,475516b5ddfd934d125dd1285dcdbe86 +5366,bb3ed818b80d7a9a0176f4d1c34658cc +5367,ff82229918dfc4268d65866e7f100b2c +5368,199f27f3d380ac44a187af89d6873f2e +5369,5fba14c74d824cf57dcc0a39cded6f7b +5370,2e6a0dbf11fc23db40c075628dfcb031 +5371,5f00e37ec43a4e7357ff268fcdbb79ad +5372,1b9c5bd44ad817f19c57b52267fbcbd1 +5373,717893af99be80e8b9cd10594908db77 +5374,9ea0698e6f3879f84959bdade5c14026 +5375,43b37727f40215c0699e4a5101d75851 +5376,44f6782d272c94e8754c167df8884005 +5377,18384e8b2f81f0654ae32baabce6f553 +5378,f884d0c1de8c20a7a531c3ccbfea3dd6 +5379,b1df69f23dcd7a127f3c41d622b61a00 +5380,6cc2dbbc6d352e51684844b0959504c2 +5381,703780bd777a4cf326da940033e0693e +5382,cfe796adaa1085e6eb3e49b6530d221e +5383,d7c16ec04fac54dde1f00eb92849cda0 +5384,cc746c787def82701a31741f41908498 +5385,562a884894b0e3083551425fae412d8f +5386,f85a7de1c11ff11b2a4404901ef6f96a +5387,6655ab9fa550ce9d12a229198323c49a +5388,50a5c3ff7c7708f4c6b3e1cc2668167e +5389,811f89a79d18107c8fad175603ff925e +5390,7793a76b2678b6b7a44afc2d968eb711 +5391,e3af268e493f1fd950ab018c10e8ef6f +5392,79dd7082d71cfd461a198edc47a98e16 +5393,40794bd5ce4c5619c8076c12fe037dc3 +5394,2f30e1f4ebc1f2ad7db8669d9fc35b3d +5395,3e0f1b5dfd405d814dd6a23de921e820 +5396,7c79d26d85ce7221b741ad6426842d6d +5397,f2d36382894d2dd7028d126dfd34a96e +5398,19222dfa556e4195d34d0f09bbb749a8 +5399,23e93a82c302c46530d50cc2da5626cd +5400,3d82b5a5d8a5f66833a3c651be891cc5 +5401,a62d1f3538cf6899f8e9875aabc83229 +5402,fd155c196a09e6f80ee49f1f1ab9176d +5403,5432eb420bd89e8d71351fe1cbb514ba +5404,d40a90204fd621a056488ffa6e464efa +5405,22592bd45a03d31c40a35eab181a20af +5406,28a2e99b1a5495889e54ca6fff30344a +5407,42535374ea487c3d74c7e46a0c5cc98b +5408,2492411f913f839570f2779b39f1a333 +5409,26eabe7bf19e63fa56ed24a8aadaebbc +5410,2431ed5ea032da8d46f9f786c3b91755 +5411,a0161ff7ab832a668bfc932f5c41a720 +5412,08c4d3f6d654a7779aa0aee947a58828 +5413,b66f1015d8d57acf39198073dfea63b4 +5414,af053d93b6f82ed6758968ac4c55030b +5415,20f2918b02a414d586016cd7f2d5c018 +5416,2fec858c4e30e01e030615f488c799ed +5417,c380d4b78a3b12047f217140fbc60f70 +5418,759839461b5571d3f3c266f52caa8769 +5419,5add23a19dc1bc9b3d5d2680f16e263d +5420,f845f6d2e29c1b904504069c9b129f5f +5421,5f615a4e60f18c9b7d2260717ed24ea5 +5422,d114e2b9c6fb4a2f38e1a1f2b9fd8a1f +5423,33b7e4bb261bd1137057a3baf87ede66 +5424,670fe8b81032c00e2903c3fba7e66c23 +5425,0843380508c5ca51fa860cf5c29c3fdc +5426,5229b4135d434ff23d14591e8e57a6d0 +5427,79fba1b7181ae9a4c004267089d1521e +5428,582ec49228ee2782202d3dbd7833d5b6 +5429,afcf75071a9a24901d3a0e0a648dd416 +5430,5ff231c23a37a61fad7c8684bd61d9aa +5431,4aaeb5b019f678985c23790719dbbcf9 +5432,b57ae4be625d4cbb49753c5bc37cd837 +5433,64a947a38b1f357c470628029556a83d +5434,5ca3dacb4d88ca087152655271464df5 +5435,5effc770d045bf968f3bd1ac7ea0e1a6 +5436,540f18d0cb24431e0892dae79405bf8f +5437,dcbe82c0deddf9b704f35a632cf3d0d7 +5438,bb1a554fda5d32f29c65c9b965fdf2b4 +5439,38a3bbae46604da409224dfa98bcec32 +5440,3c7cfd1bffe3599385f55675ebfbb5e8 +5441,678677adb17b6c855c432fa491784944 +5442,1aed37b3ed638dd365c4b994f1390555 +5443,dbeb61705aa7d32173cd9bfcf2c1f116 +5444,bfa777318f7b6dd80c05d2cd3bad3c05 +5445,929a2089623ae7ed0c00300e8c19df6f +5446,b9b565ab3c2521c61b4bf5ef0595791a +5447,02642947fc49dd34bae8076b1cfc83b4 +5448,c7d80249d488fcb4f13902469f4c57a3 +5449,1a2c234faf6ad564161fcd3287be045f +5450,19335bb93106f56d301c55b23df8a3f8 +5451,86781f7378344bf11e6b03af8f5c1485 +5452,bae3f6281bee1570dc6bb62a68f32d6c +5453,3012ca6174d920344bdce425a5943a60 +5454,026f444b6e1cac6b07d05c049f16d084 +5455,f3d1091ca7bdc17c5e1073870daac70c +5456,8ab25461cf5c0fc6d54aaff8d4d61c7f +5457,a9c1784029344f8569442b422903d814 +5458,f5af1d13d9f649b0d009739f87949b36 +5459,8d3c40743f69a2aaf72cf66b6338034c +5460,43c01c231d66a217ddce11b1773a55e5 +5461,1d82793d3ff70a59a3399042c1db5236 +5462,6114e31a9776f1d95c0f0c5e383b1f40 +5463,525e8bf476669389f2917d41a9db2e47 +5464,3d5dcd7ff5a448458bab31a04f31c9b4 +5465,f40176d5f9d4a52bd19752d3448079ad +5466,f58b1b28df28af111aeeffc029a215c6 +5467,5cf84d538cf74f6d737bf9a31c368a99 +5468,31fa657c879356e0138e7f46a8e8df0e +5469,0ec9494183668317df48fbded8753286 +5470,919f4feda682a5ed27a0f9e442acd7f8 +5471,adf69b00d77a056eb8c4426dd32dba95 +5472,3169fafbf0a7667db2a3a0bca693ff13 +5473,f8dba932335f7ecd7cf7fbced79253bf +5474,a7e2d4d768bb3bcf7230dd239f1543a4 +5475,83f111a9286a56bdfc50f2a5d4fb3b0c +5476,ac5ac26c3f1f1e35f6bb1fee58ea3020 +5477,f129b87f2ea50253f42979e02c8bdb58 +5478,18b2f660ff55929dbe16eca64531edf7 +5479,600767196c483800a17faeb159226f60 +5480,828e6acd60f6044f6e541d99ace67e15 +5481,646f638e60795992baefc2a644117573 +5482,a345b85f10bfc5e9ac1ab6ffd283ac2b +5483,0da16776c9ad2a05f6361ed14bdfa3e8 +5484,a2969c212204a706013dc5f9edd2a320 +5485,38d671523beb03daeb3202cb951b4960 +5486,4b1e2dbc1465f0a1be511a206f5aa4b6 +5487,17d6945df3348011a0744e9f0b965b82 +5488,84f2b08f07c0b91b68ba6e82f97614a7 +5489,e4ba9855c80ba3d7ad2f0279098a6cad +5490,d3d385e5c26602f6a8a97738469dd8d4 +5491,39f67a231f66c75e13f0a7d4e7e3a06c +5492,baf7948dca584a5e871b1d501c1f3912 +5493,c08bf91d46817c73257558e16341fb81 +5494,0a755be688ebca34042e9e16933f415d +5495,607be09231d03e8f944935c55b788916 +5496,48d3d3f2a56ca822dad7f8946f131dde +5497,41e2cc15be5df508381eea485812c41a +5498,19eaf17c17c7f861eb4ea80c47eb8856 +5499,126e2c767f407928a944a47ffe0c461b +5500,2741aa298fac0123e4b5ba1f28b439be +5501,832166ed8009e0308b3ce9329986ec45 +5502,bae13b7d9cd001b82ea0c01fec1db5cc +5503,162e8a23b4e411e1e284c810f5d9e96f +5504,fd1993dc6b3e0b2bf88effcc11776194 +5505,520f8dc3bcccb76dad2e3750c6820c4b +5506,cf8d302425f1aa4aeda5d569e6aa6691 +5507,da3ccff3d9192b4e4aaf07a23d4ca8a2 +5508,1b5c131f2309c5160b08ff8aa53481e9 +5509,366bdfc2f23272dc03c279d69947a834 +5510,97be9e27d2cd45da83c961edbebc4010 +5511,01139bcd11f61d874a3661f70f394fce +5512,88b7f67093cb0f2804e664b667a1ad02 +5513,4bd73219ed5b63db4119ef05e0bb6bdd +5514,050e0de25841c1567d85a303286d9690 +5515,f0642edf8ab62025faaf4b601b15218e +5516,09b1664664cccbb997be930100231ebc +5517,481ab0c0c76de0b7f2b5d56002348359 +5518,b4d996fa54a653433d78f8382b17939c +5519,276e91789cf823396ce9ef1d3efe55dd +5520,2e3c096d2be403e77cc49141d5123e98 +5521,c7a436efb5428d9f20b10ea38a20507b +5522,1e7f47323c923d103d677e2e2059f867 +5523,ab3fed0200c363f072132224eb57e882 +5524,80fab3270a04a7d890a09fef51119535 +5525,c7096e8c85a1d479b51a467ebcb6373f +5526,855981faa1cc552ae1be4985a9247aaa +5527,c35d95404a2eba7b6ca9863a73601e20 +5528,51728f3ae4af3ebf22475b0e683c6d5c +5529,2af0ad630a7c906a6e2ba4e5805b2e7d +5530,bb52b14661d679adf61a224b6fe59fef +5531,1803e03d5db5e07932789dae2d666563 +5532,83b8119247428e4c9768cf96b62d6ae5 +5533,9ef96165b28f6b37eaaa2f55d021ecb9 +5534,b22aa1fa6ffb22d50d91e016b7f9293d +5535,858279f8c5ade21735f1b32cbb4b2722 +5536,47560af564f7466572203906baa314c3 +5537,db2a034c726819125731e8fe811e4693 +5538,2959e87c6f7670d71034e7273809e842 +5539,66cd4d059a853e0a4d66deb67843cf5c +5540,f1562221b0b492ad7657c12038d61889 +5541,a900dc926f318948c6a7d00f4f5592d0 +5542,d630d87f803f69da0fc63c9292ed34fe +5543,0538e034b42b8776e412cff597dd09ca +5544,5553ca1bfaf231427d233b1a9bdab6a3 +5545,d2952237694c70ae99bff77de95e809d +5546,dc6dfe0d2cf74dca261a49974c27d7e7 +5547,0baedceb82b3fba55d295a7a09d12849 +5548,cc817dcebdfd4be563fb5b09b330d464 +5549,1766c89f8aa9cec8015882efd70df97f +5550,288bef446aec4ca11c65600ce89084ec +5551,948e44a1da971b1c2d3ba4a102df6b87 +5552,450e0a0264ed6ac888963bfcdf6e2f59 +5553,be17b8491fe2933e76c14bdb48948198 +5554,258f1401dc3a8253daacc0787169c3a3 +5555,8f4d37577afc5afe9de7e3a41acddb09 +5556,19b6b77ed3cefb5dabce995be581ac59 +5557,a0a5554dd285d84ae27e8d20731ce424 +5558,1432009aaaf154312a8a9e51bdb17413 +5559,f29391c53f680275e80fb78019346d02 +5560,3254ff9de9fb69b66711aa11dd44fc76 +5561,0270c3c97904a22baf836a7f846bb6ec +5562,de2020598df2a544422489cbcda4ea5b +5563,0c40ebad182b793edebdaab5f6a622fe +5564,fb25906712f2cc45844f64a2a3fb204f +5565,da28980421fac0e8decf9f1d5427acbf +5566,6d022c9c723f625255cfab0dc65fb8e5 +5567,2de10006171d0288facc1320c162580d +5568,86f20863f81493b292c8e8920716381c +5569,7d6c36d4f36f4215be4f1dc9f30c27ae +5570,d541747b2627cc2462dc9fe6b74b022a +5571,4dffc622f03939caa512cf8d7d543d76 +5572,4d70aba6258fce9532f92867ed5608d3 +5573,8cd6e78f807036d2b4c41083c2749320 +5574,a9f0ab4b2bfb28a30d80195808fec4b5 +5575,7f85c47652aaca9cb655ff60136399e9 +5576,01123c6a460a2fdf4f3e9f115c2745a3 +5577,21c03309f8fdefc0e1b2601858cb1bb9 +5578,c9e014e29a896dc3f9344caf7f058afe +5579,4e44d9e1ccf405d18642b2d0f04fe793 +5580,e70168962f2ea144c4e326cab3516b71 +5581,de830e67d5fae586c1d234cfab28d515 +5582,bf70db860756a18ea4320b4931eb918f +5583,87c7776cf5c75d22f7318f8d598bacb6 +5584,e4c1f1439b13d410791a3eda54e92dc2 +5585,9e6ce58d99915b25ceb535a9d009ce02 +5586,da23b644c2cc00af1dbe3d7214c95140 +5587,5411880ba2468b8f1fa5561e901e30d0 +5588,a2e01fd900d86c4fbf529f5b08fcf108 +5589,5d0a683b1477f46db9610597776b5cf2 +5590,e5b83bd8d0c62dc01f14672efa8d19d2 +5591,082fab306f6607b7144ca9a23e28f958 +5592,1794723928b780999a6300153f10294c +5593,7d041858e1268d7f09394a70c2069e2b +5594,458ece3fbd6ae37e10617e882e5a4c4a +5595,b0227cd0531c0a4a0b4b4cbd265a3caa +5596,3d8c1c8ea682c9a8ea01a002c74f8657 +5597,22230d0822f274b7e8005ffffc0cd4ee +5598,68996ebc4cb59ea7cc04fae207c260f5 +5599,f1c678ffc9e6977a1265fe9360c20a0f +5600,bda1dcfc3c7c40442edfb4fb4430c2d3 +5601,ac8ccef17b77c472fef0715310019a0c +5602,ff1e258a8b4bca34385b33972c4cf576 +5603,070402ed6b54c2e8f8b4b082afdd0e9c +5604,4155dc8c24546b56b73043eaf392fe79 +5605,7dd0fcf67696f118640f9f898d37daaa +5606,87722427e9f6252384dce0678ff8e33a +5607,42bfc6bf51f16bd3ce1a91d280ba4e0e +5608,d4773e52283482ab881dbea78c02c2e6 +5609,797e21643ab73cdf2d6c1cbbb762779e +5610,0c05305cb1814ccf848ec7b3f939eaf1 +5611,00b946423e409558d7538652b6792bbf +5612,db7f186abdab13209ff870a0c094ef1b +5613,3053d07e7dc7c8366713663d8e73ea32 +5614,5d2b2921324bea169f0fe05371f6c09c +5615,7bb84b49ddaa9f63d5112a0dc9673646 +5616,70db631cd27e908f18863fd945735e78 +5617,06b614a208e0d2f03984f8192410d1a0 +5618,67e6b2c894d4ddef24d3a8e776f26419 +5619,e14178264cf497b97c094490f2d00d1b +5620,d1b32b41f3f8427944439282b63b4170 +5621,58a9fbb9ec3d092ed2751753f450adf1 +5622,70e92def7d57dd6c25d047a47e0bbd7e +5623,4e805824548c00bf3eabfd28f74df246 +5624,22dd0ad07bf9e73b87061f9cbecf09a9 +5625,b56abb0ac9820bfdf7949f4618d58bd8 +5626,104785c52a602626c2c833ceca9ab5b7 +5627,dca1516ed0d777f4fe77b2f2a3aa3fa1 +5628,dfa70ff0fc8c3250e40e9769d6cfd452 +5629,4336ee4147f2bfa9453cc94a155ed194 +5630,28a572fb6a4ba7698fc702a4c46b6daf +5631,8be99672267d9917f212a3e72c9e0906 +5632,7be3b31068dd902951c38d469e477c55 +5633,dcd63b7f27efb2e36b8e795998db6cb3 +5634,23261e2ae6ca16147fbf805c082dbf31 +5635,4bed931dc41040f50c47c8155b5d8f70 +5636,e7b9a93a05df4da0edf77be1ba93c5f3 +5637,d468eed890b00e123098edad829cd6bd +5638,d773fab5871b8712e5b45fd298b2b611 +5639,f852495dbd734372dec9d87a58942242 +5640,293d401c870757a3be423405f9abc51c +5641,2f315278fd87bf6f44a64baf134dbbd5 +5642,51a6548b1d232a6b934fa2ec18ee32df +5643,5bb3f350a114840cafce6e94553837eb +5644,12146f6b745a668c2a54cdbce66e63a0 +5645,9e2f9b0c5df001bd4ba9ef77a674dbde +5646,896de6e4e13bd90fc9e4e1c1d48a1644 +5647,9859fff3f70b0e737ce6005fc28bb28e +5648,4818513bf3abeb864ad4400c8265857b +5649,ec8164999a30f7d3fc464bbe676b1368 +5650,14dcc234e1baf8c0d80718cb71edc597 +5651,c47a8a548506e97f00dd092c52757548 +5652,af0a0175899e6e677aa02366d0e02251 +5653,bc9eb2bd4d72658b4d01db91586f3d65 +5654,7cc9c95e1a65a28a8aeb2dc367188969 +5655,0ef54c9b6d04093dfca841cdd317bd6f +5656,1c5086e90e7eab4993c5968d0cab5c28 +5657,085f6e69cefddd2a1946942d4dfed1eb +5658,226f3ef3f3d617b1473b0ae645d0d1b1 +5659,6c3a8d79c693308fb326651ffc5edec7 +5660,5fe7522cd5b2497fe5762b45941c0714 +5661,9d81e64cf7301c62a3760182de176fd3 +5662,33561d17cb1481a9b44a0fed9dcfb73a +5663,a19854bd22663164cf09c7f6e6261515 +5664,9f350e4e1ad34a123c887ebb8d5f20c6 +5665,64e39cf1a3530aa2c0ecfe87b7c3d236 +5666,b59c2ea3230f7f71f2c69bf915df5008 +5667,169124b44a3523983f82bc3d74158732 +5668,428066ce165d28be06c8d61a41af280b +5669,782c99d5f88bdc3e6c61cb55ae5b2e8d +5670,9c2da1ad9df2b28d3fd94453e8342c8b +5671,ebdae40827324cf6903630a156f6541a +5672,0be7318740431947e32d525b9ed65ebf +5673,dfefc36efe1c5a459ee38497cff91de3 +5674,fc70b52c209e13ae847055b5f389dbae +5675,f19603673a102c127d743d9b35ea41e6 +5676,13e76279ef2c669c599ef4731745ebe3 +5677,7c2fd6777000a6a5518cd1c438007036 +5678,93aa53de1093c56010fb03db15166e32 +5679,8632647c94d065e36053c17a83173d76 +5680,de5792f1e20def4866bb4e23335c0715 +5681,bf59e88a68ea290014b8f0d78ec773c8 +5682,6b3bb281cf3941569581f4c69acaa154 +5683,2ad6e5abfd73ab2f2b2e4a1052881871 +5684,712840a59d125d12858390c3f2fb2102 +5685,6dd40af7f6de983c38e93e718228a651 +5686,8acd287d7182cf45165be49725d8635a +5687,bd6f3a09989002d4f6bb61d7d2e54ffb +5688,fa1abed0cf392ca45d19b5d6ff4484db +5689,870b5db09dab8962f5672043c37412da +5690,fe2508e7384a752b29ec80414a6f55fb +5691,e47ce8ad6ab72a364861ed309b8add04 +5692,63a4f405faffb8f2cd63921453770c73 +5693,717895bcda601863ed20c1699d116c3a +5694,59bde37d37edc28cdebf6cb1b01dcb2b +5695,da160694267219a75243533bac623486 +5696,bc05c35568db256631b3c6ba454b3a6b +5697,769b83e9ab25db150734111d3fa8574c +5698,a29dd0c3827ed628cbc32a8282700fc6 +5699,1867a66d08e2dd297362a92e1071dc15 +5700,0de378019671dc88edde5d324a4e1a31 +5701,78ecab1763514950f87565abf0a5a155 +5702,5752480e54ed32ea5ac0a25a3fd610e4 +5703,29507d7b5bbeb28f3f966a598f2b5b82 +5704,b39726e748d9f1a9b582dde86de31a8e +5705,12851ad75a6ef14ec1c58621f24895ac +5706,12de05ebc0c21fba371e89f628dfc80a +5707,28a9c25f032455f65804eb603a012917 +5708,fb4608a09572d0150325346386c97a14 +5709,ba6075a62d8a748cf407aa1ebe5d78c5 +5710,fdab2448597ca98d65926d603951ce1b +5711,c2d2027f3024dbe6e3da824cb957cc49 +5712,81781baa7d06f8d81ef009f2b23e3060 +5713,a5cde7ec047e0326f0120a44281a2b52 +5714,d1f1d6ff7b64fd978088f1e3bb0b02b3 +5715,8f588e7a58389e78cfe8eefbe3ca25ad +5716,1d6902f6e38e9edd296fcff8ac273ccb +5717,b647702b0d68a044a0e7bdaa6285138a +5718,2e5caa42d7b0a16430a1e2b204bebcd1 +5719,7a290ad2ea6d4e2eb68fd279b593bcd9 +5720,67440590f9bab8329edac27cf59fc200 +5721,f6031af8c6a0f4fbaafd8b8542170cbd +5722,bfba80a842fb4aa0e7bc7f5ee9ff2995 +5723,b23bc732cc8ff15a8aac13e6ac338509 +5724,7ac4446d03a0df7c9dfbb148bbd1c88b +5725,ae2c32bc07ed1fdf07656b13eec5cbdf +5726,93e04791d0cbb8cba5d58d5cb33ff4b4 +5727,769dee89fb11e3cec79af9512abeb796 +5728,d80f0be0f1702df60de61a12bcddd368 +5729,ea8b716ceb74b4d38753d2e571b8c0ba +5730,827052c29ade7331b225eb5a4bfde699 +5731,377f89bbe47e99e63cb41b7189d85a46 +5732,88da8938a9b7b49340f3db2fd3169734 +5733,2adc0d41f05e513f5c51b56de8f78a65 +5734,810cfd13b5b0add7dff00665a814f1d0 +5735,e7b4c99655de66734ba951a276ca8bd7 +5736,0b6a62afdf3084d8263415f755988153 +5737,a969526df347298eae86ced33aada6fa +5738,95b99fc3001ffc1069f5d9a44ca82704 +5739,459ded7673555c64061f3aec2e7bbf95 +5740,7f77d96a9438ca52b42f35a0c770ea70 +5741,1ef311587df3b7e8fb057ba788714007 +5742,ae5a7addd2b1d33b4a0bd8a2f3b797b6 +5743,85e8f44b43b69135e27774bd737272ba +5744,5fb7704f1607a1172a318f3109738f7d +5745,083e00a97a71ebd72edfe778b4efff57 +5746,f524c8ab6c98a38335f6331bed525f91 +5747,60844bd031dcd71a027095bf72f1e152 +5748,143c830350872f4f70dafc9d04d1fc7d +5749,9b0d0d05ae83d994b8b8fd99ceb50115 +5750,263047f32dcee9d78ebd7517dd956c5c +5751,a747b284904ac6c64f065890547a13a9 +5752,85ccdd416b2130ec7e3c617a788ada58 +5753,1e08ecceb671ef6d9292bba74edba97e +5754,8311662f48447433b170378510ea5655 +5755,54f548062bd2b371c74e34827fbdb019 +5756,4f87c65087b662ce62a8184f97c355d7 +5757,8d6ed5ab092ec148a62992bf302a1dc3 +5758,3b7508bef986979c4a113398b2a6368f +5759,e74ec198fa78d9808b4ee97feefebd9c +5760,44290ba04f9e4ebb1b2353bcfebe3eac +5761,e224b2b45bb1660facbfa052e23c8c9f +5762,98a531788ab33a4d04497d1c670ec066 +5763,ff493d7e302038237330d411daddbf2b +5764,2bc8441a12c3535d0107a4661f1c7e50 +5765,33512d695b2dbe5f78aea5b3df7b3628 +5766,1666774a178825d91f655c30f1d25cd3 +5767,aab1d8d496a6417fb1a8b1d11a397ece +5768,204fe701ac32060b96874c66f870dc66 +5769,c1d70a9a0555a009e5ab9212267e42d8 +5770,3a995a6f5c87018af0358ddfd5ab9dee +5771,899d3e341b0d7533e8fbcc34ee29d5c9 +5772,0a08bacb934c1c8c0f80a00f3b1f2fad +5773,d052326a8ee983eca7ae285c8e68a079 +5774,c03d50290095bbd8506bc3d30abdc345 +5775,5a8bbea42de4d9dca4dca05f7332f633 +5776,4ca45149000007e0cb55d0380780334f +5777,c2e3bc530e754169cbecf72908f20d79 +5778,eec2de863827697f9e194a22c87f95cc +5779,1d69f2f4e9f876caa5be6e2d822c43bb +5780,2d8c4cf8c24b36da96ae057f0c0a03fe +5781,feababe1aee1dd69e1c87d3708548283 +5782,8a0f0c127bf63bdd35b3f6fa594ad5c7 +5783,07c2d795e9fc4110c8ccd032fea3a8cb +5784,42408eff8646b41cebbeb99bc6e0e9ac +5785,e2d8becce7f08b2ea13ab00622a1f79f +5786,cad249dc78bf4c40b11e8f8c440d64b7 +5787,42072c9833425ec71696bbd2623ff116 +5788,1786eee7fabdd53121889325230d6492 +5789,2bd1a0d6b3d6bc4aa98e2f163d0ac263 +5790,366591d70b748d035cb2b4db692237ba +5791,6cde54c346aa3b2fa448ec622b5729cd +5792,5b08354b3319f422c9e4794bbe193ea6 +5793,4cc04c3ceefe207bb93870eb1832c589 +5794,c4a48d018429b96eb71713ba55f6d369 +5795,05ca4083ae6bff4efab633f9fa80163f +5796,9c2033f0f7a5399a5c8768d9c0839931 +5797,9e52bd13d71fc7853bdf6cee5b2e2ebe +5798,fca80f1d09d18e1a164a2af7e5be35f4 +5799,ccc98aa97bb2668baa98c7a9f8a19d72 +5800,b63ca49016068ab3411b011cdd132fcc +5801,c540eb94695ed297d749112b3b2becee +5802,115e0f0c11452889c2f6e26476a4b649 +5803,e0261e5358e4fdf8fc4693b5af966d14 +5804,690d067879a7196552b20559704ec7a6 +5805,02df3f29d3f36c1a08d60d6867b65a7f +5806,f4847d6ccdc994b3ae9669cc0736e870 +5807,eb5283925081823db6104cde7c68025f +5808,0cedf38331fb830f9ad0a13d41a58de9 +5809,4538a504f768215467d65597ca92efb5 +5810,a088ebb24510ea4184b94c73001dfbff +5811,5a0cd8b388146b294a370f897f82bfca +5812,af3c38c563ad8f3c7930bf267a1cd303 +5813,cde571f877b8c90090e05095194805ed +5814,64061d028fd1f4681a1054ec2815ddab +5815,395871dabf99fd9801ee089964199cbe +5816,6f8c7e58a31a7e0da10ecf6b2724bc09 +5817,0ed0fce610424c2b7ba9ca7667ae2c22 +5818,b5c236082e00ddb7ce60ee0e57dd008d +5819,64cd50b5d8b252a38d59f552419b0efa +5820,663d6bcfc5056aed03536d543a718a05 +5821,9e28f68b5b293f2b1e0077a1dfe6609f +5822,588df4699268cf677e67e58e900416a8 +5823,ca428d406ce064f3101927925afedb8b +5824,7ed35b9327f43920dcbd94e0ccd7d2ef +5825,9a0972d77a9f0948b0b0cfae54c011d1 +5826,93087cc1dd5c2790f890353a0778783c +5827,ae50cc06c1400a1625bea92aa3743609 +5828,ca2b4ae479b52131c0c5913068337b42 +5829,031d07f360e830718737690e8ae5fff5 +5830,55a0cb46e85d07986db587d1269bc193 +5831,b883766edb40fc5944d3ae5075c271ab +5832,6b00d645445af2e7bc07a3c2902f8666 +5833,1a5593bb45afe460ff3302b456d8c30b +5834,eab016e708f00c260d2dea06d8861c26 +5835,9a367d9130ef880bbc4b4ca8b4ecda32 +5836,bfccd22bf50b3ba9dc74f8fac0420870 +5837,4599d5cc906a8c2cd1c0cbd5b1fa4d7c +5838,9c059b669fed1340028bf94b92952044 +5839,e99ebb5ad60c41733e696532cab99ec9 +5840,4c04cbeae124110c249d700ae40fbdc8 +5841,8b8a549dcea50fd922b14407358255e3 +5842,f0e909daf80609559cf33079987ca844 +5843,fa5d7d85fa2f7ed8a4d283abddb970d7 +5844,6eb90f96be7bdebf5fbdcc3d2d739c9d +5845,1380c58008f1b0b538548bd08be4862c +5846,32dbaabaca405d55e691f165cfeee2d7 +5847,69cb8c23dc6257d546b44d963a1137ce +5848,a68cde0d5a9ffd9b8285327bf72ac48a +5849,ad217fe5b6cc43078e5891a757f4d980 +5850,53d825b4b7471a54dbabec2f647bd680 +5851,f555499958007898ee7a7a6634911611 +5852,57efbca2d8e4eeeed6e48dd36d809fc3 +5853,ef6fc917a1354dba932130c097d9637c +5854,fd73363aa01b649efca168b7cdffd5d9 +5855,3f8f49066fd0e0f8d9c5841b30a495fa +5856,0de5babccb218196de52de076ff0ce4f +5857,355c21485428feb94ecf905d1cf1cc9c +5858,826189088477061c2b2ffd4a958a89e8 +5859,f72764beaef23e1617df0cdc6ddab579 +5860,531e05e73dd1bc0a1c1963d89ec78799 +5861,f248a50637ebb55b6403a08796083dfa +5862,8eb6c9c007acc563305a462c1429a596 +5863,976edd846274532eeddb28c66693bf03 +5864,2f7816807ed616ec227d37f852e3adbc +5865,c9fd52bbcf89b7c615226c4349396ed7 +5866,faaa8aba185bb372437461da2ec9397e +5867,537b01ee0ef6fd4f2fead76b10204a0b +5868,79ae395a3aaa91f4ae781143f6daf982 +5869,dea6407671a37cfcaccbef3b892c6253 +5870,310d1031753f5e15142f9e6e62776c25 +5871,a9e7609867cf796aeea7e83d63df59c9 +5872,609ab6ffc8a253dbb6c6e8946eca9425 +5873,1a67dd86f79ae88840fe7a75645e616d +5874,fbd5eaf662961a08d09b3b82135503bb +5875,8058ef31c6449a77709ffdd1fddb8e00 +5876,b75b2a7fc315bd1ae844c16a99841b4b +5877,28676a068117b878a0417aef44f2196a +5878,788a1c174377fa209f8baf4c47e0aaa5 +5879,7a0e5c891700b0f17e0fcf6fb9366194 +5880,63f95dd039db76302685b185419b9111 +5881,142426ac722348a15ccd8c740fcef0e8 +5882,2111454012c33d4ec37e568fdb0e065b +5883,e51eab9be32275cadbb28ce52582970c +5884,bf118a99b6f1a4ad988dd6e3dc6dc9b2 +5885,46f53f2e355de9515132185a7d70343c +5886,f8e14da2ef1da00fd2dad6624d98cdde +5887,42220652b4e249c169495fdf185868d9 +5888,2bebd5fc960f493f892deaa5419d6684 +5889,a95e38ba75d7f323831dde9c92f4d981 +5890,361dd3d05a0950002abb1d8453a597bc +5891,0fb8085a94260fcc1ac5b0df01628264 +5892,5579ae0aabafefb401169b51e8e585ac +5893,3663834f088d6fa3563b976458f63b07 +5894,302b75b434073281964f7072994d6020 +5895,d78a917e310aa850e9f8aeafebb6e4fe +5896,ec7bfb0d91a2a2752b7ed4d6fc48a0c1 +5897,03a6e32a0641d29162e19703896e978e +5898,294e09bf024d9839fff85ecc1d891811 +5899,26c617376bbccc238d8ddbac103b80bb +5900,fff228f5221d481e1e5ba375acf49c02 +5901,16645817792dc0040aefbc4f8b8f7406 +5902,30b5c6a7315b1d72a0c1cef4f31ff3ab +5903,766f7af5c5f97f887718bf828a7a0b00 +5904,4094ab0cc115184dcb991f424637eb35 +5905,b14e7ce19ea58d09a4451164d7c05dce +5906,dce2d1de3cf79850dd289917193bb988 +5907,1fd3cc7515933a9add863564c31d1d25 +5908,ff6892d8c74626c54c86660a57952e0e +5909,45127bcc1c2555e8175699bf74b3bac8 +5910,09cf1f77761b7edbe16d8a62a6fdb0ba +5911,2d56ffd38147068f9f0df1f2c2dea6eb +5912,6ecd0a7979cb441a30d692687859d4e8 +5913,ec7de1e8a212aad49f04bf9dbd4f1aea +5914,9f576f13dd5ef158bed6166f3592e253 +5915,ac9194f00ded8b4f6c570820f0d9f584 +5916,80685cb5ec810290b81eea4394021edc +5917,0e17043a606eea4f7aa4e3a2afd27ce6 +5918,cea1e3e8c62210b50123082d5ab477b3 +5919,3ab7caa25a08bc954f7ea2dfac6e12c4 +5920,19812647093061f074b44a388137f7dd +5921,41a624f30cc158ae2d9bda29d20088c8 +5922,b7036dc3cb78de341eeb0f046cf49c0a +5923,c7a0ecc9b6ab13d6ff9d7dac98deeb20 +5924,93f2834821d0b98a0e15f0f5b37ad7eb +5925,92526d809002c038e9126d995c4f4904 +5926,b3574ed12711f9f756b2e2b59b64ad7b +5927,dbc5b08d4476a954848cf37fb24d5528 +5928,4dfbc3cd3b7db5b117b2de46fa090a84 +5929,1a71483c285c028a021b4cf4de4a6a06 +5930,655527f95159bd595550ae6b04bec3dd +5931,19508d3258c4fdfae50b85102d9bd6c9 +5932,555829dc44fd040f5d34d94b55351e56 +5933,b7feaee2cf54328507ac82941da63fb0 +5934,5c60ba6852222632a7165558421926ff +5935,19e5764ca8b64569c082d41613263058 +5936,4dc5919e38360057280c1a75905dc2d7 +5937,21a39dae99b627a72dd1a0f9f6852ec3 +5938,249f28b0797e5d832aa89cbeef016888 +5939,dfa07ef64ca0a3e8537a21be0ae70fc9 +5940,315bbe6d4990b2082c3aa60176e412e2 +5941,f9ff5a9eb6b26c28f107644ede05c8e5 +5942,78b1164785416c38d9b76bb27d0d5a45 +5943,d5a9c6b25d971ff49080859433d8f4b9 +5944,401398bbaa2e9a5f88b2e4ec80042967 +5945,ae4a99e597760ba1eb4ad8104f5096d2 +5946,157d54bee990c01fab9af70bb4511331 +5947,6cc51a0691b97c1ae516e55e36d6b377 +5948,b60208cbd93d97eed1b43a5250597ce8 +5949,b3de18529c325a2a2bce4bfd83727e73 +5950,acd055b5fe4a8641c16f6c5aef8b25ac +5951,66e7dea66b0aa11367cd351a49ae6fc2 +5952,d712d5a7d1c72e95b94038852c6c7aff +5953,92e3568a8753a8223e3d17dc3376acf9 +5954,fd2e16b9ec8dc75439bec63f78e6e209 +5955,0331ead67efdbb802aeb79eb1ea29a64 +5956,ab0481d9c07c8dda965f18270efeba6b +5957,9b5db5e8205d34f2805ca8e244c9e4fb +5958,12bb6ccf67d4ed188211a3ee2bee0166 +5959,af96349458f1370a0357e11031ef8a3d +5960,314e19fe9f9e81791710303a21fcfc21 +5961,a305749c4103abd7545ed309b49932ae +5962,f698279f535ff52d5bf86b3a88002c5d +5963,0b77307e1f3cddc54a7f676bdf944a93 +5964,eda0ab1d2f09446d80127beee99a18fa +5965,096bd1f320490ebba6b11b8e6b978c46 +5966,0fed754538e154355a5adc2c9b94d41f +5967,200d15f493c6e0c8e94a59a2bc542ad8 +5968,caad016682ca62f54998e4b28913adb0 +5969,150df83a40c3ba51376660ce4a90f647 +5970,18849e0b78c188abf1feafb3fe0afbd7 +5971,dc173d02e91e958f315a1534bcf4634e +5972,b1b326a6f366d75603f3a87ac82a8c27 +5973,dac9b9fc4a2160b07315714a6897c731 +5974,0b6876ba3428d5e9ef2e13ca8a3799ca +5975,1c9300e1eab8c6e40827aa866e96eabe +5976,d871620cf8e35c5f3fe2fa9dc83050dd +5977,7b9e847595177b2ef342ef6a6ca0b43c +5978,ed06bc14e78f9b64b49447f7c1983ea8 +5979,97a6e6a1fd8af9ce1c729f732df98a36 +5980,4f92617c18b3d3e6254bb342b92f78b2 +5981,f104a51b352e22b1155d78fc1c6ea071 +5982,6d707b30cdd2f51c97a63c616940e2e5 +5983,e68355378096fd6fd209b39174344cd2 +5984,063592f02759464ebecf750f13306f13 +5985,42c7f8c2cceca4e3bc7f21c8f27b798f +5986,643ae94e8b15eabaf8b4e7df7188b21a +5987,bd4b47477471ec2afb4ff07c61f90d04 +5988,8e645f7a7f4f32d176e7cc8d26724ffe +5989,bdb03c992c955f1ef13cf60c83eed0c8 +5990,8f16305caec37de5b63e29b83f48f25f +5991,97d19eeb0291bacd191903a946a9419b +5992,6297fa84e4c427ba1470b95d3830a442 +5993,98ab7235ab3123cca46c54c951adfd17 +5994,d8bed97fa38932455d9f970a0bd2a770 +5995,1c127620b32ad731036a47dd9e26bd98 +5996,511a7faaee1efa1d2e1cc2cd96f949d5 +5997,20c2d89c1714d109b926b546b7b7e7de +5998,ced195f2bd954461abd38afc638c9379 +5999,a87b92f5284214f1816a495ea783f718 +6000,58dc1a93638dc6bf6e7f5089c9a9a161 +6001,f8851f7fd9ecb96a41cdbf8997036746 +6002,7927d0840ad6bcd44e797d0c2065f4a1 +6003,ac24abd795e32c93dc618c2d22ce1c01 +6004,4617b21b8352ebbe8e16ba05a5ecff22 +6005,686ddf35133012f04480c520f160cffc +6006,2b1826d08dccb088b105e9467f19d6e4 +6007,b8adb15a2af109fe9694d81e764706bf +6008,868dfdc02e8b9ca75f9f94529ad3fc76 +6009,06f053d53d1c6a1579eb55fa12a3c7bb +6010,723acd38c60e6479108cbd5d9eb3cafa +6011,b425cce4e889d9adb0c1c95b07d9399a +6012,06ce17813c6a6a23421dee6069723c15 +6013,f3b5d5ab2c2f64767fdd3195ab694d7a +6014,c1feb91b3404e97a9ff83d7796cca65e +6015,21810cbc5841576262588cf8c1e788c5 +6016,901b7317bebbcaafeaba89b76edd3d9e +6017,32e84f35c33eb2cbb3ad83a85eba5d2c +6018,f497354e6f07e348fe75db5a06db102d +6019,4f3480bd251c70d776d23da47e464b9f +6020,c02a3cba4636cbf868496fa08c2a26c7 +6021,898fd3b7ccf92938d7db311cb80625be +6022,5e2a37721469d61446ec7595d523b176 +6023,b3bdc5425c4945f3f0f24f623fbcbffd +6024,535f58824097e6642577898dc38e4b5c +6025,8c0ec67a97502cb1be72d56ac9ec942a +6026,e4847eddbebd41a9a9f980e2fc9d80a4 +6027,598c506aa58b3453c4c763a219371a12 +6028,f4ae0ed74c602f9d8733a026a495b2d1 +6029,7886e8c74945d32a7b39c5a118cc11e4 +6030,3a709546c7943db0992aca56251c18b7 +6031,69194f55b3ae62900e85f8ca8c842f44 +6032,3852d61287df07475cd9c29517fba1ef +6033,0b76ec6dc53761e925fd372373cecf62 +6034,b0bcdc716e773bcd8e05c37dcb3bd1f3 +6035,e1e341412475809640c076b6035d53fb +6036,08f39caf6f51e78837859ecbbff84664 +6037,3b0ec3206d7a0ec2c812e702182a2700 +6038,088e8ae02bea4b54c35d419ba0b36adc +6039,a16201eb2d27de2fdf88ab3b7945abf8 +6040,402174abfc7a1cc473f97c54eebfb252 +6041,ca324d47d97c14c8c25b5102d7dd7802 +6042,3372b44e00b772213cb87e47ab689eed +6043,b6a71accbfda72a10141479ad157686f +6044,43ea068cfc894169041f97013a1868fd +6045,caa2b218ac5907193f958213c7c80021 +6046,e69dbb05da6b54793b293d9045e05cc7 +6047,2f36de0760c6b6198ecf52683c53bdf8 +6048,30c14750a5af0ed1c93fc15a720be766 +6049,b92f9f4062ea8cd774abb7e5eb64ec6b +6050,0f620459afe3948811f9f9e56960b177 +6051,ae70f2fa468affbbdffcec109320f2c4 +6052,4e4231945cdf553d14e1a092649d398c +6053,8ca35ea56fdffb680bfd0d0dde88dec1 +6054,92eced46321bd35d822c72d4d12c000c +6055,78f03ea2cd01495548b379909b8a5e3a +6056,83978960e31e0d6439544eaefba6a523 +6057,63c7837681af24a3da2874790d9357b2 +6058,e710863a9d5201ea26b61bb52ff8fad6 +6059,ea9e2acf565090042ce193cbff509a4f +6060,78abda3a54875befb31e561e685931d4 +6061,c724e4dc26952bd2c6a55e0538ec44b1 +6062,4823121add4858e31aecdfe2d48aedc4 +6063,74291a6c317ee2e24542a295c8c8caba +6064,ba0bf0cbf3fee850e9e22a2237a9ec75 +6065,d35bb0bf450835197114144e3417fb34 +6066,7ee30811d638b413812a16aec75760f3 +6067,e9f316452d9ffd80e3274d110961ba19 +6068,c75638210122bf2b673c6e482cf57122 +6069,38fb9516d2b360ae7ffdc119387e9ccc +6070,adb67eadf04756767fa58f186ff0d90b +6071,cef232fd5c002ba0369af449fbfb99d8 +6072,4659894c3c8bc5e9ee29998bb2cf3c1e +6073,36c6861953d15548048e42dcbc8f582e +6074,e55511b90f6ea68009eb468d8c800d43 +6075,2631f230c12a91b57b02c9050069121c +6076,f08abb93e1ad7ee62fd13b301f4073bb +6077,f29d92c0f095e9d5c642a5b0cf71d535 +6078,b6899a51e73fa230f66be874e7994968 +6079,3bbe8bcefc25297ebb025ed9a2fb1f34 +6080,d941f73c1467193f6a84c69e152bf6fe +6081,339b96362a5cae08f154869bc3c9295e +6082,3fa3270bdef4a7040614758357fc1618 +6083,70c1793e0252b226e5a2919a1d780bb9 +6084,5662770223684d7ed1d91fd8e7fb967c +6085,08d75023c47d25c0bc6a17b804115211 +6086,84eed89cbef9c1f54068d3649afc52e0 +6087,7a32bfeb099da98b05c40832ce080793 +6088,33bddd1e67467d3afb11600a5b01f977 +6089,06b29f930cc98967fc6b166b74a37e44 +6090,8f0c21a85d8787b2b970cd3810c1a09f +6091,026bc6cb582336c4ff8c03e2ef211a13 +6092,e38a1c03f40b134d6f38518bdea83d5e +6093,9a87f2ea223a43cbe59b40e6cd239862 +6094,2de0eafac512ffb4b5d69fec405d9da0 +6095,fdaa9dc14a7b17b4c891b09634f4790e +6096,8ffe7a3b8802584fad24eb0028e214de +6097,58a8fee1e25ae0deae22fd2ee8089f68 +6098,15fc6bc26d184f694e8954cff256d91c +6099,4ed9215eebf5fe814f3c4e67b05a124c +6100,b0efb55e3ace156680adfaf73f4fa324 +6101,585147a3381e3bb3281e0cca9a4807e2 +6102,b56b01160d8a0a206b2880a368c2c5ba +6103,eb5c1a507faf95522e18b7a098d20f11 +6104,5d5927780326a79eec6413454ee19a9f +6105,f97d8993cba0af45bc113a792962a66b +6106,a5d410008871fb2612693add4f326099 +6107,8753173e9e3689c7d91d300624017899 +6108,2f77671dab6aa7a58a2a4f362f04f3c5 +6109,edfd8c11513cf664799e6e4bbc1c4ccd +6110,e99aaa3ecc525fb238e031d02987b531 +6111,3e8143670663555f4751e95daa62d843 +6112,1b06878e34f406b739a59331361aac6a +6113,53038973ce87fb03552b5a16cd455e5a +6114,4515263b3cc9d7e72edb5ba8d7f7b8e3 +6115,b927d2c5e0ffb3ac35d676a2f0d87573 +6116,af92c64a6bf647fc180b4bdc57e4bfe7 +6117,fb2cc6d744e426bd85a9f72dc30eb3bc +6118,05d9608079706d4f0374b28ab81caaea +6119,37ea9cba1add6fa2a18c48399ec94586 +6120,76817c1f6d563e5e355640cccba34151 +6121,ac32c83165f275c5523af49b98e452a1 +6122,a4813b7fb71bc2b2b358bba8fafb052f +6123,f5fb2eb071142749d6070ed70130ad04 +6124,7058e0a78f7a2c39ac1f2a557ed8147f +6125,b79ecd88ba8faabf16d57c2fa68fc96d +6126,5f1a62a83bf5b1db2d66cf556f94f7fb +6127,036a0107f3f50d67b48baedde7cfaf91 +6128,ac2755d71a52295ed2656d9be33c700d +6129,8361259f17bbfdcdacaf04c44b70ef52 +6130,68b488bf59d38a2a71d3f5c6d604520a +6131,ca33806ff6adb23694c8993953c2226d +6132,ac292a0d9f994744f920c8710851ed97 +6133,76dc34062112aa96644e0b150291f6eb +6134,7df2f23d29a5faaf755860d92acaab5a +6135,6a19e851baa460f40c80bda0eeed4bad +6136,6e8df1b4dd6ada0004c9c64001ce5b5d +6137,8364b489e8bbc0d18ad4f82d1828cf32 +6138,49764bf8ec10dd653254f2ff689e8574 +6139,46ddb3e844aadcacd6580badbfc0b236 +6140,13c0082e7113d130d8b024d5ab423782 +6141,b7b0e4726e28dc2cb01c3712be8a5098 +6142,42ba4ad05083dcb300ad4aeb6ca01730 +6143,80d558742dbc0ff75658927f8d599ffb +6144,3b2f3b7ef175c16342ba3856db4d5646 +6145,3ebff4044694c94aa215c42b1b4dd790 +6146,434c1692fed93c2ec57dcd80acd182b1 +6147,43773fb63e00f07fc3dd6ef1b7704626 +6148,947b038f5d1bd62d60a968db6cbadd7f +6149,dc15d1c5b31422779cb213e386a23cc1 +6150,9a96e0662c1f750fdf5db7b8b375b47f +6151,5f2f757aa0baee05a11c610fa705534a +6152,90b2390a9429e00458b5f17da6064f90 +6153,4a705535c9d330788b72194d00e1b765 +6154,41708fc86ee6fe2d2758a36eb8da1504 +6155,dac15a5c4be720a593c86fb080ea8c3f +6156,bb6bf8dda95c93043cefeae7e1d00c11 +6157,ceb623ab07734dc2c4cebd99b03a42d5 +6158,c43a89a460ac9d2dd8ca988e6e6dea5f +6159,1bcd6323c407464b7013bcc66ac5044f +6160,d08c3631e19dd32b79c771610d8302ab +6161,c37ef8959e4d29ed004f5e4136725137 +6162,b0959982821ca94191a048bda44d5231 +6163,1957b66e92a4678cba4c9d73cab28d83 +6164,f21dfee1932473cc43fed4eb184330b9 +6165,443251a6d647c5318c06d4047d8055fb +6166,855773523d40496b9a692a1d84d3fed4 +6167,97e0d9e4043941321d688631a251a8d6 +6168,bcc2f98dbb97a92449454a60a01823b5 +6169,9391fbe698d706d9250d1ce64ad3a400 +6170,48ec29e3e54b797dcbfa897136717f8b +6171,ce3254e33fed0f0136d3c30cec2c8e65 +6172,a1a52bd4d3f103d75a05bd03bf76e2e2 +6173,7479612f21b81b0df553cc1fe49d025e +6174,7468ff8ae7ba6ac275ff700add170be3 +6175,f92782db18f85cc76cc3b56323c84aa1 +6176,45113aa36d12279e3450108f63eeea9c +6177,4bffdd101418ff6a9977bf9c0a6e8fe1 +6178,b1731235b2bd5fc6dbdd999cdd0ed1d2 +6179,1f5636ab03ecef03cb30f0a5a9dd9d13 +6180,a58fb599aa6363b175d013541466cfda +6181,8d84541edc0a107e213d6fcf374acbc6 +6182,fc40fc51c30473eb84cedb6932b4db20 +6183,fe4c9858ed764edd7f4535608a199a4f +6184,809dfc3e2c99dd59cfea065acc137c62 +6185,4c21fc1ba81179eca119bae8131caa1c +6186,67d7268b0e9ee9439a0cad8a3989bc37 +6187,22bc9892f6e1083c1c75928c3ac3045d +6188,8f14544faf0b81e1dc68e4ca8a7c9376 +6189,f6866a1a1b68d54d8c864c3e457985de +6190,ef924ba43ea25f47b21ddfe17e0d2cc7 +6191,7bdeca024399ffa85648eb5c809a1003 +6192,7f87999b36686e8720303fe5fea11c14 +6193,5e8d84dc63b20b63bf2e0882197a9fae +6194,305e9a6f716644f32b60421508111cb1 +6195,02029b9400a1cfc94d768691ef2160bb +6196,119b87d9aef920d0b4eb4360c47beb2c +6197,47258d77a066aceba8c150b112213753 +6198,1afd3f1ecbc6fb5721bdf37fc1cfc1ce +6199,4ab661053509b6e4616b616aba4652b2 +6200,6106d32bbe076253645b10c87990145b +6201,4aac9257e103cb32287571e5f4e56aac +6202,50096942e4fc57fed4269fac57892395 +6203,49b76088b553e94d8d8ca308280c0846 +6204,16aa854ab0e51d57edb01ffcc163ad5a +6205,71d72ff8759e375a92421c34e02dc300 +6206,c064000d5bd1930c90ef95761d857c2e +6207,811a5ace3ae994ed3129e209e650161e +6208,3731fcffaffda003dc86dea621ce9e0f +6209,e6125664ac1cf0414421df4ea388364a +6210,33934054bae159288c7e794b0e019050 +6211,6e739d0720a96412c9681c82c5f21bf6 +6212,ea35d2e727630def5b3e9ff0f4a4109a +6213,9bdd5bc0bd13be7b08fb34280eb42a48 +6214,175018b8fd1b9e7393cda441881b73f2 +6215,fa19fa3a8dbf8801a7ab5b5ee672045f +6216,f820c864687f9afba5f9bfa8dd923384 +6217,754adcc1cdf7bda6aea547402bfb1005 +6218,726a62f804871c27a9951af996259f8f +6219,16747e7e6d75894cc570927b1470d569 +6220,b09017900c71c0e5a7cf4199c25646ef +6221,6476a9077229d8ac3c55cd7649770f09 +6222,400724db5fc50a81df0369dd31162a1c +6223,c518aacb1fcf5cefd9f6cd5152cd4cd9 +6224,c374f6608ad126da7324e5609a14232b +6225,90e36b6d833c2b1754872273254bfb15 +6226,e7bc8358b68fd4b9b6ce95510413c278 +6227,8e26a3174d0dcce370b01473c272e077 +6228,7fb05ad33ee9415136ce3bf03750c502 +6229,51f4ad4c746260e58b8163d06c5699d5 +6230,9632def2cf174d7905941af84dbbc906 +6231,13bcd48f2ed703a7c32d1ecab529bd1d +6232,ee3dc4089f23a99e9e15bee0610b85f6 +6233,82b985defcd8e4db1fa351caadac1785 +6234,48c42eb2109f5ba845b4488abcc973c9 +6235,92e73f76913adcfdcdb005464df8006f +6236,e14ba18c71be67eff3ebee4eb6d11142 +6237,55674d3b4a71682547d22bbcd28a524c +6238,ad2e69d63a1deaccc1dd94bffc30af94 +6239,3feed703005050d12af53e0c0741fed4 +6240,fcec469aa3ba9fa901eacf3dbe4e49cb +6241,6048c9728a7950068f43a1b464e026c2 +6242,5d97d82182fae13b80774fd0aed2894c +6243,bee4c49d584daa5271321c9e1b5224d8 +6244,8f5de7d13b460fc15715277910a0c441 +6245,7691a9b2567360ce86ff3725e7564e6d +6246,1bbe71848fc8ae2c593305df10c51803 +6247,7c3853f783347bde359f1ec87b8057c3 +6248,ef1a20f8365a221a0cb9a9598c56be15 +6249,7cb15f02fd9c065ef0aa31f82d46e6a3 +6250,dd9920212ff8383cfa181b045d084b8d +6251,2fe1aad7262130ec07bee7299191add0 +6252,ba429458c127d0662bb90189be04b7e9 +6253,f36cb5478f45895495d784ebf097295e +6254,90447ac2dbf042d8a6b4bccb486fb8ee +6255,7a2e452034f4c6ac609143dab7db4f2d +6256,0a68d7f046bb18774245652252d752e3 +6257,68379072de16308a91d53ab69ac174df +6258,1be81605eb353d067e13220717cdd18e +6259,8de696ec63eb67eb6d83d78065668f0d +6260,dad1e2a018f92a15c955f2d2124d768f +6261,9c7d4306b6ed654e74728920ac02fc1a +6262,1b27f4e9382544c6ecc9de07ba30b64c +6263,30bdb3b2874ab935ac7a6401ee04f027 +6264,f21497c98ffa84ce522243c4c6b9db16 +6265,e63e9818319882177051e89b95353b73 +6266,95e5d4ad1545a4000b72d1654140bfe9 +6267,1848edf4d2a1bcc659d502ca55b4aca0 +6268,5d6fee1e180f7847c1df2c22c32ef63d +6269,95362d886d9f18750446b10263617f1e +6270,23baa17cd7f9e69c17bdafdbc0a3fd40 +6271,bb3b6d4fbaae19e5ca55b3d6ccd9a797 +6272,30adffa9b4996eb5ffb5c7945ba155ee +6273,8ee9ed2120539e8997a4456767fb495c +6274,787b2cc53847ebffd4754005551b3234 +6275,9ef5ab4c54e8d62ad8310df38a8d5875 +6276,3fb59972f4b6940cd5700f74ea9c97de +6277,674f5870d5215b92fc7c10b2874ae6d6 +6278,2d33a746a6385728d27ac8860069abef +6279,6feed80508bd77e49e2c5d9c7887f4bd +6280,5b7385ad3f199965fa2c222176c48a6c +6281,00e2d773d1caefb684f53aca279a716f +6282,2b2d53661d123e55c8a9def8d1a85e10 +6283,5b064ac1dd8d37e9b0ba4eb109da96b1 +6284,185eaedca38bb99afe1a4a90c87e3fa6 +6285,f41e3daf714b52a232ff7619b9ba6da2 +6286,bd79df19b1e31898e7d630fe1618b09e +6287,238b651818e91f299683f8eef2d59373 +6288,b3c78d57db188284773953f99d5a54c3 +6289,30817fe69fce2e2131e04d7ddf823b52 +6290,4c5d47ca36384c9b80a0b23a69a1aa47 +6291,2779f325b24a1963fa996e307ed69bb0 +6292,5fd61e041329f2df2627ef3c4979c7c4 +6293,54577875137c3edc34b8c6d140b397dc +6294,77f45a1fcf6040f243a845b8752e02ba +6295,8e79462c2aadd396f728fd2b098534ef +6296,a25abeb91ee0e1e832e54f0a52f3c816 +6297,04b6027d2dc920f8923d48807b78a3de +6298,33a7a3405723a0fdf02348c65ff8fbbb +6299,76550609517522067e1f658fd491cdcf +6300,148a3ca92b128a1b642d0f9025cc511c +6301,e105afd1dd0cc9125add061c392b9c2c +6302,687ba0cb150258d5abbb939bf3c0322b +6303,92936c234349fc080b3288ca638b6f15 +6304,b138d5919ba32a2506ad01f8c967fa3e +6305,b62f4614326d77261d7471852fb795a1 +6306,0a4d1dbd5d001a5418892dfd68cd3f8a +6307,5e627274968ad4f5e9c196a656629d5f +6308,daa7b9c2c8bafbfbf4aff460b896cd1b +6309,3b31b208d18212b5aac8edd9c9088fb8 +6310,513c5a5fbba44f3ea903c433c1bf3007 +6311,05fa55f0b8789f62d8776f0209508167 +6312,6f1ca2a5d8c25ba185c54195532f421f +6313,b62877f8afb958456457183ff38b5976 +6314,2ac09b042d0a8753b38d6b3cfe04489c +6315,669f49a4e4e64ba651596a5f1bac3d78 +6316,f9fa04b72aa3f56258c9626454bc4079 +6317,0d5ab25befd570b8dc229dae6bb70870 +6318,9aa3c440afa1914e549e217eceb4eb16 +6319,3130265a4be75e014535293178c9fddd +6320,22c8875c30d7c49257a8d5c387ebc860 +6321,13b3cf8c6950382a7dd6c3fde15820f9 +6322,4fd0154af75e0c02aa91f57077d4792e +6323,af48c7b8672d534b1d47a10931a1a510 +6324,16bca4ffc1d947a6b69388976bd4112e +6325,d4976b6c1cf85a4be83f506b42201afc +6326,24ad6c3e58ed338a00fa83365fdf1fe0 +6327,245d694a387901f760ed0f23d763421f +6328,621123749aa3c4bbee55da0455447887 +6329,7b68a67d9bf8cd439e8da74ff3920370 +6330,d12e5adff05ed3d683644fc5cfd13be3 +6331,10f2f42ec125d472ae243289ccb699cc +6332,49094cad20d58a6ade60e4d56ea883b7 +6333,efc3bb2877f69ec77002db53fbec1528 +6334,113493e77dd2246ca364f34a2b56ea8d +6335,6afa971866afed2b8c2cb410c30d3879 +6336,de1fb231260976a8e12aeeefe4c1744f +6337,70a1237de7aa5ae7bb7f826e22ef2aa2 +6338,0ef06e587ba5185dd6b8fc9f709cddfc +6339,5d8739213e15aae8abf1887a9bfec0e0 +6340,fbc458359042fd1abd1298f98a1ffcc6 +6341,63ceb3ab9a2173ded74b171209c83097 +6342,2a388b62fa876dd3e48e7fc834108228 +6343,d16bcaf9c352bfbc0aa1eb5bc0caa631 +6344,83ad9df81fd08a0399499a5045f47ace +6345,759ade6ad0243cc89a49ef998d32d4a5 +6346,aa17b0061f3022e310e19be441dc3838 +6347,e6428ea74c45ae68a8917b368367415b +6348,716a05b445ab21d14ed2bec1db6762a4 +6349,502d2fd231369f3da0ad41f8f5ce3cb4 +6350,31755ac2e618bfcc919b676d37f6765c +6351,8366c7c5084361d17e5c8c7b16586c41 +6352,b2716e2fe31e909f13f796b875cb2d4d +6353,f8223ef223868d362e073d5c0c7eeaab +6354,832ab4f76d169fd0e40cbbb8beed0b65 +6355,baf882d97717b3dff70fcc4756614f66 +6356,7fb46a7a8ec761c18e65b1bdc06a767c +6357,8f2c5e8eb8d0b263e603ad191bb8056d +6358,bd9291d9906b401f122ca8c9b1da49fc +6359,8d002f432a5d68935b7bbec5d37f35e7 +6360,555aa0f00113ce717ec3399289d4c484 +6361,eaf48844fc8cfd415159dda451055f3a +6362,49d5b855ee9f504fb4b879ded5c7051a +6363,0cc0dda56de21c10d2cf670f5b0a200a +6364,e67587d38b4b6eef438b1c20c5a67c0f +6365,4d73cd067f0736205a3a0554ab5df86c +6366,56f5b460db0f2a8ac9a9b9382f75c12f +6367,6203a2020be1f67e9afc1ad86be246ff +6368,2b6a77c38cb4bcdd2ad5be81c14f501f +6369,cb098364d1324029b64566ec2ceaf908 +6370,e9a07919c4799a2180e489b4ba7ad2c4 +6371,0a3eec364874b784a01f697d0e53886f +6372,8dd95c92a63f6ad1818567e27513c770 +6373,2d5599d51bd4827a35dc6e478fc4d0a9 +6374,28ba662cf6b20037b0345f60f314be4b +6375,c45fd6a940458f6af26a6b5391e2258c +6376,a0348b79b1c20c3f5830ef0a6701c168 +6377,47d558071a69ba4d165706db612ac8f1 +6378,2dcefa13acc75169714db982c1252a5b +6379,50230b888bdb20b1d75cce8525a32db9 +6380,e0b706fa669ab7e23ba8bec5a211a850 +6381,e42c53fc3ef914e753713e3e9991aaea +6382,db040d4b9e660d58c25150c063aef5d0 +6383,17d21be1832989b88efcc5bf82332ae7 +6384,a29b9a9eca531a90ffb537117c3e3a02 +6385,d1cb7a62b5022ed50446b2ca5431b7bf +6386,66a0d7aadac24f53e904c6a5552ecedc +6387,10b8b57de12a88d61020a269b1f67406 +6388,11699e930c7cffc00107cba20bcafe89 +6389,6e50a53c6a43d17374da5e4e7237e415 +6390,e0fd0856ce888b90134667527f663c6f +6391,c60021ccaafa376ba5b44870ce3d7ac1 +6392,42616ac95dde93e418fcb7969637a430 +6393,381d2a7750531983424eeab7aa1b2910 +6394,3bc007317a2291b279d18c31600fc346 +6395,24f577bb3163854764d71a4d3706d4b1 +6396,efdc633d2e4d0d32976a0f2e53e079c0 +6397,654202197771747d41c0d9c8de0cb3bc +6398,b3516b47b3cae924ed090ba43c654e7a +6399,e71e0b7efe97169d3c469fff6e5feacc +6400,f92338b2d9aa59f6a2ca23502d8b8f93 +6401,dfae45ae8725bf34999ea3b270e0c54e +6402,a8d5f74e4f6ddbb79b3d419e989dc836 +6403,39e78f55b9d17ef756e5d698c41e17f3 +6404,b5dce55118b13a1b23e873db6e94ca6d +6405,55b1f90646b02a280bc372f3885d3938 +6406,a22bfbd543d90e8d1fd087be7e31743b +6407,ae1a27109c7edb9c0bcf09101c5a7b8f +6408,9754106fe5c67fe8f10bee7254f83bf8 +6409,a748f8c9c246bf5e62378c818915724a +6410,2a03e26c92d2bafeeb5d2a9759da0b40 +6411,9bf566b55135cb9d384ed68e3dd3fb66 +6412,584fc435141d47a76f3e73614a0277c1 +6413,ce940bdff03d6cc6bd4a22d71579b0ff +6414,f65591acc17d63445b134c5818246cde +6415,b11323d9885ed4ad846b00428a24ac81 +6416,fca60d44e495efca081738475ab21b15 +6417,0039cc6f4a1892f32abcba889e415f05 +6418,ce1ce917698ab307fb2b1bf398b773b1 +6419,347cda80adfafc7d3ddfc6e656e97424 +6420,12b9da1867d415e2edc6fdf27e3b432e +6421,7ddb8f05eedb6fe59384b2fccebacd0e +6422,8a94011466df193adfbd14ed22d02e2d +6423,87a0cafc5fead6a16293ddac708f3dfd +6424,ab8da0df1dd73a2c41fa0b45572abe5d +6425,2661b5cee86180e9f74b5bd7809c045e +6426,0fcb015bd7f712a518f72b9eec115db6 +6427,80c01d9c9d5fb0a95f9214c44d211a07 +6428,1580ced14274a424f78c35fcf0a2ed01 +6429,4e06c55570dcb0d2525cd46f6db463c0 +6430,ec294f740e9e52e5f8e3c03fd02ce77a +6431,bb7e174923b1b4280280e02dd18948d0 +6432,795d23aae492e37139e40cd83c5656fd +6433,add27df2917d7c09cdf47624f680ee14 +6434,4d5154b90698c589904e622192ff3b73 +6435,7c2e212ef05f9a57a12b98bc1fc0abbf +6436,67a6835929269560aed035f3c5e5bf52 +6437,ebd3b93337cef024539efcee8d5debfd +6438,ef587763c4faef81b65c78beb50f7ad2 +6439,89a3bc8736d2b960cae5f8282427f43e +6440,15ff4abe6f3f522e12f584b0a26c5c22 +6441,b0b965d4fe969be4fce21e632629292b +6442,e4d1d17068b70576ea00a1d0ded92971 +6443,5476dafa535ecf502fd3fd9a639fad0d +6444,97d9cd5ff26fbe164f3322a5fa8c305c +6445,2a8cba99c30458de48d3b9e5dda1ec50 +6446,1bfa0f28b301f039948b7072bfa8a220 +6447,f8591c1c2ed206968a1b7b04966a5c9c +6448,3b4fc49cfa174761c7c5bb3ef779162e +6449,fd5fda2e04ba44e31b83c29811f2dca6 +6450,f8df18eec7e147c2f082b16edca44ae6 +6451,1a805b7954106ce746e3f88a4541f3a2 +6452,18edd80ff119282a0d91a548991d0222 +6453,aba4cab6f1de5579f1c8ed453d0baf3c +6454,15bd85ea6e72938dd5a29e587c75e405 +6455,041f9a93b5ecd57835d9d6b8ed3e9a2e +6456,b23159e1ec7234037103e8c199477b46 +6457,9a133fbce27e61749f7d8cdf602ae238 +6458,7c378a0976bbbb870385053e9d1eba13 +6459,2536413670f129a21985098ee3857d78 +6460,615cf040c978e5b4644382c88309d213 +6461,a191fa3ed5fb9309e010d33a62537915 +6462,47cde59e198abc63ee426b2edb40779c +6463,f773ff1dc28d729675ab7b8983970e92 +6464,da2ae719cc2d3eb015582ec058424a23 +6465,dd23c46df518c8193e724e6899209cbd +6466,791fad9db3a4e8da225e111f11559cdc +6467,7aa2e41550166838cc53fb5b08d8a7ee +6468,63ab1fa8ddd635e0aa578879d76f94d4 +6469,e57566f0e4876b7fade721a136398ca6 +6470,09ebe2ad5c64056ca7e5298c1bb95401 +6471,c6d6ea7ed264955f81991b00313f7cd2 +6472,b168f7e143abbbc82fa62a146b7dcdaa +6473,bf1a0d476695cfb778970aedc95dc1df +6474,e421d236b6dcda49820d82adc22a5c67 +6475,d352950d6ab32387166efd995786acd9 +6476,809d49d24c764e08207eedf5221eb6ed +6477,33e960c59650f1681536a1fda62f2066 +6478,90d1cab65d61d4ea4679d4b6ab093a3c +6479,d46e5fbbb1d70b662ee92214bddbf7d4 +6480,15a7a541bef47a24545bd1e0a027ec9e +6481,d62d2e22447f022d89eed0f84614ae83 +6482,bbcc44de0ac5580daef94f6cd3015538 +6483,a0504f7d6eae794a18b7d2cae35de8ee +6484,8c64617a6a2945e77495a3b9f681a900 +6485,d3deb29c868892f5932e9875ca64e60c +6486,22033f640f0372a53553682f536285ac +6487,fb67bffa4cc2e2d92379c13a542c6e4c +6488,e922f488eaefccec7d01527da6fd3e29 +6489,f9d531cefecc5ef3073d26bb33eea22f +6490,eb9dde2f52160d6c497a018782646930 +6491,162971e2a3b32a7280a8077c1217fae8 +6492,8e1932e2787dcc024370d954aa3a6f14 +6493,04b5f08f6c0d5ce19becbac4d07703ba +6494,527403b738424ee38883b9cfe24c3894 +6495,40aeb3d873b1b2a36903580a5bae3d52 +6496,3449eac14df1d1dec42ef7dd712fbd52 +6497,70d3b188d1fce769f649d1476d5fa617 +6498,7db737a74845b7a2dae20202f2b12903 +6499,56e7d5ce7847ac79e77dfd821b79379d +6500,c05b40f767075d427d9d725ba69e7757 +6501,df89baef2a13bd3b00bafe28b35c7367 +6502,e5c459fc566649759d9449c5ff43d9e9 +6503,7f521242a1642b70e972086c587994a3 +6504,762fa13d47153dd351790ab9bbc39156 +6505,6608fed47979a571456e6c059fabdb12 +6506,80c257c2db8255a6ca7cc5770c2fb495 +6507,365f0c39a1ce876fbc51a4f6402977ec +6508,0e0b2beceda9374d531ad56885fa11c0 +6509,5218450e43e829f8f5d580d318c6d7bc +6510,cef2c41d158651bd67cefe2ac726dfd3 +6511,af9988b9c5f1fc72607beb331e4cee5d +6512,07c88c679c3101b37bbc545f85b53b46 +6513,8193319ce72cca694f813276b21b06a8 +6514,dce9d6778ae29c3e3a395743970177d2 +6515,7ad5307755d3e918e2e6ce395101ad8e +6516,21dfede7c06d4a52571b6018fd535794 +6517,12b5d77e2d51b694c952a30c43584514 +6518,f2b087e630f6da28bd063e2ea74c9fde +6519,ac7b383df2219620ddef18d0637bb542 +6520,4befd320e6e886ec70e45a62c8562090 +6521,c7bffe6eca38752acd8555ad06b74233 +6522,9d46c50e42a36bb8eb6b40a379b7bf18 +6523,9d102c862acbe24ba3da84e69cc72bc2 +6524,a5adba54c24590349dad67f2119939f4 +6525,1506704c892111c3ccfc61373c1f9b2e +6526,26378230e171b502e712d23d380df356 +6527,012a3350b1b1f1fe6397c745583a0bb0 +6528,dd15187e2ef72843c7a5b9bbc6c0183c +6529,3c58db6742bede87c92f6415a5c87c5a +6530,50a839a7f31547686161951a50c052c7 +6531,08701a8fafd3b867c8065df37cb943ac +6532,32db554f3a44984da725b15f846d7272 +6533,32a7935f1acabe17b215b0368ee85283 +6534,12eeeec187ce2c65eaea1bc177b24125 +6535,e5e8ae9a1227eda654855584a8576e96 +6536,01cea2270e91d57615ff11d6db9d5051 +6537,a597bea1be21b8e0c3182c04d9d871c5 +6538,d3550294c73eaac9413f89fd44011e7f +6539,f76d22c75c105b2aec672cb8517cc02f +6540,083ebbafbb5f863c310318954d7d9575 +6541,82aec099535066f4c38951f7c1bbbafa +6542,7646134250c8ba760c2f4f113193d99a +6543,eae10230929d038550295f4e2298faa2 +6544,7e7cec2217f0c0202a1f2dd078a5c7f2 +6545,f65efc0064e7d63bff8d1518f402249a +6546,2ffa4e90418121b08561a6f80ae97a0e +6547,5179b6ca940aea439ed053c1091d12c2 +6548,a7ea5c51221561fbccc2dd9556938a49 +6549,4ee9bc7f3f51f486d6593121ade486a3 +6550,1cc21092a544a37b984a55ff1ccf39de +6551,226849bcf089373e3881861f1cabec00 +6552,2b33229628594ef455c6f50b7ba0d821 +6553,e8bfa8784b0c8ef81482fb964c3767a8 +6554,6409b7d921a3670226113f1273fb4fea +6555,7f5517e8e6d77bc3bf741365b5505c65 +6556,bbf7f0050ff9ddeab4dd918501c09130 +6557,4c0452d867770744424e16cb3b698c7c +6558,c227f81c7d8a730673ca9846659ad0df +6559,9e060bf6acc4a624dddcb4253ceada67 +6560,4efa8fa9739ed4eaa97e376cf53504fe +6561,d8416db9dccd18caacf38e38b2433f9d +6562,9477b1eab198cf3b0b4b9f3ec53fdd8d +6563,0cbd5b3250c54645cfa9d1ca53feda5d +6564,c7e1764c3ff273be2bfd4a81a14d807a +6565,17ea9237af92b9ef2f7831a4ff8837b2 +6566,36e527bf3c87c616f826437692c8577f +6567,5b990b2475b3c8e51a729c67b85ea2c6 +6568,f48f6893b409993d83f54d465603500c +6569,cafbc049916a8d1f16748f588472f051 +6570,426492f5bbdef04cf00cb71ced893d32 +6571,67becbdaee8dd5b7f543c3cd9cae3e81 +6572,63db903f592604669f2bc4a5159d80e0 +6573,e2a8d065f49646fdb5f1f80850a579b8 +6574,d2480d29732937344745fae8c5031c85 +6575,da43880b4f9d641b3a58d390349dc6dc +6576,16e8bf369de63e3746da9f10bb5023a2 +6577,5c4804b34c1ed1a65c25502c24238a8c +6578,a6bd8988be8ba4731103d9ab9a46d937 +6579,dd62660d8df544c287c46d0820b48690 +6580,8c5690597278eaadcacaa529c248aac5 +6581,310c5cf63d0a262d58bef15859128ec4 +6582,4da32b27022f34ef2f4c4d52e1773ace +6583,7eb3e3a0eea673826d60ea1579eba607 +6584,44e39d439a79216509439e54031515e0 +6585,b74a5d900c1822a13e1f5f3bcda991b2 +6586,8a0b9815fff765726d6146f4847f2ea3 +6587,5b4ce13ca881b5230e73ffd2b2cbd948 +6588,06cd9b884ff1a2877ecbe9a8178c5649 +6589,7ce420199894c566923b5cef520b6dd7 +6590,49e70473f4d515a0c735eafd6ee679df +6591,9172041595ac1a4909c23476a46ea831 +6592,aceb0af4b189f4f045538b3b6f8a56c7 +6593,d0ef9b8ad7e291c456d7d571d8226a8b +6594,52fe4d59c9353d2b8c55af10cd966303 +6595,f05c66c31cd792f247c91095601bfbe5 +6596,aebb9f4eb41bee9320c976247cf51e86 +6597,160675aa19b08d3131fe0f34a3ff7e28 +6598,225ebdc446cae436c444b33aed0b4336 +6599,ab85c5306f4e39e0ddd72b43ba002723 +6600,da2939fbdb99f9c6b4a4e7a52126d3f1 +6601,74811446d491b48a0fc2e0453fc4dfe0 +6602,442adef1a6b6c70a81086c90beddf2b6 +6603,3ee4d3353b51a02dfb01ae5a2591f338 +6604,e86f2f6962518fe8edcf7204e6ce334f +6605,cab053ced7cc0878885c814a6b9b9ba7 +6606,503b61df23f5e5cb4f171d1d11681e65 +6607,d0a6a431db528525221a53422af96f12 +6608,42d1e851ce68474034bacf75158ca8d3 +6609,5aaf50b7ce953ad5499a1cc6e67bf4a1 +6610,e2bcc15df3b043324e41c38f0c6d5160 +6611,6f857b332419595a7bc62fcf8b7f5bd3 +6612,aca262d26323d9758c2071f91b5efdc9 +6613,9c71661439049b5fc5520aca5cbb9274 +6614,ff5269f03c90d2239fd6c8a0f2274217 +6615,b7582e665e9c57ab3749d017c0d8e68d +6616,e6358a78a3231a9cf3796eceecad33ac +6617,52d5e1055057ce77e0a232192119842c +6618,9deacdc8100058170430ab179f6ca967 +6619,cb7e80a50396dd65878ba64405bd3d24 +6620,d9d026023033ebaa41f890b65ea8a24b +6621,d9ee7e851a0e4ab3fc6372ebcc47886b +6622,ae455706430fe20f8490e9a172c2d575 +6623,ead16a9e2cb5d7cfb583999de156a6ea +6624,6a024093902c87be53eeb61af0a52771 +6625,3c111d87aad9dcfd3c788ae581a00cb0 +6626,60754e01e271729966dc5e21ad9c448f +6627,b8969e0340b3797b00a48d64f4583db8 +6628,618a367c57ca11e4b952316f28c2fa5b +6629,aa1bae13154afafbee2163d94e31f910 +6630,24592d500a4473b6c411f9f85952127d +6631,c24f4fceb34333644bf70340a8aca522 +6632,588d1f52cefec5f24c01ff8099d2b270 +6633,fbabb996fa1761559172f92c166ad063 +6634,64a0998f3124a8836b1cf482933b5cde +6635,47c39b26fa2492e88df307b0e0f97ba3 +6636,4ec74db129b8e15f3178649fb61f315c +6637,8ca012550522d7bd787f8b1a7e0eeb72 +6638,1159fb47596e8cfb70277ff3ee83263e +6639,d2f1603a56bdaf3c1fed05da8a61558b +6640,68bf87ddb168c8ab61568148e5530742 +6641,44e8462c766de226632f77051969dd63 +6642,306ee09edc863761c389ca4d246faede +6643,80ad1e0a2c6aa980ab74003eaff5a4f5 +6644,36c586a6d62f9f367f5af5835d77c071 +6645,de8b205e6fbc0ffb37ca43f6afafb98d +6646,2f31c5dea722d7cbbe31d5a971851ad7 +6647,1ba2093755d55210510a4dc2b81bbcda +6648,2e26f5c6ecfc12df50735b5e3fa2df2b +6649,fcce299773fc9355b87b732229433c68 +6650,c04c30be0889a1e042fb1b71bce6e971 +6651,5c20567f12d5d40249c174e94396e3c6 +6652,2f9be5806dc64311baa4a6bfeb8e064d +6653,a42f69b47f4e91e60703cfdcfeba096a +6654,a6257f6ac8a08da0c8de6e71f95631f5 +6655,11f358dfa3d26475111395903e5bf616 +6656,dc448a8809340712e6d7ee61b8777c45 +6657,6e1c0a28e8b624c8781e89eb5e86f2a2 +6658,24cdbe0f86ab554e8088a6c650bdd2b2 +6659,0615b29091615a04617a6eca2ed19a67 +6660,6dfb2476aad41367de76c43bbc1a7525 +6661,a27d6e635f1b914c5c070327517f2fa8 +6662,ced52bb48049856fcc1f60289ff056c3 +6663,bbad1f1527a5771c3d827707c2bcaf08 +6664,93617e3bd8dd3385c2f8d575138a7e83 +6665,31e92738f52c60c0b8957d8fa7362c49 +6666,a55b9c71e2a93c235863f09fb75b1f9c +6667,4fa3058bbd0673cde30b412e114705ab +6668,00edb6f09455837efa61d53cba5cfd0a +6669,f5a9479d6c9c3c3a81bc04d40cc6a0aa +6670,0d503635d067a1621bd34b9797b8aeec +6671,aa43d8942bee9b1c1838de6ec24218dd +6672,7b6b637a2849514f46820f61c64f9aad +6673,c3ddf9f4bf9b4393025c2e8862f18524 +6674,9daadfe9c09e7aab69faba644effd787 +6675,b26b2d2418ef134aeb7185d0494713e8 +6676,34240055607132b38b11809a6f1a0f95 +6677,fa83de0f854390d2783d1301d0f15188 +6678,55216607ce6775b0d9974896099f80ea +6679,65cf36cbc07065701252a91ddfa84aa2 +6680,f3dbf0ec5ef584eb30095e8444f47e19 +6681,5d491d4c6365a39c32d38800a801d371 +6682,d989c593d245c6e05a454a095dd71e9a +6683,4cfb7ac3f8f2a7d9e32426e75f671d2b +6684,62fc2cac88ed080fd541cbfef6fc2fa7 +6685,88ef2ead17845cc71ba0da5271040c19 +6686,f488303e34f343b66f88ffa8c77a5833 +6687,c6040573336526a7c7b443411f7ca4aa +6688,581e6cdb4c2e6462632a1a0d183d0506 +6689,c8933c7c51b5c79093c4ce02c07eabac +6690,2872518b3110f9aac67cd731c81351a0 +6691,2eb3c6172232bad58347b7b8b0fdf5e9 +6692,1934b26e689766ac91856649ab691137 +6693,1f0181a493db24e20cf5a4a7b06b6712 +6694,47d9abdc48029ad4baa42fec708c7fd4 +6695,37bb1a411f2e46fe44516c1770913153 +6696,697af23b1bbd6e38ba992943550703f5 +6697,7589a2db9da9cd7b1a72638643ecadf5 +6698,ea069b2d89777741d6340bca31932b12 +6699,cf4d5756c223958c6d9931136d993690 +6700,8ea605f34a5ce929e74b50793b995b01 +6701,3225adefa7eb0b0069af6f27d068edc6 +6702,14c2e2c3f7eee1be01f0e0863480ca0a +6703,5b9fb0cee25b14cdb213d5eea60ad604 +6704,6ccb185514eeb115d2008c295f216765 +6705,4b9c6be4cd467243ce65e9eb00611e49 +6706,a98dbcfa75aceca0f76f7cfca6a88277 +6707,29eba52bed3b9e031a950b4bd09311af +6708,adaa8fa8856cec450c3f37bdd63eb63a +6709,2550e89c6f50f4e52e3412932443b0b8 +6710,048fc22ba899ee5ce8f812a22cb04c87 +6711,91b4ddddd7fdc51e644c130220ac7e4f +6712,5e46a30760a6c545b2e08bf03466e9cd +6713,e4c7693a15ddbd2a3f02166e2861a157 +6714,af2b8a3755120ed3f49f871735d0df66 +6715,cdfcacf234cf43171674aa303c10f8d5 +6716,72f66f6d88ea22a068cb417b159668f8 +6717,5bdf31157319dfe669dad18a41dbfb66 +6718,72fab381240f63c39ed5792f46be65f0 +6719,22d9ec5141c082e762ed3bbdabd89301 +6720,b9bc20542a605679394c24663c7916a4 +6721,fc10894f435ce3597cd00598beb7c8ca +6722,8e262f9064f7f8016c294ee81bbbed7d +6723,aefa69e9ac46ec70b614db8cd5c395b1 +6724,f6f428db7b37e27e48346785567ba749 +6725,9f2e6f08de37cfa8f7132bb442fb93da +6726,8ca31ecd1153b37c42432a346903204b +6727,8e8d88580d94a83f9db2d73f1a722d17 +6728,55761c0cce41f4dadf5dbbb8129a37e0 +6729,206cc5fce3cddc8d6efced8209ba7e6a +6730,8f4328e40dd09e403e1cebb6719a8a03 +6731,2cb784cda10bed19ea25593f4f40be8d +6732,8f0deeeb9505fb4428edd7935c2f69ea +6733,f74533d924ab6de7f09748e08d3c2deb +6734,77b41bb7e37e128a228d5d8ee358d788 +6735,834bb9137a5226ec46d4796f1fada240 +6736,5ec0b976415b38359b19bfd054cbacd6 +6737,9d8f1ad12dd1b77e8131caf4fe8e4860 +6738,048b4d664ff17b8079f5335a01717ff5 +6739,f5d881504c3d1d24671f87e8c7c3167c +6740,3639928af4e91c24d4bf2ff9f8e84e94 +6741,e92f87af9984da0a1f91508c2d6bece8 +6742,91bcc8d56aebaa0711420fef192486e0 +6743,a7836e89e5b7e0d939b2dc2b94f8e97a +6744,cd3cfb47c803e3e70e201307b8ea355b +6745,9c61351da6b9f2b056e15ea497a70767 +6746,5e29d1d172d8e08a7a24bdc5dd13487b +6747,19db40412d007fbf3e6e9db77df59c39 +6748,b4fcadf1af1a855f41859d8e00d835c1 +6749,06c6493c6b2215b508da3cf6fa82b13b +6750,bfaeb7b226365d5d3c4905f6d93d365c +6751,65c2c5c8b47067c190b71b88a0afc5ef +6752,703dfdb346e8838db3661f789ce17c88 +6753,3a5b59841cca271c73c542d327123dcd +6754,0b661ee5492d941e59bc835c54b7f9cc +6755,a2d61b4445c01adc7be621226bb57737 +6756,c4c31c70221be9f9f59e169496eae00c +6757,6cff0bc7bf25c9ab9f7c3af35c18fd04 +6758,af31279d5d0b7c21a44b4b97fdc9a23f +6759,812d18ed543dc8ccc71f58838ce68f3c +6760,01549e71a5867ae4271f9ce3b4d93adc +6761,44172a8e9dab6284d66e746104133fde +6762,1a0de112e9bca57fe2b92efa38d97d67 +6763,8b3c8ec2606d80061dd6246cecdbdeda +6764,3e2cb8997b4355f495048fba3e3e083f +6765,e00f9ef1d66ed0f3d0fde8c95d1a8efa +6766,076123587f2f2cc0878e34815591406c +6767,1f5f37b623f22041a6f43d9815571d23 +6768,b76db63a9a14e0638d09f708f9bf5c65 +6769,b59cc678eaf496bdac233332cfe0c934 +6770,4d7ef5d3ea2035d66692e9f5d16db8dc +6771,a98367f2a6934942250bd4f58311b656 +6772,ca607ce19b2c5e9ca686982345117ad5 +6773,30ebdd7d1355c3819bbee30a856f69f3 +6774,e7b38ff13be2367bd269d741cc81b311 +6775,262e3086762a0cf13d99deab2aac743a +6776,b0cdd26fc75583105a22c73273cae9b7 +6777,3d28fa8a216e424d7f8b075d42212d8e +6778,5dfce3c91feb9e63c8b31be7fcc4e7e3 +6779,9aad77d430ad1358cd881d035d317c26 +6780,2299d2a97e43a3d65d862c1e461b22bc +6781,144504ca61a633444cf39f7168c07c2d +6782,41ec918c6f3bae8f80abef1a5228135c +6783,ffd3c39c99331208062b96fb95d74fcf +6784,3da0f6c48a4b02195ce172f65c94a61b +6785,bf555423ea9a05b2848a062be4168048 +6786,e40aad27d92099c48b4e5fb3384192d4 +6787,027c0882a88953d798d62aa557da6b84 +6788,c13e50db4b0c809892f3f65a012d333d +6789,8268ca31b1be5515a64f80c006e6aaf4 +6790,39e9e4fe293dad380b2422a411d189c2 +6791,65c6c050ebebbef18802dcdda55081e6 +6792,f7568e86668d784c8ed7255a18b1a95f +6793,db86e64bdf7bbb5acb23c661fff1ac99 +6794,1da91add226ef39d5ccb230bad232ec4 +6795,a4adda9127a2563b7fd7c86523757922 +6796,76a591adae277b838fea2ce3e85f7aa6 +6797,244f3f443ea0b4c78633c9237a29dc10 +6798,aecd8494d7bac3f8b153016c1fbb1a05 +6799,dbe7931b048f930df1f99d8ea2f5cbba +6800,1b36c623b2a92b6a128c9dac87195714 +6801,17fe57564b2a7585c7dd63d7d120e1d6 +6802,630384f0bf526aa6e231a9a96bd956ab +6803,b66f0989ecd38678334d5ff80e68a306 +6804,a608673578c4f1c15c0f00c35dee8207 +6805,883d59cef32631568d5f1ae279bba730 +6806,1a3651b51d51e80700074b64b4dae507 +6807,d932ff29565c4a9c8c13ab425cb02b07 +6808,89f65fefe3f3e6bfe662c27619156496 +6809,fc992680ef51f9cdf82b73b65e0b61d7 +6810,65127aedd0bc6ce97c7cc0c069de8510 +6811,6bc00f96ad9762e4602d11e08c369f21 +6812,fc34ec0545a0ef61204a50a21c107010 +6813,8f57bb3ba08695078e85195dbd9c4dc8 +6814,ec5c00a6b3fa129f79d601f03d625986 +6815,96fc43ff805e87e41a8df468bcd717ec +6816,12e668093e96670728dd7785cc7a70bc +6817,3b9791b16a2e6740c1e1bf0f0d0387c5 +6818,46358d97fca2cfb682c4d13a31b941ff +6819,72b4fb988e30d4bd5b9a610f2b93fd36 +6820,c87272577d53d0ae109e846ab0c7041a +6821,f40aec531baec7f5dd408f3af5296ffe +6822,3a41e23671735f2c4153113b9086d64f +6823,be7f63af6b0449ec5ffb5a735ed7ef5c +6824,4d5b00bf08c4f48aad3a92a3297f24aa +6825,e71bc847cc2026342c26acb52d8e4eab +6826,ee71a574038b572b19328f6e17fa98d8 +6827,48baf241d7d4d8fb5e10baffc656e2e2 +6828,b2e56628712fa6a1f86a2bc52083243a +6829,bc900522607a3e8422198027db19acb6 +6830,eca2a674de5bdb256e0911204c3001e6 +6831,bee2912ebe005f2d6226487a1b6a9d5e +6832,0d9d38600cfa321510f1cd68421d86f0 +6833,bba8b4293a00f1338ccabbc73be77255 +6834,5b87445a0109554e52f314c936ca86cc +6835,75a569e8112306714c8244415e6449fc +6836,3e6176a5dc970a2e4fa894a0ddf3ecc9 +6837,4bd1fade62becb5f8721c547c3a1afa6 +6838,65020a07868adfc8005b7ea9d7642a02 +6839,99906c66afdf5a728220d3ab50522ff7 +6840,c880b69ed98359427da5cbc8b63199e6 +6841,acaeb17b01c3a9e042349675eb68110c +6842,764d5a1f5b2495ef4fe591cd4db528d8 +6843,0276953f4707603430111623896faa6a +6844,81d920d975c589a754cd0cd38ff77815 +6845,e01a172a10ef0875bb20448342220dc9 +6846,1d1458e223a59c7b3ca33ab7436e247e +6847,bd96529db95975d75ad0b143986da1c9 +6848,57608ead77f354cc858a1fc81a77e8ca +6849,8c353d07d7a831ee37e3cbe93159fe41 +6850,f8c4fd3767476678172ec76f8b935b73 +6851,6c28b807f8d35de9ac44f1821d82c1e3 +6852,064a6a6676c9f445026db2bfed136d57 +6853,70e9b5178173dc9ff152c8bda6f73990 +6854,8e9c0f0f5f26a542d88193ffd20394c6 +6855,5c109fbb1165895a3a28e2a2d4a1cca6 +6856,158fcfacb9d1d0fd3d17375c27eb5beb +6857,20b96d6e374c62ff47d6a94b4c3aa501 +6858,fa9510419b31c838f9de73580266db8d +6859,c94594b9fa3157bd0deb7277861fefa7 +6860,597dbeaf6741a95be4682835ec9504b7 +6861,435a63d494474d9f75a29f2312ca5ffe +6862,b707395062f9587148918bfd541eafe3 +6863,b8b054d30d3a604c0ced60ca05b9838c +6864,eb31c700cdfd5abf1adb335f77f459cb +6865,ec96d3f6d4cecfd15e4dc32550cce0ab +6866,0712d1317821d5bdd77fc7bd2162aa80 +6867,7aa3528a0dc2d701462bceb6abfb30d1 +6868,b4ed5df9e6c86e6e0bb247a5ca004036 +6869,f2626bbc5b7a02dca139ee63d108d1ad +6870,86dbec6b00e4591b231d86b07019f455 +6871,2c6d9d0593303c33f28da2881def7fa2 +6872,fa0e6daaf3d06a6e18305d6603e7a613 +6873,d6fc3685b7a953efa84c05b7d7648d5d +6874,a0ec6bedeea29e5b05dd8b1b3d6bacbd +6875,b955b2e2d4fcc61cce9c5398aadc930a +6876,c30c0d875d0375ac7d2d7ed60b33271e +6877,16d171c9105bc239223596eab258a58a +6878,0c2bfce78a54b3545edb828f9f48c608 +6879,c0833a78929fe10085757ae7121ed336 +6880,a05a201428d55d16d11776b8f92fe6b3 +6881,2255fb757083cb5a9b5733002423dd36 +6882,2fbff94fcd33f9f5aff3cc7b096eae7f +6883,fe7980efc78e1076b01ba78d0e284d30 +6884,a1bb4a4f152ac689a543df5155df48e6 +6885,a3f1a2dcc08c6d114cd82bde6e32007b +6886,3fba7f846ac0770e900d6d49cff2a4ad +6887,325aa959bf95a9ea54b81cf8680d5ebf +6888,b5e2030f24b9d90bca48438b83cbb8ae +6889,c321036cd324884d3aaceb20e837b7a4 +6890,0f5f0e22cce89f5329036690f80b13c3 +6891,27cd4a7a721d5c523d38405e28fdcc27 +6892,87732111ade41b9d0c0d5748f70f8688 +6893,dd6b5fc878dec4ea30b03d8cb8f5f887 +6894,52bec258419145f7838ca1ed1f18af43 +6895,5bf5808791939adc0d938bb36772009c +6896,da60000a52240bec34237b76b5a26e3a +6897,1def8c0ba6815695bdf873d0b2280a84 +6898,8b71a18d30a40adc553a868aa36748c1 +6899,72a06116df6279750638ba4089afc782 +6900,f8e28674cd6440a954d580fd90c29008 +6901,f63cecc5ec46e603555d26638b625cfa +6902,5eed4630faa0134fb6b1eac91b14d56a +6903,63d5346da3de6f3631618a943f379e6e +6904,b0cb88835dc5109424aeefc3e4018a12 +6905,3e9f191f58de22ae59242d3bf5a40125 +6906,9c8af814802186da7ecba71c219498a5 +6907,12f3fc764115ce3602004911de3760d1 +6908,8b5aecf62a194bdcb5036fe22c73e58d +6909,5e8012077ee12f8d8411acd8e4ada406 +6910,128f4f9430cc8a57435aec8a7a1d0c80 +6911,31d3729259ac0f871fb5a41715308a85 +6912,43a284c9874d3993a08277bae697e17c +6913,81f1cfd26c564228748d2780aa07293e +6914,e13d2256c223268ad68df56912a75e48 +6915,bfbac1d252f22be02e75df838fe38ada +6916,1bc5c55a59ba1931161506db1723e3bd +6917,e24769305a3ff1ebad15d18a259aace5 +6918,7bdf4f20922c5b27a41266bc77ddb453 +6919,fcf884944e4e441ccc1fa5542e2b0eb9 +6920,e38dd33d16d836453f5d08351c1d0407 +6921,711277ef7aa765e3293c4294ba500386 +6922,d9289375e56f99e95d1045c676117a03 +6923,692793c2a58c1d0fdfb38dcb130bcdfc +6924,c39c1a827ed925f0cfab4c6478e66317 +6925,65f6d5dbd94f3d206c6d2b3b61fedc5d +6926,ce51c86382099186ebdce6720ad3f56e +6927,7d82c2b4487deafb0183d0813a1cb059 +6928,81c3d96f1750468c628f72f0ef8ab991 +6929,9f454a46655e64aa7e2d338a9793aa7e +6930,3f52844ffdb0bb6ef88fb950a9defe54 +6931,ffe0726328cde9a9e9bcb79a497fa430 +6932,d740c5e3c7c557e25601c8b76e1a41f0 +6933,287b623714b290edf51a8cb4064bbfe9 +6934,7c1b5d8e9259f592f1d7d21a2895ea02 +6935,03c1316a1d3ad158e2470018bd84dbc8 +6936,a4da98742c1ca480443a5caffc2db630 +6937,c968ae6f0147585e346a0a9893328efe +6938,e8f8db6635835dc0161b71ee4a138fa2 +6939,57061f94a7a703ff7d8df294392c843b +6940,9dde72aeaa4e6a7840e4b70decc347ea +6941,d0781ec8c626f95d23d8bd9b5c866fa4 +6942,f4512fd8e54912f8e7c4b4a516e2af5e +6943,2bdc6368d1eb894ee54fe2769dfeef20 +6944,161089aecc8211dbd9633b0296e447d8 +6945,71047665d3d84c9850e62acd89501c43 +6946,8a9094313435dcc71ca413b4af7ae0e0 +6947,6ca3788f7cbb01ed2a896ae27adb6a8a +6948,cf980ee0bc5f217e9da4dbf9d4ce548e +6949,4097e2742ef19b4a557ca3159be45535 +6950,8e7580fca1d4b7f066ccbfb984e482d5 +6951,553af67d5954071b3ec511eb994544f6 +6952,a18cc8885dfad9c83acf3f45affd288c +6953,ad912c9bc63d1421e2ab2269578aaabf +6954,200fb1b9f50cfd9beb8ec0c1e8e51524 +6955,480a9a8797ef748d7d1d4cd658169f1e +6956,976fb8ef95ba2f6448b1584387051250 +6957,41580e80b8a896468f3845dd00f65977 +6958,ff8cbeb2b570082c479e487f96fb98d6 +6959,ed4af0064ab0c98abd480ee6a57552fe +6960,e503576d099f99352cfa96a21bd21828 +6961,f1e71b5ae9ba9fbb97269beeec4ef1bf +6962,de8edb24c4dec350cde3e9bd8df1b2c7 +6963,5f9569194c5dc658c628a4b51716bf54 +6964,2ce3c99ff45963da6df3620218b9ed13 +6965,b9d37e324575579d9dfeb3e16a270028 +6966,175ffbfe0a1d5149490b94f84ae711fb +6967,686615a6b8bbe7deb01374c55c8d6a80 +6968,e3d9d02d7ddf5cfdd143d61e37e5674c +6969,feab8f7d33c007d595ba6e40b3041f27 +6970,52c581bf4561abc6b859ce1af9c7d25d +6971,2c2a34ee7ebe0d6b3711d01cef4fbab8 +6972,d6bc6360e22a2376899f30df9fc967bf +6973,8b6fc4982c11646b82a12008bf80c5c4 +6974,7ede19d77cfbd93bca9aa89f957dc530 +6975,2bad5fe1569de79e0bfc0e810c48f264 +6976,842cc64410d4f64ad8dd400054c12352 +6977,dd399a9798310cb7ffbc8940c21fe4f4 +6978,0e567dfe7b485337193ac00075d70dba +6979,4f12afd39b50fd526a066f25df2244ae +6980,32792a349c12d59936012845cbf5f8ba +6981,0ae6332bc7c92dcb5bc26e20762bbbf1 +6982,02b3bbf6cd65aa8ed01c93b26aa6aa44 +6983,84ad5d342088c0af53474a04d593a39d +6984,a714edb5eee1287af817553b818b47f2 +6985,f9668b91f91c7c2888f4dd68c95cb5a9 +6986,34e1d69ffef6143985b4da110a1d7395 +6987,7a477824ed00f35c20cc602f3ee8cca0 +6988,7b92d324825c7b4df06b3b6d8b079e73 +6989,37dde747972584daa4f75cb68fef36e2 +6990,407397f9ccf468335e8e929e63df7581 +6991,2ba94c74e38f246bf51c544d0ae2b0e6 +6992,2b6856f8035eed5aa981a4feacfb0aa2 +6993,6ce4961422613d8357678628d839594f +6994,f0ad9d07469df738035c2188711252dd +6995,cbb4e1faec88ccbca79b0b98a2d04904 +6996,1a9e225ce24f66b800780111df4f88f0 +6997,11cb28752612c28c8ed9a2c58dab1c67 +6998,4a2797c8429718066758a802c99bd076 +6999,e265f0aba8ea9d315afe02b7d1180ff3 +7000,9ac9327ff62a4c3f958ca6f28a09c4ae +7001,56dba1e883b9dfbf41924ae132cebfe2 +7002,37437fad5df34c0994b6d1ad4f9cb288 +7003,e6078587be60ab02a82d8c2e1ad08e86 +7004,c5f04de778fe4063a74a015ee075f959 +7005,31adbd944b5046826fdca27314d88649 +7006,06f3dad99b6c5a856e8f8c78eb854a30 +7007,95f5c38ff4c9a48932acd5df4c0487a6 +7008,1fd1ee73922b2f41570c39dec6c21080 +7009,865c83c570c1fe7f8cd4210258f10b3f +7010,bd80a712d7f3d95bdb940f21c1ff321e +7011,e9e7b01f17c8ad87b88a88178a90c541 +7012,a07e4fb9a915113737252d782267cccd +7013,e310abd3f7bb07168d1f57cc6de6c05c +7014,c167ca4c06417e4e3c2fa1346018c078 +7015,86fc322741ff2bcdbfaeb9e77439ba81 +7016,4d0c6ca09644c2a8658403d6cee74009 +7017,a7b55fd7529d934606ff5146559304af +7018,393fe4372b20549f4496514b5b4ad442 +7019,657a7c00619f73f94ad49178ff0c998e +7020,4e184af0e991d0fadcb422c5cb9e703b +7021,5d4aff14b205d83d78b71b6a58ae82cf +7022,a69223c44574de3aafa28084abbf06cd +7023,9ed7a52aabab41198e9aa9d48082d2f2 +7024,03eeb7a61b6ffc9f4f1e5f47e24f0ad0 +7025,5159fde12ffd650fa3a98078eca21536 +7026,afd38c2c1ccab80ec3d8ae61bf77189e +7027,b77873a38bb2139911905e7121088b95 +7028,5befd79da817d17b5b423cf70c64b316 +7029,11391873dd7c52622f42081da9a8674f +7030,ecdf9911cf945db5da4c7d2a0a32e5fa +7031,245701626204110ca46846128d99516b +7032,e604c204a908208e2fc9fddbfb02c335 +7033,c24da7263ad8f35ef9430e8dc8601406 +7034,89cc2945b119eba0025d38159e1365ca +7035,8da245cdbde0e74f4f2a3c60752b4c8c +7036,980399ffb83c6eaa857966f6b1dd630f +7037,9f14023a078236de0bda18de62119adf +7038,2c38ff2ffc224f6793ba9e2ef0727fd7 +7039,3a1a56af96b8dea0d13734c82e7039a1 +7040,9b93c28b397de7a36dd7728cc497e6ee +7041,b37d4fb2983f24e3971a37087add8c47 +7042,2b829247be1768d3900005bf5757fbdf +7043,710cba1041ebe272c7006253fb8d334f +7044,537fbc5c854c77898e153bf61c621e2e +7045,6c60026dc3b90c8c8d5315197af8a66f +7046,15a56be482f6f9a3e81a47a2271d371c +7047,e92c4c513dcbd6c2093eb2132881699c +7048,8623a9d5389f462ec50a0128c9ff388c +7049,40ce796334fd70cfb08ef61ddda19131 +7050,1b532621967dfde21f6a5412c8d42e1c +7051,3579c7adf6d62970b8f9ff86ff1e73b5 +7052,661eab608d9f4e2254ffd8ac1cfec0a2 +7053,41bd42383250a5b162a27c5431150b1d +7054,f8b117d16e602558eae7873616f411d1 +7055,a494f1607a077742b2b0faaba9f6e4f8 +7056,67c1316e7d1cd0ecc3b5679f2373796f +7057,8afd6b804876cb76d92a7705061f5e3a +7058,ac40d316b4c59a9018d2160d407a128f +7059,bbdca595af5397c8f0292f956bbfe3b2 +7060,960a4f038c4574ecd524bde301a5782b +7061,ae6b452ebb0599591e1d4fe9a54cd2c3 +7062,ff73c669206dcc4da56a323198536fd8 +7063,27bf265cac1e8f1c65d249969621c565 +7064,7b278d78ec80b6baf91b9c0cdd87d889 +7065,89850cb5d5a15855ab419abb77c7bcc7 +7066,1ad2f8291942f0438729a123dae75bea +7067,d92bcfa068eed393f2e75ef75e1cf632 +7068,ae422dc0c9c3d622c57eea7615edc403 +7069,c265a68340d3f70b991fc1f18ffcd9f3 +7070,e78a5d2f946f74ef5a34b8bae9719290 +7071,7a6dd8da88a3dd475f03699a2fe8d39a +7072,b915a3b2b0b119e5b29ad97fb5a4bcc6 +7073,002a4c481baf5f8fea3ae59cae3d8a32 +7074,59c5d844095661ea0538f2c98f875b8f +7075,214683960481e95e8dab04efdc0ee8b8 +7076,1d94c14f682f64c9bea1ea2fec31f7ec +7077,7cab3736b19dd6154fb00ff770b8d7c5 +7078,2f3047d8417b99a693e3c45806263791 +7079,c49a012f7396c997b1fcb2a3db87cf4b +7080,623be8f5d93d1639d324608947235090 +7081,f2dbb43ed85720ab23a666aad2963240 +7082,1e523d3e0e94f2ab826c1fdae2af59d2 +7083,e41425d4a11d28f33d200fb08aed226e +7084,c4027ad37326db9cbeb86e739de3c771 +7085,e7c5a7d90d7f8f1b8c45809b7dbf72d2 +7086,5e8eb5c2578519de5913e31962d4646f +7087,696395aac74cf091673b26977dba6397 +7088,7160bc3c64bd762c21ca05c54ea75263 +7089,c6c072dc01ddd9ff8bb1afe1543a2252 +7090,ea82b0d1c2eeb031679662c591f83bb9 +7091,85c95c70bdb48eca4f35c74c49b089e3 +7092,25623c288d1095f527396d8f254055d9 +7093,261b2b69e7aeb46625eef2d1ab13b2d3 +7094,1c87b48c260e02b9295c46b81e661107 +7095,2324716a7f55c73aa6b99d5f3a1e4094 +7096,e5862e1af2a0aef422fd6c06d11853df +7097,4ee50c584639a6aa1f2753d44a1848f5 +7098,f48299641b4c312028506e0363d3130b +7099,16e2b0e6f917102cbe97e1c2c2bebca9 +7100,d3358c99543f57547f83ac6e67914299 +7101,f187cfcdc4ea48ed0a62fee3d1cfe327 +7102,bb87ba9d76cdeb936a15f905f507e3f4 +7103,0ce850016b7dd2e119da2da1ee196269 +7104,a71cea283f49b07d4ba7cd415e409f09 +7105,ab8c3b914a84039560e096e015a342ac +7106,d9e650f21090b3ec4c8ece4ae57b54ba +7107,a70d3ccec9743390336c3fa47e851292 +7108,e59faf81a5b76a80effaf64cad8ef9d3 +7109,78cdd865c772bd9f39d9b6850f9fad6e +7110,6209eae7ba86fc132e847b3fa533d534 +7111,b1ff6a48b12af67bdef5bf7a1424a749 +7112,9e17abaca95ef989d6513332258ef64f +7113,940af2b8975f840391123be1e546e32b +7114,044bbef187675f1df08472bf3c4193d4 +7115,050f0b097e5533ccd84a4f6c04ece24a +7116,94e230a4c125db86225842e2b3a5bff7 +7117,40ed835fcec7f719d4237bd823384916 +7118,c359b38564bc20d0fccf11bd29396044 +7119,6a1fdbde942c144618ff7ac12f194a37 +7120,0b91e3adc68a3c851970db3426d0b398 +7121,c91d64af246c2a00217a34c010508573 +7122,60f5a3a72b88b61506c69fd42dc7b2f2 +7123,3135b695402c36724d4a11c66594a085 +7124,5ab8eac2a59744b61f82415ef416f6af +7125,8e0dba307bdfc463a89a342900c5bbfa +7126,ce2ad176c37c36a0dfe11bcfc307a382 +7127,8cada837883b098c587fb867700c59d7 +7128,17f0d133cf9a2658d09e6f6aabd0b01b +7129,954fb06764f1f86446a197936967b6a0 +7130,5ee7b84a4c499291f8296b755060851d +7131,b377730c3688e259d27c0c8e3c5ccf44 +7132,972d25c41513540a8a8716d8b96d53b5 +7133,2e50daefbd23284e0d689ba0d6fde2c5 +7134,70ca39381e2f3c3f374927525b9d6548 +7135,f91b82643ffabde3c25b9a36875a3aa2 +7136,57812f308fe2c860745ce3ab52156136 +7137,9e4b5b7f273fdc24403b9ff720528038 +7138,7db9a62e68c61f8af3100ef39c108db0 +7139,2f3c1a20b4f6581ed781ac693389c08d +7140,311864d5056b99202c6e0a61acd1999f +7141,2c26cdfb4aa47db8a4f89d301d058d09 +7142,a64d830705ef33348e4c942e80683681 +7143,cc02e3eff8bcf6dbb7f38806fc6f171d +7144,9f0dc3cc301b00f1cf5c3410644ff026 +7145,2b3c3e4e35e003bbd90892ef5444a7be +7146,ca910e80fdf4e8c130f69f1f9de61732 +7147,05af63cff79dba98cbe8ebff84b922bd +7148,6076e48ed3e3c6ee99f07fcd19f16714 +7149,de81c57b28f2d7dda4c8f07cc702d044 +7150,ca03a06e7c6cf3282f53af92baf96eb5 +7151,6c26ed4d5e28755b02a88dad793d68d8 +7152,f2ea7799708b6a89286675c011e00ea5 +7153,42afdcac671d0a1586864d9f0b1d7b42 +7154,3d5c480939e9279fab395b4b709b63b9 +7155,7be89954a2ad521d40f40963869b1c82 +7156,7890487978b87871b8dcfc79290a9633 +7157,57783339ce73011033c9d2f6d9ed0479 +7158,80e7ee9aa17997118ee0cdca837d2bb5 +7159,da934f99d5c74d43e4bf72b27c64c7d2 +7160,8ab3465f23a38f276cefc6686b5e8ca9 +7161,b7934bc7acd82b929763ea162537d3f0 +7162,63e02bf8a9401615cfb5f8a18caa9acd +7163,dd6c6667f0cebe9d34ba2aa2fa1a629e +7164,6e5a3063b7f581904784d0853ebb0eca +7165,6a030d14f07f8b562c9c417985f337e7 +7166,36d7e51e1ef38f23b8392583fc84624d +7167,717699f98efeb79ff5e64f216b4bb59f +7168,acabe4f8cbaeacc11603daf1a215a814 +7169,d303d4d30bb0e87658e2c90688dc1a47 +7170,c07fda29cd4bc6f535965fd8a11c4176 +7171,518a165971af3873ebc271a76bcd8b13 +7172,1eb5a4d7c9a3e600030567765ef14bc1 +7173,69858c55f12208b5a4f1d6cdab700014 +7174,74d2771853bb1e97d9c4da3a19976944 +7175,04b78ad8d63528aa055c45e1d8cafb2c +7176,4899354eadeb8c59d5b78d6c99eb7f36 +7177,138b0996495ff1c3a7d25584331fdad8 +7178,45c2b1327a355c49e5420a3e723db0d7 +7179,be331bd242f44e7dfd949df3137cdea8 +7180,9f02f1c7d656b2e8f863c51f02322288 +7181,56007fc75cb59eb07d85f929bd849105 +7182,77180bbe53263363bbd79cf96af7d437 +7183,e85db5c20afed1121236000286a98562 +7184,e54a9f44aa5785e13d82d0e02ead460b +7185,709f97fb95422a9dede46e6e3d560797 +7186,f75dc9813447ecb0b6fd97a973133f2d +7187,d1d1a1062323d3d37a03a0e22989f0d4 +7188,8d4cc80e523b54d1b12dd173f0c3d622 +7189,44b692575292817b5933abc84756b10f +7190,4b21452f68e323654cbdf7fc2a7ac16d +7191,bb1c214fd97d32dc43a8121dd0faeb57 +7192,c5d5c93c58387d7f4e0f3a8c955183e0 +7193,934e7abf8380014caebae0d4dd1822fd +7194,747bb694871a3dd2ef0f0ab7e7955a1d +7195,803f0129252918197884cab1d3a99b82 +7196,4e5c21fd8c47f27f4e6a16ee20bf1044 +7197,0caf195c206bb7c2cec37dbf368301ed +7198,1c4bef8a24214a5da8c26c19763bb51b +7199,9e06d42825b8a4bbc75274c49bac4195 +7200,9b1a97f5c08ee810eec0635dbb0e7baa +7201,f221acb6b42795bea043bc914839db2d +7202,c510858ce6d7b65bad59761fe73ce81c +7203,ec724ef78d31d5c72c7e124ceaeaa486 +7204,97edefe25797232010c5f0190aa3a453 +7205,b063c0cba51a1a1d1a4091157086bea6 +7206,a33dd597c5ce3547b5cc48f48954dcf4 +7207,58d5e5898b3fc3c1c7209e04f2f2c0a4 +7208,1a925256066522a4efb2379fc8720368 +7209,7fabe1ce53692b855adeefe76b08f022 +7210,0a1bfd8ecfa483d55f83209594725e7e +7211,f5c8451a7cb84bea48027ed85c742aac +7212,c849bbfc88fef5ae145ef43d5ddf98d2 +7213,da000aa777035ead535130bdf6ff3988 +7214,322116ca8b67130ca0169512bfc76874 +7215,1bcd12a58c65084dc112585fa28944dc +7216,e8900e06dbeb03d7d79e67b9ca57a977 +7217,68ae4c5205cee734d522e4184bd772ce +7218,888763c8e2171547817f0c46c68e7736 +7219,3d448442c2a9d6f0465fb35650d471a1 +7220,6fbc84d661f83950d1ba49ccce062c90 +7221,ce406fb964c37b5e2972ae730c3aa877 +7222,7d5cc23b948b29e7898e698b30934049 +7223,b1b5f72f2a0857ba4606dcd55acbbdb1 +7224,ede21ec62e3f5b5d2cdec35f8872dbd1 +7225,b53d67a3b2c26a7cf0a0f9217e972ce7 +7226,817a131c67cb6577912446d3ced532d3 +7227,5c96535bb12471fa50722b50818575f3 +7228,45bd8997a95605d60590636b6651bcf7 +7229,3f4168942e9a2c73f93a564c1e9f9e7e +7230,e9a22f457dbc4bbed3c5f9f167d4d7fc +7231,b8a611b970b06fa6afd0873a82535f00 +7232,2e033a67abe3b5a41d43718c38b5b0d6 +7233,16122c348860e9239e4454cf129cb3f6 +7234,4949a7421cc0774f7c6341cc04efe471 +7235,f59d5bc0b26755afd73b4ccb7e680e70 +7236,220da977137466187a70e556324c66c6 +7237,4ce71d4f8aa66ad426af4fb8f95a6ef8 +7238,5b51ac435b8d8461d249af5d3b123d94 +7239,7f62c88c7e13c7b908f6d0ef990282f6 +7240,71fe3dab7ed51b9e96a323d28c8997c3 +7241,2d2750e2efd5df79194bb940f57adddc +7242,76c928d21b30a6ada152e5866ef56a1a +7243,2634b693fd84075465e758ac2ec9af51 +7244,e227deb3a8752bcc631000c004339322 +7245,0bf646603050e151bd08601b1f9a5a7d +7246,0af0f5579ecfc0e34c6f3e09343b7133 +7247,abbeff54471b5de526a3075fa84ecf3c +7248,f2d5c0ba5d7cd622a0ccb6c1348bf8d1 +7249,30274e98af6df47d083b1c9ed41a9e57 +7250,4f2176ba10a2f2e4a6bc08d5c5dfca08 +7251,d6582b8106be8f4da45b18760c10ef34 +7252,44dfbcb750a75be4a846cc6d6ff09bfb +7253,d57cc2ceff4dc7ab2aaabd0a5490e490 +7254,5d599f3e17331760dc2b0072bd75620c +7255,0e2a3a6775169176c1ce089e3fee09da +7256,6a6e4bb3eb31a0d440d0f1566502b103 +7257,8ebec5ce05e8f474f3ed2992a19ddbec +7258,886d13fd500701319fef0d93025b060d +7259,882f85483faff2be1774423929ac43bd +7260,c6d74c11046b67a08932a7f9ac84102f +7261,5537dca8cdb279dbae9d2bd66beb5015 +7262,c34f7e5dea2688cda64898d895e03ea2 +7263,1373552c09eced1b0523c9107b03ae91 +7264,a0b189116e7d87e92b86088962197204 +7265,66d617ae4a401b0e398fe9b26153f778 +7266,b0fb2d1fedf469c565f66a7c5966397e +7267,57b263d5760bb035bc691ab9abadd504 +7268,426150d8c08334522c58228d02e27428 +7269,c7a686c09abf803a67104be7f4dba44b +7270,141f0430833e4aa1dd440ccbfdca5784 +7271,bd84ac224dc26a0470b32a388033bf1c +7272,07a7c72a8aeca52b014f3210668dcb6e +7273,9f354b634e748566ede7fbc6adf25dce +7274,607dd9a76c2a5800003bbe25e0c9baeb +7275,2f408e7a471b0681e448f50831399984 +7276,596c6c08a3e73040e2b7717ba6152e77 +7277,d1c5cd7089adfa8bd39e2e7ffa32fb8b +7278,4bb8c74021022b819f5bc48058f4745d +7279,5aa88982f8a4409274d75f884b03f67c +7280,c4fba35d8622a8b487b4724657aee6b9 +7281,efaa4263705b350a69c495d76351247a +7282,7e0ee5d04c776e643094a4e617f4c5a8 +7283,bf7ebdc8cdae6a05c40423e8d9d5243e +7284,c6196a4eb36f578c229df9157f36e490 +7285,636a73fb0ffdde50fd16689c74bbc19c +7286,ed1e795f62e8601c3230f732201da8f0 +7287,57afa841113810422630f267fd2bd0cd +7288,957aaa6ae72ec70de4c186fea824d1fa +7289,aabbc9ae7a0521902b39b3a0f70f933b +7290,f9185b3a458b0c2f24322165b936fbb2 +7291,8529630ebb68ad15c3fc627037f939c4 +7292,7ba68574a2910ff9f0f7319dcfcdbdb0 +7293,b02662edf3f7de490466747c9094b641 +7294,4ef7dab1c46adefbae34b5fa63b97a9d +7295,5276074b6dad3194d11911b754eb91d3 +7296,10b9f101769d5c7c6ed9f84fe86ce927 +7297,40dd26072418a94a561712e4812b4db9 +7298,f8ece1cb8d489fcf50091b758ee734ac +7299,0541aceb337628dda233e15c585555f3 +7300,b7cedf75392c6cae96bb3c29f7c8273b +7301,c85dad9f778d487ae6b04e0fafd2db68 +7302,8b78fca12c146d4584410e69f8b11a93 +7303,3e6dbef2e04d9ad043bf04fd71f86348 +7304,ac8311acdaabdf19d55b4e6d1b85c6ce +7305,8614ce1e17a07d5b31db1f121a7c645a +7306,ea9b923efe19d1894a7f8a2a4525b7ae +7307,ea6189e4ed09fc878538e0fa4a672b1d +7308,20ed2e9f0a4a0add0be4786f7369663b +7309,086925689fed0849a92d63e612e805de +7310,d7718dcb84f0f56842aeeccaf2723976 +7311,465cc9feafbdc101c88cea638341e0c8 +7312,d17708d3e78ab6549e5e2fd97f641837 +7313,28955fcc6bbe6bf2d44694fea5b332fe +7314,080124a804e25540baeb6ee78bdb2fe9 +7315,aff022c8868c1772363ea504d35f83b2 +7316,d0532ed8a94f56091db2132775dcb6ec +7317,0dfb4b16bda4ac04f000dbb39c22765d +7318,7f1cb816f63b9d561842a8f4dcfc44cb +7319,9d7fef6720c095f4894b5d55f167a80d +7320,66d86b2f5481de77220ce1d98389121b +7321,302cbff71f778c29d839e9f438473c0c +7322,3abea08e1694b53de878c100e3b05e1a +7323,ad0d0f5095554e77d11aab1928f00b83 +7324,55f383baf048938637d8d12ab8e2f353 +7325,79c95be9c4604925a9c97e314f4a8c76 +7326,309b57d40d3021619a46e707abcbb907 +7327,73dad6ac481a8b1d7c5a4b6404cc0310 +7328,5c21ff50fc7906848c2bc562174ef19f +7329,5fd61eaf2cad9d75e53a7155a2504f6d +7330,f70253152431736586e6813adb7a906a +7331,ca081e8fd6526f9397b691bffd619b08 +7332,72a824a8fa583baee8fe89bd237e9c86 +7333,3ae7830145607410ebd4822bec51ec14 +7334,75cef55998a7b261b8dce062b0ec3ecc +7335,6db887e005b78a0771f396b7cb7b9f96 +7336,17d3caebdcd95de426bfd4cbf5a54613 +7337,32c5babfa60df7f4984970f200eb9118 +7338,fae578cf055be2949f89f627e93a55f8 +7339,c05af9408a0bf894756daee0288af96f +7340,0980ee6cee7d3a1252aab01ff8952487 +7341,f033904198358f313d0c8fd20425802c +7342,f607a22461251498e9b2b01048d95354 +7343,09712098fb1e61edb603e6a9618d876e +7344,3b4ec8eaaebefe7f108dde59ba4d928d +7345,2f0e6289b20ff9278bf2ff09dd762542 +7346,15f55f231d1058869338ce882f1655da +7347,1c0f4eba1beb0675a6344d06aa28d758 +7348,db0c88f0646bcf5c9d6e6159c84f4277 +7349,54ca45870242c7f2512bfed21a48db0f +7350,085a9251db2d245a9f92b472b2153786 +7351,0cae340708741a6231d92ba1e328801c +7352,9524440800497790d173841a3c479da7 +7353,41f2f3f4e3bc3d374ca831f2dc008f5b +7354,a2b12fd3ed51805eecaa0b315a26c63a +7355,dbebc1e3078cd961be157bd192212abd +7356,7bc1f8306aa59aabca664e0c93684297 +7357,5f306d0f6fae007381184a52060eaf62 +7358,c1d269e9935b1c774c849e09fce84fc8 +7359,16ee1b5d802ed24a1dbc1b1d93f99769 +7360,5b33b6ed7e5dd495495a2c6d29ab5880 +7361,364be37c1a0bf1335255c43324b6c222 +7362,778c62a1d0deedb472f20179945a298d +7363,4f5db09e6778e24c4c729351694a59f8 +7364,63b744892cf5bdea019aa32662b0ed3f +7365,6c33553250db13fb40f969c6a5fbe6dc +7366,f71199abe743f5edfaab8149bdf7c582 +7367,06d98216c06fd27466fa53e806d7d8ed +7368,eb8e23e7325771b15066b6c7858a4364 +7369,fd361acfd347301e053ffa1c531d0ddb +7370,5f467ce2c59e86d179ccb09974059ff2 +7371,317e0bd4b3ef411ef16c4e336e9355f3 +7372,2dc7b19668429d2884e2cd86674a2bdf +7373,0b968aaa2e3fb2a05c1098cb7766dd7e +7374,ca0754d486e5d94a6c05338b62b407c5 +7375,60b0699d500f738b6450d8f53e9207bf +7376,ffc31f7f68cbefda69265d8d03587559 +7377,e151bfe18ddedfc08b9893777fa4e304 +7378,7247eaf7e01c0b4470a06a0690a1183c +7379,b56ce56d30a47b3719a4014cc9d6d7ce +7380,be212c524d07aee08369d7f16344740d +7381,f671697a421841dfb6007689217750e6 +7382,d3a6c6a3421449cd9d4a60c2203736f0 +7383,a19fef1f1da53a35e4dce36c81cc8ba7 +7384,2a7e380943cdc7b8dbf1dc7ec567910a +7385,db11850360b3d593a59a0484ab7d43a8 +7386,c360214883d61389e96615024fee130d +7387,8c95b80d42affbda2a9be34e08719e20 +7388,ca81af8de1a1afe589e22d1fd44234dc +7389,fc9253c252e1b25d48a16e61044aba56 +7390,ccca99653d5d424251ff8734f8e31a9e +7391,d243c567f1b43b183ebc906d2ac9e549 +7392,f9a677e1aa67db702c5b1029571002e6 +7393,9fe18ec72f383213a89f3acd263939c5 +7394,d914b0c29e5428d544e1e94f789c206f +7395,b120c33d789597f2f887228c4ac55d4c +7396,f8da33fb703d173d8e5e82be428ad246 +7397,d98a44181cbb176131ec9be908c86592 +7398,5050c42bc63dcdd688f8ac6212cf60ec +7399,51504924951c2af3bb25d00ac1aae1c0 +7400,38cece2e261578c7031862808537dba3 +7401,e49de8c015c7a750a99990180dbf2f0e +7402,77f029171389948509434ec24a222c27 +7403,043461d2bff3da460b4919a59aa363be +7404,77ac54a53ebaa0a8933b608d98d17b62 +7405,1df77a14de7c73aba382fd28bd1081fd +7406,2f8de3966b7f02b7050943e74eda7f00 +7407,3d4b2e0f48be07e2226ec9d2418639d8 +7408,ff25339969e2b3c885788e27c2d7dc48 +7409,0b471420ae84803dcbc1f86cd9b0f4a0 +7410,7195f204311dde54f04576d365cb4768 +7411,0dc528e1cb4d2e99029e514f9e5bf7ae +7412,2d0fcfb8ff6393ceea1442ed1bf24a75 +7413,d94211e01fc55177c8bf13ba06edbb5a +7414,ef9ab8ee76cecd7d12749e6246a38ea5 +7415,ff51c7b0d5b1f0e3ede3db853ed9051b +7416,658f5030d565fa3053f3e90c7ee068b3 +7417,8c587047009eccba5ac1375df97d0e01 +7418,9ff55c2b105a9c046cd3941efc44f449 +7419,0037eb369b1d180485c7a7343b32dbc5 +7420,108d4178ca0b4487ec65fadc2cefd2d4 +7421,99a45098b6830a7b55cc183812898ada +7422,e97335234b35a9753e955b273987f0ac +7423,b7d3f8391c9b16f9f982a46fc4a18738 +7424,9d0a60d383e3534795306446cb4f79d0 +7425,da841768ea5a32ad095f8ff27b64c451 +7426,24bf4265de8fdd3e15eb6688d8ed744b +7427,1796e8a0f2f88b20fb33e77aa2e88279 +7428,4d2f6b05304299b45012ffd87f035df6 +7429,5141548665ba8e43bcb10d9161c12690 +7430,e3af92f04f900a57bf00b58abdcd4be8 +7431,4acb9d9dc3397a80ee8dfe9c7df62aa0 +7432,6f59a3d87d51bfdb3c8ae894d60cecdd +7433,2116eb57a440ae00a733b76cb24ef361 +7434,c716ebf86fb35cef5f11337557511206 +7435,f32f6872695c4e724f0ce0c230c5057a +7436,f049264f31f3c59d6b229c6c1de6b8fc +7437,e25760880e0e5a7a035a12ab37759727 +7438,f61cd322341c8b34b1977226d51fe621 +7439,f912d19096fc3a62a9e34a2226aa2b61 +7440,1bb8b8eae4b8ad760dab0c1652f1a222 +7441,227fbc8c672d1a75422ade0c9fb31e7e +7442,4281e4b2e7a5403b26db18ddccc8d238 +7443,60092089847573abdec0f462be1ef246 +7444,c27d4ad58b23b4543ff34b931ef0871b +7445,52cb31206ef6aaa54044827eafe6b489 +7446,cd0ca9da82fb9b40e4e332b0b7a0d045 +7447,a09e69ba4e4fc56d1c7fa10aeb12f11e +7448,b86fdb2705143b5b8c467bee60cf4a4f +7449,fe751b1f92b6272bdb7e0ae6e1e3f0c0 +7450,9f7f70ae78bdf915f3b3a6ff8873afb5 +7451,1ad0aedd386bb7a01d1c3ac17c960f2d +7452,6d864d66facecf9b908612c152f19632 +7453,c7e6921e84a91f4dbcf3988eb67ef7fb +7454,d607c5dfab67ffee904d784118e15561 +7455,bed46b843e8c2fa31f7d8d1c178e2161 +7456,cdb9bc2e735f04ed535199c4bd990ba3 +7457,a55684b0dd0d7aa76396d916c366b22f +7458,9c989582194b6256a07ddf640c1a559b +7459,a579703ac5436941a869c0e27cc3897f +7460,a810df41be06a211075ad21bb87506a0 +7461,feb8fbede51fac8ab151921ba6399250 +7462,f4f7d94da81a397c82f2551ef56355d4 +7463,7d090b30ec5841aba235b271a3f5df6b +7464,d1cc66b192772aecfdc173e47b4f6d87 +7465,15d847fb7ff5a91d9419324873e27f70 +7466,1ae61919f59df3ceb18a5cf4a732986e +7467,30e92f101d344e8011f3ba9718eea7fd +7468,9737f478a60eda4866990dd46bdc80f5 +7469,812980f4092176a2733435e090f29215 +7470,5ed18e239d8baf0cf31095d8a060a8c5 +7471,7052d20e5ed700b367dbac0cafb75ad4 +7472,9b80156b584fe08d6e8767cf7ace9924 +7473,72e06e405bdf953f1bbb645967214e11 +7474,0c27cb2e78b0876062173fda12239440 +7475,1e9f8f514690fc89aeb08ba0f641db44 +7476,b04a884117f729734d52f94ec9c65237 +7477,df95f6532c0e6732d9012a8a469c4991 +7478,240ef02e4df4fe85c0c599bd1d57e219 +7479,17086c1e8307cec03c1b47672198f68f +7480,d3245fbc5b7821ab8677df9a8c0be92c +7481,2cbffa63e9cc7118cd9a5c738a1b7b52 +7482,556155f93027a76caf404342382a2d72 +7483,be7a8e3b836a0a274ac5ed3e6dd4aed3 +7484,27ea2eda02a02c657167c0e0501ef35f +7485,f7810bfb01a07a9c27f7dabca8d75eb4 +7486,38c8b3990ff0b55648b792ee5d0f01eb +7487,a7f68be1e048a4a0caf41229a38d4583 +7488,964f27d016c891ab304a30cc5822cfe5 +7489,df03994541c97c3c1bb29a9321d35e97 +7490,b089b0f533df114f34be8a9de7b1ce72 +7491,56f44acea3fd6ca83367f420a1f26554 +7492,2a506289b88e38c690ae93d5685e8b29 +7493,91d94eee131c44dc4c8458808ce39b77 +7494,f27d1dea5a62d5506dd0b91468a3b5f3 +7495,6f32d878a43588bc7ea9d964e831f101 +7496,adc85628cb696137683088171f93bfbe +7497,01bb1b1e6e519e2d99563ce20707573b +7498,22e8b2b37bec442c2993a649baacca38 +7499,a025b7426d563d336238ac3c45fa118f +7500,7661ce605ad8c25ab7dd55cce48d5164 +7501,0919db0cabc97a465e3ef7f5cff6f547 +7502,cbb03b6b378fbf63f4e83cc02073a774 +7503,4f9cbfb14f878225b58842c4f24e8c8f +7504,aef5b0b57648971c4abe75a665abdf8d +7505,49d3ac0664bb02614b65ca14a1975d7b +7506,3f07a55bc8e5aa86ce65fb420f45e2f5 +7507,8afa567f1ccb486381c70b25c5bb620e +7508,a7c3e9b56dd6dde17d297ba75b18c318 +7509,14037672300b3064754c844f60247d17 +7510,18ac602ed46aed2b4067a2aea41bf1e8 +7511,5c69aaa4e8f1d1a7e6494992de65d3cd +7512,90882f45c466b07a73b87768623ed20b +7513,b24f14472e7411c803c8b9889e2bb6e5 +7514,efc32bfa0c02c482e5f419cade5d8f21 +7515,75438826a5f1747667e084f628dfd94d +7516,655761939dcf012b4c08c215e995e530 +7517,56b2421644aae03bf1b3125b119a2b4b +7518,8f2b376d17c1e328e06b812be8e87679 +7519,8f6bc1fc567dfb3be6da0c8f1f1bf343 +7520,3a05ca65c064e27d4072acca0fec6122 +7521,1977ac713b6032ea951a9dfd99210869 +7522,7f2a46906cd345bb48f41f7adcf8ac88 +7523,fc6b6162c8601c102157d4665fc5ab49 +7524,de3bd4e9c96e9a80944dcb71b8dee0d5 +7525,8d4466559e1608ef84423f7488f67698 +7526,056f8dc03c52a5ea40997f96f951c94b +7527,ea16ebe64772d1fae6380e7a2557bace +7528,7047f5b1c3a99e98ef82493ce7f47765 +7529,29cfc1064795f16393537fd371ed6594 +7530,4cc32d95ca4be7efbc7634df1dd82b9c +7531,174ab1c3e6809a2991c4d6dbbd5346ff +7532,a32e816456c6fb144a3041baa323a50f +7533,f2dd1f5f2440dc0d0fb1b8f5ac97182a +7534,4ec65572942468ce6d6057865a4dbca2 +7535,2c1399bb84691aa283d930b004a23d9d +7536,780dbeb9978d7c0694d6312177619d09 +7537,1fc7e6eefaa86ca6d3a8fc316f36f1fd +7538,52f9dc0adef901c6daf93892a854cb6a +7539,6b591fa6a8907bbb718994342ee5e321 +7540,ffc005d728956df7ca35dd781ba03c5b +7541,0cc070d02a7500562325c517f3cdaad3 +7542,ed2bbaa60068c515335ad0f50d0bc4e7 +7543,89ea092b8d67a7bdae24bd76969f2544 +7544,3dccccacabdc9e8a622635dac3bb7552 +7545,458e0f0a373a104b6b13edf491989d71 +7546,9407714ebd204bba6fab3569baf3d022 +7547,51723cea668db268cd432378bcb1bc7e +7548,843e92023bd28556bf68e53407d4b31b +7549,8eba234929a5bc96c9572d1a9a92383b +7550,47f00f579602c1f7b9e34e453b1181b3 +7551,fa7082d1acca61090ecc1134a60b7fa1 +7552,e44d46daec930a66987a21447e41803c +7553,08debe5045b9beddd88283e0b1a7bd3e +7554,5baa178ea844a2492cd945306340cae1 +7555,0fbdf022ac977119058a735e2669a1fd +7556,2c16b62ce556863d10a08b83404ed776 +7557,87d50d11ca95a277b183b97c403e2dd4 +7558,08b4d91afbe16744dc40a62ecbd6898b +7559,6497e5f99afce48c7b7eaad1716642fa +7560,d95c930e70c5b93c4d4fca2a26d05906 +7561,f9f6fdd65d21fb8d8bc16fe2cc588254 +7562,a21865cf1029283cc5e6102e28932d93 +7563,1ed325da8a5275f2b86599fa4f82db65 +7564,6cb6e0252da55515025d6c2367c568ad +7565,6b187cdcea94cb4cd6d237093ba8b095 +7566,de17b9f5f73bcf8002f5db7a28561eed +7567,e9928a906f1db97eda1b0843b9c9d397 +7568,35989f5fe8cff26671fc101d02d798c1 +7569,778b1114a5b76cf135687de9aa1dd605 +7570,b5d9d77e1a9222c22b55203886ede379 +7571,e46cd8109fab04cf0b9112d248819a17 +7572,9a02d164c543a9b5a58b2a034c455884 +7573,e45f3dcecbc325285abc7311f740a30c +7574,78d2be21c3ce4d6267537a4387cd83e3 +7575,f2d80d4cdfdbc31fc21215e31647e2e1 +7576,9e81a667057f13af8e182404ed8e331e +7577,a434138e2e4d93a4366fe8d75df9e6b0 +7578,d9eb69cd389b420eabc193f879e43c79 +7579,06c212b376938608157f1b1e0e32a1fa +7580,53836f0d56c0aca92a781ca9efeacdb8 +7581,8771e95ba06542fbd8ce9d98f16dd415 +7582,b40fc101f93453489de117ff406b9c05 +7583,7e23777f9d78f66581f42ae2268aa292 +7584,d3cf984b738a116a7661769ff8b7504a +7585,9d0f44029907eef0be61f8ef2997b7b5 +7586,24cc45d5e5050fc6cb027494cfb226b2 +7587,97dd3d1b0205dba22e1840aae701dac2 +7588,123ece90cb955c0e73cc69a78d3e5b66 +7589,7dbfb64ea29316b62094c265e0f31e52 +7590,cf798061091017aca1eb50e8f8bc93dd +7591,c6387c90d7b02b59d39f5aebd0949e2d +7592,7bb1467039fc2c264fb4b1aec76b0f8b +7593,687d4fe3bb3e0c7aa6acc4bd1edb68bc +7594,da281edffd7381f04e185b262a51c717 +7595,932832cdb7585524a908797c3d6be308 +7596,73791b1ac55e2bcdeda1418c2ca620d7 +7597,a7dcb4b182ff1d6fa2b9b9419d4d543c +7598,788de2062a37d93045e92a1c34affea6 +7599,dfd6e0c17d3ff0b6623beff9172bc0d3 +7600,0b9db2f580a934712109426385b061b8 +7601,fea90bd4023c15a558b9d035e0c02918 +7602,3d1bb69c5520f36042510654af662271 +7603,05afc339a1fe5d71444225288d6ca79f +7604,c7edb2dcdc760ba179946a614e5b4f68 +7605,d0a6e9a16518c058b5e6dd00594193dc +7606,b1c7732d57f2befd3a2122a1f8d6502c +7607,3deab080711257c2806e3bc231c326a0 +7608,740a611c35384ae73ab5c5178f2639a0 +7609,198c05331aeb5a05a495400f85a09467 +7610,5af3b6dd19430d9fd7f58170ef49ca38 +7611,5c591af1807e3087f6c6f3764a61e01c +7612,e3927e98bf1ca26378ffe2d9a9039365 +7613,a36278cf46ba701ca39da1ecc87d4c3b +7614,446d524654d947d2de207c1c651b2411 +7615,788a2931afc08768c1be3631a44300db +7616,5b7f3aab922388fede5c4906850e01a1 +7617,52359c5b59e86f821a69235c0926cd10 +7618,145d7fe768b5f16eb33764cbeee09f63 +7619,e1b55f25dc76f63304154d454ac98724 +7620,1004e14d26c2e2f74ff2d55daf9e5a0e +7621,0805c01903f37dca9171e756452f746e +7622,4497f33801493cf619eb1d95897b4cd3 +7623,e72a394ea146fff6d1a68794a0841805 +7624,3ea7a3fcf71ff9f8553c04bb56c2fb9b +7625,0f0756ce163f80bc532ed3f16d2d46dc +7626,df104b5a5cb691d6e5d4c75481e9094b +7627,56b6a2a9281477dcaf3500c16fb8b5ff +7628,4503ddaccdc7638fa5f437ab9ce7dd7c +7629,a5d928ac47b902585836c4598acc1481 +7630,7aff6cc7e80bac07eeafc9d171ba8766 +7631,5a94804cfb34060c3596ba1507b5f1a9 +7632,63c36685f40a64e804f40def08e05912 +7633,3d5efe9c3ebd44b720fbcaab5bc12974 +7634,75d0a48703e1feeb04c604ca6ea2d981 +7635,c1af5a9cd64f7c73cb3de7b8cba2c435 +7636,b202ef8989b8398de067ee2878864a9a +7637,ac47cd6776fd3bb2bc8d8d518fad4861 +7638,db6c335c01e4979cdfaa3a9e40da3134 +7639,1f9f7a7d6810c149795b0a6f2657158e +7640,b66b2f799306148e19fbd6b009d24ce3 +7641,ce2d26afca39e0d13ffc5fbff519dbe6 +7642,bcf18d0f1d637245639ec15c06f051e5 +7643,04b717f9996302be6bff963f846c7fc1 +7644,f3892fef5d2a6467e6ffa0aad75749e9 +7645,94593c18df214d9007fa39f76c4f8024 +7646,ae67e8f0851ae6550e8359d37df584cc +7647,71b82e4b04bb09472ce2c4f31272971c +7648,1e56ee20554dcef3f5f77a4d48d9294a +7649,e17e2cc6d952ecaf0d4f0bb5d494b226 +7650,01f9a68713aa823af71a9a24b68cb008 +7651,7efd0fcdd8427fb06f1d552e7bc3ddf5 +7652,51538ec44bad21d96916407482c159f7 +7653,e7277711680b9815988ae08ef989eb49 +7654,002a4484a52e6b2aff202afbe0f3ed10 +7655,0817884456aaa0d5d0b221e00e3fde9c +7656,de2db0bcd36fc7a4b0d8db271d35b685 +7657,9c6f5007642ebd6113611b674790131f +7658,b845eab24c00a50cf0b775d829a0f4a5 +7659,3a093a0a6ab1c0abf363fd1b0733de5b +7660,6f700226272724b27c6513354ed1a521 +7661,fdda0c7e762e56014d79a37d92b59d1f +7662,e9b412535ca54ce22a4f06cc8883e716 +7663,0d641a3bba1afe7f471daaa937dc4d5a +7664,d854d0a4373a787af9efcdb53b29497b +7665,c3f4b7cfcd68e25b006a2aecec981e4b +7666,24fca3cdeba764fcab722e4e3dfeff16 +7667,c118fa9d85325d621eae238a4e2efe9b +7668,d94247b041cfb41e7748c196c44715c8 +7669,b750ce94b2da84c15558e66cc55e886b +7670,419e3d36a983b35b81dd1e14be9d88bf +7671,ec9e36e4fe4bc48db1f4869ffacf37f0 +7672,f20db56c1a95426312462f4627561721 +7673,ea19d2e4e42463a3821d90e94270c682 +7674,5e9f9bde864f06e2b0649a3ba5cb1ee8 +7675,c27a6cc7a8c235ba2941fb09d84b71fc +7676,d6cd18d8ffdf53a105c1bc13d8d12123 +7677,931c2ac4a7d3167c4cf0f3054d247665 +7678,94710d774ab898d799040593c2f7e8da +7679,ffd3015f24a3d2903370fbb579735e24 +7680,75cfaa01340921d0adfccf6de6274f7c +7681,ece4fa8f48e1a06dea3c393f9309c772 +7682,3d3911fd749a58cec0e71988c38b582d +7683,c182ed2030b88f27e8ef254dab54255c +7684,591df3a0d0f88383c25bb1160f767945 +7685,e99b905ad0a550a6accf2274ba6ff860 +7686,b84fe5295606446ee4d0a85fd76fbc52 +7687,9257bf952ff412f5c813fc5e126d0a17 +7688,a973b2e24e756031feba92dbe8990555 +7689,bc431e9adf8ea185d14557dc3d11246b +7690,e0e7f880b8911ae249569ba7bc3a63ea +7691,34da03ebe7ec8a21cd489e8ce1e98e75 +7692,41a3c8f8b7163ce58385320d6f9f561c +7693,1dad7d772b5a2ca6b640d02466b3a587 +7694,723298e0544ef387dad06f57f650e837 +7695,ae7d5028d61ca5afdf90fbd7194c666d +7696,c31f706d39a8afd9f21e19c992c2750c +7697,9bc32c3c41f9d7def7227d6b60767583 +7698,b37e8eb6b320239f542a8b1068bbd8d4 +7699,5e5e9bc65b7df0550f74f44dca276f13 +7700,737fc4355ce8d27c231007ef79d22c97 +7701,fe4baca7de4d2dfc92382d2a32c301a8 +7702,6965df2b110db002ad376b2338950045 +7703,3ba3af3cf1e18e1b814ddee1a9645bc1 +7704,90d873003f5031b71f6a086f1ce6e780 +7705,619e296c576a77731628c3ff1d4b05b3 +7706,f683bacc9e280f066eff6028f944c239 +7707,c6d0fcd6acd0c73e47ecac553034359a +7708,fa0e094e6ecf242d31ce6eec79f320dc +7709,01a5ff19f6736ef58d009577802da069 +7710,df317ca1a89c28c30e1e03dc24a166bf +7711,ceda9f408cfbd0b0078a5fd374085f68 +7712,6ad878ad3ba0fbf621c29f2f2cca01fc +7713,5b36a8bce055ffdd744305e785937f6d +7714,682880d90a4de38646d05f850ab66b25 +7715,fcdabf4dce56d9656c46ae36eafeeb05 +7716,741122d65fe5fdd8900687d70da63bf8 +7717,1686defeb8c777e15b6b480050448002 +7718,c2fb5abd51a8548e43989c087a73c062 +7719,0f8cfb4ab13b7d16f4b3fb60773d7f7e +7720,2e8c189fedf6a187b819b37e4067400b +7721,f9c015ef1e80495e7c8a91a68b2fda64 +7722,50e2c66043d715c322d803de655cfc7a +7723,2bc32cd6f79334d6503bf73fb284a4dc +7724,c0c940726814e9bbebe264e8a63a7553 +7725,76e37452c39143b1f988e54f211cd811 +7726,2abb75e15ef2945884b00d830dd2880e +7727,b6fab86954ac83db0de1656df292426c +7728,b83201c364cef0c9d2ba39d57134c3d4 +7729,8417e127ed84e60a59675496dbb6a5cf +7730,c7bdafc14acf2b2658f2768dc46876c0 +7731,74d237222d75ada39e8a02938789f780 +7732,ff4ad28248505453b0f8d6c1f44548ec +7733,0c8ccdfa67ff598299dab1b468a3516a +7734,d17c4b3c40ee9faa41b759a6eeac0d6e +7735,29c3290a1bbe8e2c2a0c3d6522a805e8 +7736,e6aa7e399314b52b8b12d94a874b64c6 +7737,55a98ceb5105751e740741d122ff4380 +7738,f0536acdc34ff9d13f8ddb214d90300b +7739,c68fcbd6c66cb054ea67557774b5e7b5 +7740,697391aa365fefbda084bffa098163d0 +7741,5c88c9b7c7400c07d0bda71e27477435 +7742,e24c4733f351752f82ff4d643653c13b +7743,4e8eb59cb28b70d1b1d3ef9d4f3b8a13 +7744,e30c35f9df5cfc4372974cb45205391b +7745,36cae32c126564f11401f18886fc6d95 +7746,6a8a74b9fb4fb6b611052448604969fa +7747,137e1eb7502f73e64ee8712e4ce6ad9a +7748,1d6c136f2b0615e38bc0b2345496347c +7749,a2dc580b52804e2a0dd27fbbd1abc25a +7750,9f04ee88a63eac036cd60978b179fbd8 +7751,6f478aa74428120f42c1fcc71b47a530 +7752,fa52d9b4b3d410bbf06687499d47f4ac +7753,003db9445ab1409a01a354c4427c4f4a +7754,7156a2e77ac75670b7d7e1bc068e1382 +7755,f7f150be1ed7dfeaca950a912ea60ca5 +7756,1906184190a306f26c6cbaff120d0829 +7757,362cb3646d0a535eabd9091c0c10833c +7758,cc63b715086c8c345c1207fb87e3863c +7759,f67ce2cbfcc0f120b7de055187ac2d57 +7760,de950956322e9c24af9bc6c7d6d1cb0f +7761,ca1f3caf3de1bf0c2a9b968ae677cf95 +7762,f517346ab7ef9cb40a6948099a2a36be +7763,344cfaa3fa3463923451af38ca32b4a1 +7764,785137096aea1466b361469e9d0b28cf +7765,aeebff2ec3248d9b1d0713e1ba778c88 +7766,0293d4178f37f94bddde88a55417a966 +7767,2b255820a6ed43b6e5cb1360df9729ce +7768,89411fcf09f070b612a9c1e96b32eb80 +7769,171a62c94b87dabfc6a46cc1825411c5 +7770,47ad44367f12b946c63fdbbc94f32cd0 +7771,ebf8fbbe117538366b976b90745614cf +7772,e1889c8b17daa9b2bb3c315b0f3dda17 +7773,4fc044db7f60c5fdf69bfbe2f57d3811 +7774,57cdd3e732b812e59a546ceac4f48737 +7775,8ec4e1d05e36f3fa43883bab5558edaa +7776,355278b61ad9b680460758da8669344f +7777,0d86d179873e380c8352d16357e9456c +7778,111c3b986b96837e4d9a0ee471537b5d +7779,085ead696eb85211864d6902b8b97b75 +7780,9211ae6999e890aa00ba8788a1ee4e67 +7781,2c48621e43f3cbb97a8826a9926fa1ba +7782,7b0bf21cdbb50520837d952305d38c77 +7783,9001b8e681045d78e9a34b17c15dd029 +7784,a06fd633c4dc999b940bc1b76692eb5d +7785,0f8c58c5a9dc0a6f4f55f28682e55bcc +7786,4b65730f2fecd2a5b47250cb55254dbc +7787,863c19b2d07e9ef660c6ed2453db33e3 +7788,8d1ab158013adf197d2d0ba11a309745 +7789,914b5c668e970eed73e76553d2d888cf +7790,f3f5cb741660de5be966f089395acf30 +7791,7329dcde6995e27328f6891a12c6b272 +7792,fdf2d276a9dd456ddbeb845e2da7b6bb +7793,b202dd3da6c52f08f4492e7b06e0382b +7794,b9bc71b8bb5ccfc8cf37900db65a2305 +7795,ca638f956a4fbc917b5819a5b6ff2d00 +7796,55c7dbdd8cb6671c45cabe122560323b +7797,eea9e19a4e2bc9d2bbffc46a270d455f +7798,b4f23368d7c6a9e723389261d72b05a6 +7799,be645691fede5edf358cfd5ef38ed536 +7800,e5dd8bd078b133ce1d014aa3cc87d06f +7801,feae91db5ad19729b7b08aa4155f4a8a +7802,78ddc9330d923013d14d1eea5b6fafd4 +7803,da99037a6d0be55b81086d6c6b21fd4c +7804,7dcf8ceb1a72f9cc0a6819b65487d0d7 +7805,a4dcfbbe6d5ffdddd9658feb31d39b3f +7806,cdbbaa6694905d7a6688766460043ad3 +7807,6b8720552a7c99f6b3362f446ef70fde +7808,17ece29cf841f2b0ac01835a8be2a37c +7809,cb2f81c1c2e22f025ca476f6adb800a5 +7810,fe0281ff7fb2dbe4b6598fe238e4d68d +7811,27baddb7d4df1be8d6eff7b09ce2b5a1 +7812,be3858b4ab644208b8e68d0456af154a +7813,0059f8055f90ba2ab71e67c5159b6d77 +7814,3b37635c523352ed80394739c9652831 +7815,61af5f18fe73fa9fa423ccee23b2c544 +7816,28ce92ecce11e38fb8562b48e5f9ae48 +7817,f09c03a7b627316c87a885db44ad6a5b +7818,70753e145f40e30a5cd5d3ade6bd4644 +7819,60f6d8c7f601f35f8e64e4d43d831b63 +7820,e8719889bfcb8a3eb29a4165454be091 +7821,ac71e08e96bda12e39ea5ac942b3267f +7822,4677ba90d18307570baa97d15107d072 +7823,74dde2d0fb562c0cf5d1b1fe9547e282 +7824,659e689266209ebb37b4bc5763a0b77b +7825,77d08e5d7f2a1fce15e74379a0eadbf8 +7826,5d74d8e89fee68a43360aec50c411ead +7827,94180b014a541580ff375b6c860c7bed +7828,8b87c748fb7d3d992ae50644dc3e0ec4 +7829,13b6712c0eaac6fdda0b4c4e8dd1e006 +7830,7d12d466f700f0e6445fcbea38c14143 +7831,e703af9a655fc01a635b2ad72c99b3c6 +7832,1503e6b392ad08b10550d0665635f178 +7833,a379495b0b3a2174c01cb5993405eec8 +7834,a81a42c96b89d7519b86978a9a4dc8f0 +7835,928fb0fcd2a9ff51e5eeb9ec6899b67e +7836,722b19cc8c8edf0ba478bd63c99d9a1e +7837,517cea4f8d793ca90f515d65dc6d4ebd +7838,f8c759de35b8d14ba6cfc322fa44c27f +7839,61c7d726c01ded61f87db2e55262f5b8 +7840,2798d04abe181cfb28ed8acdc28d8491 +7841,329eb3941d3cb42f3b2ee1aaa798c0b7 +7842,639747e38dd1774b631fd31f654ad586 +7843,a94e1e7dff80ea4016d06009d93b40c2 +7844,ce10fe76feb4396f8d49bf8eaf061d2a +7845,145c8c56808cb91c657a998f63b37ef8 +7846,cfd1400a0630b5c5feb4b5fbdc6a6794 +7847,fe436494f491036d185aa607b1100247 +7848,d877f18e84c1105f944ca73cff121443 +7849,41347ab2eed5453f49531d6159f69ea8 +7850,42a318f2a47e712d32b669dffcd96251 +7851,d7009c39efb7bd4e66cf74f28099a453 +7852,161f5c225aa9bc2160368a7c40554893 +7853,c378340c83b85c69540d6a4eeefec419 +7854,429233eb1603c92bc5948d1b257df6bc +7855,c67a25de25ce207d1ad85032196e8588 +7856,e7cb058dbd67e4aa90ba28c521a27015 +7857,b30c347c80cb8bf5efd421ff87fa1a3c +7858,e8d30d57b3c7dfb0f99f26208946f21e +7859,672d276b912931bb516e8007423e9ec8 +7860,168a43ceb48ecff1c7ace6fcc38089e8 +7861,7e1e361463cd3f885d65fe028a82c68c +7862,1b1500a37dd2ab40b4c88accdf1da4b8 +7863,6711286f2f3e20128aac22c045799445 +7864,596d9d7fe8b5dfb6597db70d5d809e17 +7865,d214ed09b9d9dd836d52b75c4cc1a326 +7866,8f5cc18b8c529f921666e390cc922068 +7867,bba92b58107551595bf2b1539ce8e7b9 +7868,00ffb44964e59fd1c6485311ceb4eaec +7869,fc4b415ff7179bdbb5c5c2ddb71df152 +7870,2cfd755902dfe735597a20f566f4afdc +7871,e3814db89387c3d87f5dd780b7b0c744 +7872,b0f7113742d3352d87f8714f6c6cf888 +7873,dae20915e83b839da3daf5296ed7fa62 +7874,40f21c9f005c2f76857db4193337f8f3 +7875,ad6413e40300e2dc128cf95477436244 +7876,127b2c1305f663517b2e5a8ed3d19b5d +7877,2d9070021469a0f4b56487471385fb2f +7878,5c466ef2b84fd232594611eef1ffa486 +7879,8568ec913119ffdc4297f756ced8d316 +7880,f2058d852a10436bb154baf29dfa6bea +7881,afd1b284fcc5a59549a43d0d1b6069dd +7882,878d8d077589d1019ca9647927fd55fd +7883,ea1f46aa4b078cda54efcb2ce8bcfb51 +7884,f50def8caca81c473abc41e7b1048a50 +7885,be9e32f1e7bdcd01aaac68a2197dff9a +7886,36ece76c8422c77ce8a5b3b4a6ba7fcc +7887,101149cf32d086f3e167f5fdd25da402 +7888,5dfaebc14a93636a87817b5e2347e845 +7889,8e1563053d0da6237a6460bd4fd28d58 +7890,6edc8d84b319ba0228e4227cdffe9e46 +7891,a0b6aab848b05f9b0aa628996a09e34c +7892,e062c0f33de4785df45a1f6d1be053f1 +7893,fce2e8c44d2fcbc44dd984100828953e +7894,b4d4e8c450b2885f4ef854545e877e82 +7895,1f822c1ebbd94ee2291438d985c55a18 +7896,59b421fbea66771d072b8ab3a6e86686 +7897,ce5fd4ce24a04823de660d9cc916b49c +7898,0a4e4129a9427e3b98e2de4a71ef2fa5 +7899,1ec935bf94beb4213f176ab7cb78623c +7900,d9041d0241edf074aaa5381f649d685f +7901,b73edea622a147792041692d6b22cda8 +7902,72f7b1f2020a69ff1fbc962fe19c85f7 +7903,b2be71427e960dbe5cad9b1082f6baaa +7904,4aef238f77d02bc2311e1616366b2a73 +7905,08d2a1b455b386eba20615317456f548 +7906,b308df9373a5f9dbc903c2d6c17309ca +7907,b1970aec027724b6d80612c317febfa6 +7908,f3b8c2612a2c4b7886fbe8ceb8cfdf16 +7909,8f765101ff75d47fa4bbba4b3d4b8e83 +7910,5dce6bffb8ce2384e40f1c924a4785df +7911,6bd72b86dec86429b723dafaec76d830 +7912,3dc2dfc92dbad0715509dce64e65a7ad +7913,a3c69acebcc6fe7cbd893748eecc6bcd +7914,23d0f3c474c603b19f3eb0193ac2130d +7915,481a09a3cba0a4ef0c619095f106172f +7916,ad0f309f64f5b0d7b8a2177248e56a9b +7917,87d60e85aa7da8a4b2630fe4cdc6d5af +7918,c762cd57820c66be59119ed514cac763 +7919,89e023188e0868e6b396fc357026093d +7920,c70cb768cbadc15d8671e69043f6c527 +7921,2066fc13aed631662b7664b3d0a9f2fd +7922,5af964fe18d56e06946a81293c540215 +7923,f8267951bc546f5d2d88361cf3878085 +7924,f12720a89d33e8efa41dd359fe54e4ac +7925,95bd651526060e97ffe8a67170d23f46 +7926,b98623ff1d215e64c8a0d84376653b62 +7927,ebe20b773eb1444e03b6953e2ff7ac07 +7928,60b488c01c535c75ceea3a4cb7927425 +7929,48427f8a63f2b52077609dfc457eea1c +7930,268af3b80499acb05770d197592a1228 +7931,0c1a67528ad20b15dc3cbc8672133bde +7932,8c4a38c7889446df0576f1e78f709d04 +7933,f30179695cd7db440a1387f670a562c0 +7934,46fe290993d64838312e6f0f2086687f +7935,fdecb8c7c982996fd5410fa714500dbb +7936,4fb5e04022e9d16dff48703a5c794ed3 +7937,a0212311b83bc77e884997785f70e59d +7938,1b36b9b49a66c364d4c9912cbd0a5c3a +7939,4eb515f0a2fd8e0679cf7792e938fa78 +7940,5585619a65ae6f18cf44b8015a89833a +7941,9ac12ce68ab041d8a47a0fc060c6f4c4 +7942,22225294ee7d2a2a8f8c219924fc53f9 +7943,a60d820cb1621d91a010abc5756e8f36 +7944,af83a0be679cc7b906ee903539bf79e0 +7945,620d2fddbe3dfb873c5c64673b7a1e32 +7946,2376ef5aa27e9e21df523d8f5af7cced +7947,aca69a3f7c336874a78c8a0db04ad46e +7948,d096c55e1d6a89a8a4874e7d929dd75e +7949,a8fd0eaaec689350d26156dbe3b667e2 +7950,6536d0b5c3b0aafd897e9b90a3ae03d4 +7951,ca8710e39c4f56160f826c025ec36607 +7952,258ea39908070dedc7c24805d76ccbe0 +7953,9b1841c7a7d12da36f6de71fa0969c8f +7954,f4b600895cdc6e9e49e343c3c93bedba +7955,01821be9bfa24f748c0948bfb2a337ad +7956,43d59d536d6b1a9248f1d86d86bbc6b8 +7957,6191ffecfade5a8c913badea454f5e6e +7958,fe03d1408edb7de85f6a1412165403db +7959,1e6951acafc57f382e890980920d0341 +7960,66c406e9088aa62983fec04bf8ea00eb +7961,7f051616d89617d473f27e358bbe52af +7962,ba774db00a7a161a2dac5c06939a9e25 +7963,8c6ccb4b40a3e06671b876b23868d919 +7964,0aec344b3b176994505fd1c1fab8ea2d +7965,c8dea95f7e2334062f4827c172c9bff1 +7966,34ff7fa89cde33efbaa673cc860bfa08 +7967,a0a50ea7b82c2b9bb2ad4a81924a5bd1 +7968,27f4e577b2ce77bab69e96fb40b88c26 +7969,fd6cad85f3fba5facd12e82cc614683a +7970,1098c3211d386019383a5f71a6d44bc2 +7971,dba16b479fed3fe59b4f91e030223661 +7972,71241473cf38cd65dddb3d104ab4cb96 +7973,9c2508b406accc1291bba3194b00492b +7974,f70935f8c6d2939d5ceb48336c8466bf +7975,ae1a01fe7b4f1db31b5c86c1038c009a +7976,f7e59253e1ec230ed0ee01a47285536b +7977,c3c44c88517b039063fd624ec159d4db +7978,6e3a3e6b0214a522288104a505ab67b0 +7979,9056523101c71a0959fbc98de6d27a87 +7980,c0f7c8bb6cde46ce2b6067edfcb258e3 +7981,29afb0d43491c9134f1bf09b7218c6ae +7982,937818cdb33dba8a8904a1df2d904664 +7983,0340a4c1a80a254f681024cd2768c3fe +7984,3656d87ce1b4a152a0020099ad3ae254 +7985,7a508e508196ad60895e56ce10bb84a7 +7986,0b9255a1712693273fa3f446163eaf84 +7987,659ecb2fd1df359b13d6467c6e4d46fc +7988,56c48225cf8d1ab0ae53f10a077d76e9 +7989,65e7e340bb59f4d49f40ac5efdcf9b27 +7990,7d03b4137838989be6583fecb7deb37b +7991,5e460ee31a9735e76b3906fac7808376 +7992,bbc6d88a5e75f59406c856bd425d5947 +7993,31767f14eb074a4d185a26df4708ccff +7994,361eff52d42f625e1a3591171f0b8e53 +7995,2478cbe5022f5c181f9e6bc0a6507c91 +7996,7651513c5b1998b90bbd2bfce2232ac1 +7997,834e4e9c17adac2021ceeb4636328705 +7998,489679e79bd5f94badd7b0c3dfd7ada4 +7999,2e0fa501bbf43cf7cdd1ff8e02ad004a +8000,19453394b596848fd34c5353625f1e88 +8001,8606925a78974ee2b8074051bc0c9f03 +8002,8350d94ad0561300b20d1f8e91279b38 +8003,17b5cd5db928894b656a57075fa44836 +8004,4ca3e54c594c648317f7d5eba4920d9a +8005,3c9d6e294487d5e970af02be381a02a5 +8006,f3cc5f4160f47181c978b4d4d499a3f3 +8007,a8a2b798728aa75606038e6f6e4ceed8 +8008,f5e719230ddf1c48c2c9faca0548b6c5 +8009,ec94bd7cabc0db0095d55289a5270f08 +8010,7e85260bde26d6ac44b17ed956674282 +8011,a5d8d42000488315614c32e692ea924a +8012,81c06c7507d24798c75ef7e12ee2b01e +8013,470a21b1fa2558afee36f7d70f41e50d +8014,468cb8689d8012b52984bd8905782597 +8015,2604785dd60ee2a50f2b4a10927e8a10 +8016,50395b7191ee4d13a53e7e4b69219def +8017,91df5070d5f65cb11cd2b92034a613fa +8018,2715bb8caa968ad992df7bd0134c7ae9 +8019,a5351234a2860c3f9c604a440ef57f60 +8020,508b57a090b5263f701019b13d3b1a5e +8021,b7b4ea3f57938ecde8598c3d97ec45ff +8022,9ef1ba28547819c2e251cbc600d36610 +8023,21bc4638c03437702390c98095c56f0c +8024,6c058c27841b247b075c8664ef1d1bb4 +8025,bf4f134df648dbfd4ca8086b03e59fe5 +8026,9af51f01eeb0ca9013f913cf89ce4202 +8027,bcb18d548b23c0b4311c81a8c4d3d011 +8028,ee07ba026f0861c12a9aa8672b9e94bb +8029,0b05364659574d1c72c8dbc8f345457f +8030,8138daafd2bb03a6a97a8f3330853154 +8031,4b2c563a48d88e1d7fe8d5aa62b72bb9 +8032,efd8d1c85c14f5c557267a48eacf8942 +8033,98c7a4d9f85d2d8e51897937925bdaee +8034,0c946d59f3b0b563ecbe2e1483e14cf9 +8035,e30fecd717624223c611d783d21a5308 +8036,f664ef73e3519c52241c70043151ac59 +8037,33948e634c72b71829f00c14daf2de62 +8038,1824d25483748c6c26646632ef53472b +8039,9115dfa5a5551c1018e72e59108f6f2d +8040,11e12e29f3d96a4b1ae298e1150319b3 +8041,6c6b3a3286c2b2755c1a2b61bd216177 +8042,c0ee7624f144aec8c3832311077a207c +8043,1c582817f7752a1e840a0b4fdcebd8c3 +8044,efa2accb2101e50f0883ad1b63db8733 +8045,3ac19ca184970e1b14d0cb4f7bfd0e76 +8046,5671b596f5562e18af94cd75f38aef4b +8047,67ca47b9fa7a9595201aaab70e6407ed +8048,77ac7575ca57d37f1b41a2d8409a47c6 +8049,ce6d2272bc7b93c053bfca7be1bb8321 +8050,5bd63ba7cca58bb671443942bdf0b61e +8051,0387f54b75ffba0667345d6fa4f78796 +8052,9ff7976666d7c13d552cb039975da6ad +8053,0012ad06c31f48c21d4b93d766ccc869 +8054,73773719d66d7c57b6b6779bcb9d9315 +8055,c52c5213e72d4bbf9b0c0f05ce3c8ec9 +8056,f609c58a16d0bb2b8faf9a7c92f20b3e +8057,9456ab9284473879f26669418e4eecc8 +8058,d76b6a4491b9a256c7194a2ba2f197f0 +8059,d8c3aaa7d2c129a68ff983b64c95f962 +8060,63f8f8b4f8979ffd960c68fc670fc365 +8061,c8b832745334627e78bee2f92b4fa15d +8062,e6ee2196cb8b9f2ce02ccc3c94532c12 +8063,6a692892f1f794fed77b083e23f39b72 +8064,76ad82897a1176a62f73d1c1b2f63d4b +8065,d09c90a8a0821194d0cb7cf0520ceaa3 +8066,52e1a033edfd1d7e9f110480c3428dd0 +8067,c28d5d27ff769591fb1fc59c17063507 +8068,9b37195d8405c2918e2067f4291b268b +8069,0824c9a336c9ef862114dd7a16878d73 +8070,0c97403eef19a6435ae3992e5b140d9d +8071,248e093b5e8a08ff7ca25c421f360f08 +8072,dc5a491b0424415aefa42b4fbf4074fe +8073,e4704c6f5da495deed84ba885d032bd8 +8074,cb10824b38617acc0a0fd010e06bc1c9 +8075,c5e7bbe63807043f31a8b9b17861a34f +8076,d01d25a2c0423d99400b85a8dc260236 +8077,ccbc230924efc2c211c975395e3cee90 +8078,050fd57b7cd9fa4043ae881c07c450ac +8079,bf7f2884616894360de845110299e2eb +8080,194e7b062387f42bf7311424a38f0ddc +8081,55f2ed21ea53090c095f8c439fabe2a3 +8082,8ebe94c6004d918498eab5f16668a9b4 +8083,3d439d9a8e7ed2d18466405c0a4ed93b +8084,72450c71b8e658e508117d3dd01d72b6 +8085,826f6853d9b51cf39e5629fbb2b9cbbe +8086,f02328e95fe7a93e2bde51a9ce9e49a3 +8087,e5ee43734f0d30bd94ff7d3531bd9747 +8088,7b946896c038fced4207c4c5b121f3e5 +8089,c6ad65d82788d145bec346b0248649b6 +8090,8aa3ab3bfce11c336996006833c2981e +8091,c07dfbae4840e41df88fd5b2ff61da1f +8092,e74e374cbe62fecc71f5a0d54c08440e +8093,f376e843bc4f1acab356ddf868077d2e +8094,07e235b6e5f5872cf9059ec23a4e742b +8095,149999e50c4bb70def9db52c081bccb0 +8096,aa0c823f8268877d83d843cd14fbbfe6 +8097,a308a969cf18eef284f353d9b42e7e95 +8098,2b03bfcdd9a4e6d8df0a29c5fc23b05e +8099,f9b5553b0a07e582bb57e9308b1b3cd1 +8100,3a18afadb9924b07d04cf559e266425a +8101,33e8874253547c482b0c55588b13aad7 +8102,badfdc47e5aff16c9fdbd6c392b82a7a +8103,742f13d4d4575b01df8b5e8c7f9f1e31 +8104,7b0d391d4c3695ff8edad53a840d80ce +8105,de6a077f3c3a0d882170d3871db6a359 +8106,088cd9f7ecce021d8d837eab41fdddb0 +8107,8289a9b73346ad725b1e465eb640d6b7 +8108,d3e8afa5613d2588919fc75dda8198fe +8109,b97cea3ab1eb2bb290d555401121aa0d +8110,e92f584339f09dc60b971977b9894fb1 +8111,08bfb5678c87485e99a22f0d69f08303 +8112,b2dd83ebac478dcb60d4127f3d9e41d9 +8113,885f2105a3c49870e593eb003175cebc +8114,6c967b2cdc0e3349ab0cf9b8e23ce712 +8115,a1844c7a3a3564c0b631ad3867ff27ac +8116,714d2bf34beba669ff86fdb418e39f08 +8117,a4b5121e68aa559bebfc419333b8926a +8118,ab6b4883aa46c142c71e27613d2bd0d2 +8119,5e0d7e4da46e4f031a3d68de4da122a7 +8120,376415d0e5c9d5c8a5be4bae4ab0d195 +8121,c8147d64fe2996e18875e81c90fd1dcd +8122,52a3cb874efe22bc775c6b81738bf5a8 +8123,d75c79bf20db994e90982f22fb7a6dba +8124,3dd688bd877974226d9ed38137c20a9a +8125,3828b9c4334250f242de090b404b232d +8126,7ede69506df1a6d9357cb4ae03f4519e +8127,2c92f7c31b2382d96ec17eb1e990c04c +8128,d7020fc6b500d5a72405ad50730c3c07 +8129,bc7c80399f9d6eb3bd2e98407e683bee +8130,a892661c0fe0b11688d3979c7f678bb0 +8131,3f00d28221edac31b89f8aa7a60ae36b +8132,2e3e80b11e2b4b92a6cd32605c258664 +8133,0c1522930dd4000b1aa2c9f345846f7b +8134,2c67259c14ec391df01424a13fe48e88 +8135,d7ae3f45958ce5fd46dec5d99ec9e438 +8136,4aa835f98654b78c40d3764335745fcb +8137,9f460abd2f73b86b3ecc0ef17af454b1 +8138,4887f8316b6d68827847fdb2cf04d5e9 +8139,bf8dacf2ad9ec1db1eac314294389205 +8140,b56f8e2762f58d980418de512a8b292a +8141,d5b5ca0da9bd61646b206ad2493949ed +8142,6d63056bf099f1bc2e51b4459c0c67bb +8143,f499b230f5be2347f7e9a42bc59354e3 +8144,715c5e33a879e442e0323474b6931fea +8145,f97631ce620f6bea177a6092b22108b6 +8146,31b582ecab96ba5090db31cf094f1ddb +8147,6c5aa5850ea5c50f3f3b075b99fee453 +8148,37a1a019e7da0b2b90a2cd25eecb4bcf +8149,5dbe3bdcc3a3a62245855bd61c7ea50b +8150,581205d610da9c4b651b29f96c5a114d +8151,ab105398ccb91994a0e12016dde09724 +8152,48c419e7467c7a5aab9808a213a1926c +8153,9c2f2ef21f1178a8819b94e80a1e9789 +8154,a57d7eb229550beb10b78baf13323c2d +8155,b96e520428799e1fad4523043083ffeb +8156,7c6493e2c63c74d155c9491270dbc2bb +8157,e61fa87aa6b8637233678922e8de4f74 +8158,514270988fb87e0df6aa796e9a6313a0 +8159,0c7aa4bbb8a379b8f3a93434743c0bd5 +8160,c5b740986ec1444c95c1997d1dc631a3 +8161,0c88c44af8f5e71fe2b1936c429e72f2 +8162,f6028f5c0d1058f03f9c9962394137a1 +8163,b9b41ef7c6166f83b01773fc79698a64 +8164,435af53377a56d2388c67939bce5ad25 +8165,eb23139b84d57f561c2c060a462076fa +8166,579bb20bff426764e6f53d0c7003023c +8167,8f833003a82a4cd9e1f167cd24449291 +8168,c29b9a325590aa757bcde78591e51439 +8169,f267a2f56c1dde53e2f46d390814a696 +8170,c6c834626463531a460da8ac2501ecf2 +8171,ae9d2c94dd5d7adc6b137c9241e78814 +8172,678d4afb9b85d8354e7dabf3c5adeb83 +8173,45118a1f05f44872de4f3abd8edb232c +8174,86c27444e9277c5250d79d1a2fa6f63c +8175,98b40c3cca8a4a0f2e59452e5450bbea +8176,185b44bcd614387b174aa9826e69c85b +8177,667af6cf6a00fe504c3d06204f33999b +8178,4da13f66e1e829a6d89619181b0e0176 +8179,4f09a68cebcc9cc6555495d9121a55f9 +8180,b93c1555705e5ce964995e33c0656e49 +8181,5648edaad86d69cd690467b2d3039701 +8182,b4e332d57143194c849dc8c4e1b1ced3 +8183,19bc23b40438fc4a782c3ecd9d5343e7 +8184,304b7e01f08cba93a08ef549d1b93b77 +8185,b5314cf8966beae139773be9f414c518 +8186,2191fa03036efc1fdcf680fd21b25f41 +8187,cc2aa98f402543683bab6ec3cc4909a7 +8188,9773cb8695712c6f3195d90fbd2ca3eb +8189,6033e68afcd0a794e285ce312b84d14a +8190,267190c006691884bd63da22ebdfcd59 +8191,13f66e411c8bcf9fdcae3acf062105bd +8192,938424d59b36a8846706d8180ada3f13 +8193,6dedd6047fd70134b39988ce509bc60e +8194,8b2457bdd80b52732c9cb23ffd3d4f60 +8195,6bf2cd5750c6841795f4252c7fc76ecb +8196,4f0e8d1e7dec6705d5696d5d5bb650b4 +8197,7ca10caa52219ba46bea20d3792ebdd2 +8198,7787b09acfffac5a97298ca05f0a274c +8199,d4c9b2cbe6b89477b947d9946d6433c5 +8200,b79a83d5fce4e2bcdc28ddd0d247a448 +8201,4756b03c2e506a7df1d6dc76e4d8ab7d +8202,11f6ad2925c8d42cbb4e094579028c43 +8203,f6d220931a685c6d5e3271351802474c +8204,3fb0eda26f2a007e783e01a12c505a95 +8205,852ec707610f5303db3a93369a92e40b +8206,1f525d4c9e906d30b9ae8da868d04c08 +8207,50901914ca081b16873abb7330efb0eb +8208,4031d86309b56117c5f0c4e336e081e6 +8209,49582096429efd0c86c3964b5dbf985f +8210,4301aa975df1fde1d9ba2fb3b236ce85 +8211,a28947d35372aaf831362ef032931495 +8212,eba8f129f0a3c7bf767c61881bc7ade5 +8213,ba79ca931a277fe8cbee02be48001692 +8214,171e73270b0a466b84994a1a7d30e9fd +8215,30d179655a844c79b02c510f646d019a +8216,f9a4d1539b9a559ec9350f324c93a29c +8217,923a8c05d8c1ce2f09e3484b4d64ea19 +8218,d220649fe3fd9666bcd1698806b3428a +8219,53d89870bfa69682fe2d515c155c5e18 +8220,4a6deb31a422e6e3e5700e8b07ad1633 +8221,b554836b878681347644d9074a66bc69 +8222,00d1ad98bf145418fc1c33c3457cdc68 +8223,d8e0112ae91949dae9a72b3e02218b97 +8224,e25e82b84914467fef366b60ef953bc4 +8225,1cf46907bccb1272dd38b49d4b716f35 +8226,9432dd1732eeaf1a1d6ab718d5e37ba2 +8227,96df13d265dd85d7dc6778e2e122ac1d +8228,69b727310363b73dcf7c04e4fef96785 +8229,1b778bb3582bb5138e94312f9993fb42 +8230,e9e1604db2be2e6a11dde670bcfd39ec +8231,d0405a91c4abdde348847a610cba5f26 +8232,3f9a91dac12d791b7e20c71d0858ef43 +8233,787fa1713f353e825a71248db07d8bc4 +8234,c56326719356aa4d598754be7723ccff +8235,ca090956d4c99b304bbc971609921ea0 +8236,4ffc8dbd62cebc61df6bcd1781ac595f +8237,5e5868e8dbe028cab0cc7d60087dc826 +8238,e291204bff5b0d2af61bf2da26220f04 +8239,8a7286b558db4baff86dab9b5736fa46 +8240,6fd3d1b527c82aeae22f6fab1d76734d +8241,11b4ff07b0f8cc35f6f1bbff103686a1 +8242,0f86845c573a51b25e7f8ce877bae9e7 +8243,b79453b8bee2b32941081f5eedf726e8 +8244,f2c8c1e8d1480dd2c95c48c7896c6130 +8245,cf342892729147b1863abd4225140e7e +8246,4269c6d96a56605e051ea17de941373f +8247,e0005fcd9b633e24af2a1e418741ac95 +8248,fff2fb3eea6261d550c48c7fadc3c814 +8249,9adae85c64ca61433e1d75f4f1d88172 +8250,f0698800f7a9c3c9fa120fb5ccc19c35 +8251,fbcac478fd2592eb3dca04e6909b85d2 +8252,1b6c3ddd49aa19debd70845853220935 +8253,5c804003c08d56f911e00b7e5cb6f16d +8254,e16f667d001048de1305b2993a4868e8 +8255,1695c5b723041b125baddb5d2013757f +8256,e08f963f6c839a6b1425bc4b70872706 +8257,6607ecc231447c7babe1bb50dfd5fc1a +8258,d2483f954473ed92b09cefa9572f0909 +8259,12bbc999d420e706ad3217f48efe646e +8260,1687fae683c0a32a0c02d76a2c2efffc +8261,286d05f069e1cd6a5b6b71cb2a6ce9ae +8262,332be601a38254e3f2a9543b78946f4b +8263,d5728f7216ec1660e99dbe0e4396d2f7 +8264,cb729e40b23a96060f7f9ef3535fe7b5 +8265,585dd412bc831e6d6068881b4201ea1e +8266,0bffd82258ca462c504bf2c3d4f42fbb +8267,7540a196e4c925e639951c4019875555 +8268,af49155fca9edcd5e86a43c1d17187e5 +8269,af74cfa6961e2b2509cbd04349a4a4e7 +8270,9646883a276c84bd36e74750ab2c371e +8271,5bc9cebe577226dbb19a272d3adb3a4e +8272,f1bedb38703c8de3d598ec0ba659eb0b +8273,143ff27ce32b417d4987675945271528 +8274,a19479c73a236a79797a0e8d21b9a08a +8275,3971752c90c19b65ce089fba4260654c +8276,07ceabebc87fd6ff2db990cf22a0105b +8277,f283c1180bd3d245811e0711d439c3d7 +8278,c58d8cb7ddcd8400fd5025fe0724d46b +8279,8f87d022abdc10b4cb7c0d0d00b7d828 +8280,b3601569f1f669459c5786234316345e +8281,3b1c95a4f259eb17c268a5fa1b525176 +8282,a803b9e5e1f966ea834e8cfa02a4aac7 +8283,a50946988bfd02f4f9383c10946e5219 +8284,425a4b0c1d22b3a1f216bde60a2908ce +8285,838974f217706049e76a596b9254ef03 +8286,9185a9d541e6377f9b99822bcf51a6c7 +8287,4f0b34e361532e8a384dfeec8001a3f6 +8288,3e2b228d6fd8ff9ffc1382876d081631 +8289,0c2657288005c0ccb32e081ce91c25ee +8290,22bfd47cc40033db6c197d620c1ad10e +8291,5f895e0e4f3d1183de949eb49f6e30db +8292,6cd45669328799504ca9f0d175556196 +8293,ca9db73950a86257977e0ffcc3ddd825 +8294,a75c79b8b910e8cc4fe5762b1bd4688d +8295,3a18e3610486ae609f802d93fef12b61 +8296,2606270f7a70c665cbbb1fe58421f7e1 +8297,be3d3b01cd614c2022a651c15a24d13a +8298,1151ad3d12c68ef11e19796488899640 +8299,9bdd5b4033943d379b56a188fba7aa31 +8300,a01e1e54460b89f99de5fd5862f6b08d +8301,6170030ad9443b256ca4fc46c69839a2 +8302,b7960e5876e3570a0d28f9c30d300364 +8303,7c9a506fc5a84b48222f9347fb4b799d +8304,e67fba4367900900dfee4bc6f43cf6e9 +8305,5c4ad3422553a1ccd01efc813b55d27c +8306,9c33841af9b943ba054c6e0262fe57ff +8307,02b2953df2bb869a0e3fe21b9660b197 +8308,c16bff4807d6a8200e7d26c78e6ba128 +8309,f735f9d69bb1e440e9ef28c7f74e1978 +8310,274795b90e5277e501add285e9de1c36 +8311,b0c8fed3eb90e6a8e7c972228d0ffe78 +8312,f3038fa8e24f87ab926394f82cfc3633 +8313,e423694db6c97b51b8f8c749ea3e07cd +8314,a923a142bb3963aa3e701b3d5c1044b8 +8315,392ecf51d0861f60a51d1a96021a76bb +8316,c18dac0f0026690a4b1f9e06b833dabb +8317,b5b592464973454f403f9bb86ecf8f1a +8318,7d7d3903c52bcf02920cf8c353aed42c +8319,f99903ea10441739b6e62b8f9ffcc5e4 +8320,889ffe82e8b432d93ab191649fb259eb +8321,f7b5f5864dddc6c29f53f914420c3ab2 +8322,206dc6d617fc28415f48753b734f54ea +8323,4b9d527c07df9cbc245989292d2b9317 +8324,bf91e1d4510b47b1208422ce11032ff5 +8325,1662b2c299fa8625c999cc40930cd881 +8326,8a88e1224c3bb29d4dc4ee8051acc8cb +8327,cd8300f7229f4653ca09ebbb935f36fc +8328,6df9480d4d543a5e22cd3bd078e000ec +8329,5a1cd897cdc5ea08c629176cc93cb487 +8330,461025150c79266eb227a2502f1a9361 +8331,b7ea3b74a14e9138c6147bb26070178e +8332,edac2e880700f0a692218770588bf416 +8333,88e1aa40630d4368c77e4edd37eb2a34 +8334,942d4c4251efbf05614b024662b5434d +8335,06229775d2caae50fc26f50f18305e6b +8336,6c3285e888b4370fb352e6c458d2650d +8337,102d9d6f79dcb72e7d595f567fe2a573 +8338,81555984ac582b32d6d520cae09032e2 +8339,bfe03015546cebf7c4f5c6e5aebad6f5 +8340,300dec54ea13ff5175a73b544c60c736 +8341,e3781fd76fa5d8506569d6f7033c9510 +8342,8e74e13660083583e4e14ca480459ec7 +8343,ad00ba43c52a6e9855f7dd40deef2dc7 +8344,501ee8d2ac6ba35589579f04e0707cd6 +8345,ec2dcd3e1ed0bfe633517b296efa0060 +8346,9fb96ca269c42ac1ecd3fee1c35674ad +8347,1611aa2a02c047b1c243e2184d6345bc +8348,33e78b8dbf632ce95d4dd53ac58b9afe +8349,a27842bf1988b1d0c740b7e239a7d539 +8350,058250082b2b2fc8d0518dfa604e7d58 +8351,ed70097514215362b599370058b3a2f0 +8352,a272714239de78190dc53b567d23e210 +8353,fd354596b32b7b2349dbbfb5f6637f8e +8354,6fec1859179647bf9c29f71819eae421 +8355,9568210f027221b9f0481c110dafcdf8 +8356,bd8c2ea510a8324630ebd83fd6a9d228 +8357,c5bd63284ae5b17d21af6220dc48af98 +8358,9171eb4806d85788af6259fb8b58dda5 +8359,ad3eb63e19eb258801a1810a8536d8cc +8360,8a23be934ce2f5ed42df8ac14a69da7a +8361,7c94b11e83198cc303f8e9751ab41715 +8362,5859775143174ceb56d211fb6e8b7d3d +8363,8eeef3f08127bc2f26a53cfa757deb2f +8364,b1986733b0d4040260f1f7ea163acd9a +8365,386279ee65b1f99248b916abfb6d2fdf +8366,62651c64760e317a1a6f23e6431e0174 +8367,881384b43ffc5730562a2d5ce6b91adc +8368,eee097609670ae7c5a2256fc7f8676ca +8369,917830318a33167941ea9a44c6afedf9 +8370,50293a0a4084ff2040e4d50d5a0f2fd0 +8371,2db2dc55acd781a82e9a9b4e7e867378 +8372,99ab94c221136b87651639aa6a6fe1c1 +8373,bdc876bd1d9303a7794ece5fc7597322 +8374,1e8cad9b651ec5587cd3f2885f9536e8 +8375,256e78f4bf60acde605c214045ceaa78 +8376,689b86de6acf76a116fd11e9320d0211 +8377,9956fb0888ac1e9eeb5ca509d1239d81 +8378,c83aa64975d75738c232cc8b71571c23 +8379,b000a7fb1fff38417cc0246cf40ccc0d +8380,7ac1f819466ac1d062203cfa5192b73a +8381,8b012b8c420372fafeccddc5d8ba09cd +8382,022e2744775149531e54c4f1c6312961 +8383,797050fffe62622b0ba63a64604e98b8 +8384,bb6b617e8963c3ce3b6889af41657d50 +8385,8da2dd2c18f3f7fcb94f44a1a551b009 +8386,95527b19d7c766715e15e5cfa5f5d941 +8387,b26491cb5b031cf8d889cd65ac2f07d8 +8388,4a37a11ae2f6fdb4db83ef77c1158eae +8389,6b0a0b292721409276109c1771ffdffe +8390,297ca32b80d0153a6d94b0ffb0bf42b3 +8391,55fd1737fb5a9fba48db450e001f2b2a +8392,d9d5c4d05aafe9a92a5816180685ecd6 +8393,9703765a63b60ad81d50e0d5d9a6f215 +8394,2e20e46c34c1ded2e7ab965a2a6ee150 +8395,0d2e202b363defdb5fe4038b32552371 +8396,1a969b095baf03fd86f216d9c296f02b +8397,bca5b3cc599c1c97d8703e8c0820b88e +8398,0ad3fe8233e08d2f4fd8b448152fbe53 +8399,fb91824f1a3fa7a56ac67730e084e5f9 +8400,a20237468d26649204204e3be740eabc +8401,b8dd24f4215019c9e5e89ab1927645ed +8402,0be291498f15a3c03ac012a5b5d21d37 +8403,cd23663e07240a20a3916992854e9293 +8404,c5953a60359017075bcf659edba33971 +8405,624517da134b3d89101bf6b061199903 +8406,9ec008a224424cd3847d15c643ad0489 +8407,02b2eef53296d422216e6c8d964413e3 +8408,83eca283105d3b6ab80c895caf710a7a +8409,9e19587c321d536a58589858c72d756d +8410,f7c0158f57605a735613b55f0abf5e68 +8411,c92b37acc9eb5f41f5d1a6a2dc909f3c +8412,8824c5b7f7bd6e1162d5230d81da9b7b +8413,2301ff3cf1828b76596ab84b99edf83e +8414,c338ae91ec797e6bbd26617996567e23 +8415,68031cfac1a5bab3454ac163d79b6465 +8416,5b7a7ebdfc6e9784211a192db14cb233 +8417,d66f57595d805f58d86630339b838f7a +8418,b338c81427eba2193c2d383375d929ee +8419,4b492cd1edfc5136fbfd93e50b645c8c +8420,1a2c7f6f324fae68fe188b0c308db379 +8421,a709a54963c5d49a685c7c6703d2db0c +8422,68bf3d794a5357b332389c31d01344f7 +8423,b38ae01f411a82d0b9530ca99761df8e +8424,8f983a3e01728395e58c891cba2fdf4e +8425,058f0634aa032eadf40bdf2f7df0091f +8426,f12b248fde8f11ec0ff0d2acbe2714e7 +8427,72b314f050acad9b74c64801466dcd8e +8428,5730f6bcd9c18967b6ef9f3e96852bf9 +8429,a39a38181147afa59c9f569dcae670fc +8430,538e5f55e708a0bafffcd0edda8eee5c +8431,4aa1919515e4515f72dbb70cc5a17442 +8432,248fd45633e029a53f34c06f63063106 +8433,d845151298c5c34603d2205c39fc320e +8434,13364c62c0c724b8505f52b985f9f4c7 +8435,336454e871e60785a3432a471f41eb6c +8436,922b4647acfe6892f55b178582c95aaa +8437,f1ccfbe87192bf8e0325b32419757aa2 +8438,804e2c0d7eb202348e47198e58a454f2 +8439,47bde4507ee3b8ee0cb7ff693354ee0f +8440,403855702e5292db8864374ae0180260 +8441,a3f35466eb0e08384e9b3ef89be6ee03 +8442,6c145beb2d6dbaa1b58d8cc6ca650341 +8443,0740da01ce9387150e5414701e026bba +8444,e9cdaffa370b42fe9910ccac4cbf4006 +8445,3f658f5d9619e2139f20707022ec53c9 +8446,5b8ea3cefc29b6ddbb18f76ff3ba72a9 +8447,29e2cbe267445acc4a62f3b7db8479ed +8448,b27607e782d3be0dbeff7655cf35b306 +8449,c66b1eccca616e9606085d25008ee556 +8450,1674b9764ac6feef6d415f5a469fff8a +8451,42018647f64d44ae2298255a111f9ab0 +8452,a87a769d28ea96b419f2bbf2d46cd1ef +8453,0cd8ced2b8ebe9ee114f6c0f3ef9ede7 +8454,af7228dc9b47147744d6ce1f49b495aa +8455,cce3f422195d5717bc53f3550372811f +8456,3e61a201b6bc64af6144248fd3ac25e1 +8457,8ad44d3c7b735e468c17d307d275fa82 +8458,0516b4157069fb353b35dfbf80572794 +8459,24d18790bc4e3b56f7845434e37c1f1a +8460,fa6315a6fb6f3ca32be1d72dfe8e8aaa +8461,e9a4f04d3694f57b65ddc64d17b7df50 +8462,39497e1da26e5cdc59fac499a8299850 +8463,cc58b35674594a20aecae333bfaaa782 +8464,a5e36314dbacf19a07945eb5a6c0d1f0 +8465,fccf7480b1bf00b00f82de9796fdc9d4 +8466,c0193c33b2808124435a1b9812a95362 +8467,374e5d2d435b245e08ed77bf749aa2b4 +8468,244e984ce07673e16cedd923441dbdb8 +8469,112665cfa946c05aad446c438eab56f2 +8470,30b9252163e8a967e445c69ef6df7ed4 +8471,629a9fdf257be9471b8a680da80c32e6 +8472,7a520960599e686adca81b39e7b0fabe +8473,73633ca5772dafb0896fa7f2d2f77bb9 +8474,25f5a0388cc59caaddb45a37ae9e6f1a +8475,359779607f1dc74f7d9fc749ce47ab50 +8476,a023ea0c0f047f0f481a97b754c6dc9e +8477,05ac0cc15622a66a43aa5eca735c48d8 +8478,63ad95310fe50ff99cda701f0dc65890 +8479,e73dc76c25b35832e87ebccfde350fd9 +8480,04ac489d7a23ea31851312bc2101eb03 +8481,37306f3d43a791159c9321de89f91d68 +8482,43910a38accc686350ecd40144027b3f +8483,33ef9b777bb5283c881500264744e3ba +8484,a98e705e5b930c551dd4bffbadbd502d +8485,e9162d283100dd17ce85ac39dc1e3e38 +8486,0433d815e74d2566fdc23212377b353c +8487,8dd1da7df75afff8f46f5abccdd0c64f +8488,d1dbbf71be1f0a802ab7da5f37a6283e +8489,aabd7408871f94b1e6a51cb3980be36d +8490,f0c1b8c5f9a19573fea17660959ee732 +8491,59c8f53554ff583c76318583ea944ab2 +8492,71c30bf8ec69a0a0b6e769faa3520c14 +8493,bd84714ba577df981b2aaa74142033a5 +8494,ae2efd67fda8e0073966d08e2060fdfe +8495,8dfe90be7e3dd99bdc58c4d7b39ffd22 +8496,cb5f8deca06dc8dc5223a97636e2c8c3 +8497,9ef6263f03845cab4b3c9b9c67b244e7 +8498,b9d97407350034b53e81e0f863f84ba9 +8499,15e43b661a72d22a63b1e6a15d121104 +8500,b6952877a05d0e86a7d13073ab69fd34 +8501,b9bc4e2b84596bf6e33d12da4401eadc +8502,5797dafae5585095be5cdc3d75d3b143 +8503,39335e56ab732384d3edb4a4595f80fc +8504,0f33e0edacc71c5dcefa0a374a723ab9 +8505,eb106499e738f99118feec171fefa3ec +8506,b9e95a4c95bb51f3674249e339f4661b +8507,3e7e9eaa347a761d7bc8737fb34db145 +8508,3849192933bc7b07aab8721bf10ed818 +8509,818e3e898fffae8351bee26640c6768a +8510,f513ff6cbaaacdaa96fe8640f5015d60 +8511,e234e613f57a057c81ff4e531442f1e3 +8512,aebac3711212565be60264e87c2fa6cc +8513,497d96d4c35b558d8e10440590eac915 +8514,45f062136d67210095bd2146ff27d216 +8515,55b669b0207f81bbe331e38b0db1e765 +8516,0d0696fda615348404718af20043d972 +8517,d936d7fcc03873a03530c71fe10f92e4 +8518,d4eaa67d2d7946e61f8155a1e802d511 +8519,d570dd8d10c15ee22b7f6a310310933d +8520,cea80ad3743e19488746b799f84c5631 +8521,58cf38a5f7846afffb446da7e9cf0a4a +8522,2b581dac5d0ed4323b8b2a7e0ac2691e +8523,3706aa3063724402204fd6e880308b12 +8524,609e78f37c44f0baea44533ce40e9e97 +8525,acab7163ec1240877b1916c9b32711e4 +8526,74cff9168e78b7e8c36e526fc6b692d1 +8527,3906ab22039261e888b9520146ca2253 +8528,de901700327fe14f8c7d4f7f40f1ba72 +8529,2eef52374e655e1206a125619251dc38 +8530,0b28d32e30ae2dd8bd133ca222363d22 +8531,b6ec23c59121719c68bcced5d52e8d64 +8532,97540af7232a19b3487b58c4f3174743 +8533,57d1a012208771e24438f06716cde824 +8534,520b17ca534cf7908d92cbab6005fc23 +8535,42a0035b82b597b366bd98636d26253f +8536,011392952c9d4be6484c809def45605a +8537,93a545462f4f1a82d793313c2c54a2af +8538,e500a3604297e43d252cddd8ecd868a8 +8539,bd20d5e8a1c34c954f06172099581968 +8540,6d508e0b8d1c300383df5b10e26683be +8541,30b357bdb7535221952105335de826e9 +8542,eb36fd0014eaa200631343be8d772fc7 +8543,28afdc68c70f13a4b9e653b9cf3abd9f +8544,d2b91116261b8cdd77e61a7711646e02 +8545,7248ed07f1d1ef671e510111091ee855 +8546,441c8732aed7438a865b7acac72319ac +8547,387ab80aeef59dbac521e332cb9ea8db +8548,b287fbf970ca39473c27fab126b3b8e9 +8549,bfb8d747f525680244995dcd8095dd87 +8550,3ee3353f20a186456dd4cbea814bd48d +8551,962806c7a48cb09cf063ef496bcea925 +8552,61c0489bc89ee92d2f3e3516f90e13c3 +8553,7e8aee5088837df4fc5b69a94792557e +8554,2d568b31d1117b786b287ed998d3a584 +8555,d6a80dce48596546635a426c200c2532 +8556,9c06f9b85913dca04915b3bfe85fda0b +8557,00a8cf052eb6c9b860f63c9eeb69f6c6 +8558,3d3fb8440f77fe5d671ab37a3b0e6d3b +8559,72a2303ee4e020309e3c031676c1089e +8560,a048424db9c99911c026deb2a66d786f +8561,b8ac1b3cb109f385d1bfd59a2715fdb7 +8562,1b234b92cce238b27607d2641cbe20e0 +8563,17163cdd8139eecbd73ab774214ef634 +8564,72845a39e2e7078be6a3a23675fcc779 +8565,2fbed53c6e8dd7111cc00548862504b4 +8566,08a506a70f70a9f6c354e8014273547b +8567,d41d9838aafdf1dbe682e9d57e1036b5 +8568,c5d771acbae3ddb91b958ce7d5ed5eaf +8569,85f82586c21d239ad4b7a876072a6e81 +8570,83861f8eab83cc67e7fab5140a387390 +8571,178ed01ffbbee9442b0cea12406e862c +8572,5bd4e16a7ed1b11b1119b338ed39de63 +8573,22cf7fc1b1a8241291a6b33bd7a18413 +8574,6576037c547bf1899fb8a341270c89b3 +8575,27315b2f43f5cb8abd22e535c6fd86cd +8576,e83a3148ed4418fabe8383fea07a557f +8577,bf3d9b4844079f3f4bf5f3d17dd99d1e +8578,44806059a55d37b9b7d4f75d3401c67c +8579,e1f2d2ecf1f8eff415e1221392168edc +8580,918abf9f28c30f41eb9f80ff9c061661 +8581,5593af1d221aad6dc91043d1c15251e8 +8582,e13dd1c143dac915b60693fbb194f333 +8583,7a68c397e15924df3c1ebbd46d0ccca5 +8584,d3b6b353b1f764e1f3595882cf8e9551 +8585,16b2e3fef4bdc24f38326c16a731e311 +8586,9c748046a1fdafca16109fe7b22678af +8587,bf3972426657cba3100c8ea290bd3591 +8588,52908ba0d2d1dbccdfdf586c213d277d +8589,670a604c5299ff0123f053f36072fb5c +8590,49e9494a5dbe330da4a2ec3aa5a3bd70 +8591,53e90a3da4d6a8fd66b4b93f77c8ee2d +8592,591c8c18434c5dcfa21303de4b0b32f9 +8593,0daa45c095bb14e5a781877504122a33 +8594,6a5eba599d2138953d5902287e81f70e +8595,cbe23ec9b54cf04a6f0e2210542d3524 +8596,5b5f462dddc2e1c2c3821fa659c2db16 +8597,db108e22b2b0a3e7497cc60f4c704afd +8598,9629087dbbc729f811ea0e6e201ca96a +8599,e95d8a00928ce07d94a264741381be7f +8600,be56ba3460ebc6f2b69f903db401def7 +8601,79e30e5e0d0f2f5148bc719ed8a4ac2d +8602,82e6c3bd43b66f4557132446a708fe7c +8603,85eef59896c2d2274c1f90ca4305eb9f +8604,9cb067143b253c16665b248736cd1a96 +8605,6770daa6320fdce91cd05b186523b057 +8606,e855d0374153908bd8abf62fd2566d13 +8607,feb21fd6d947c29c4687250c050eec25 +8608,6098fcd300c8a88e04a8ffa6972bf431 +8609,1675c5290c0b7b41a006cb9c01650f18 +8610,2840e38f2663df0995e6ddbb68e203ff +8611,667f6b182d97b92d97533daf8463787b +8612,2d01a4af18049a82a7439aed391c5ae9 +8613,08b80c88c384601360bd3310d506de82 +8614,833d681737778f59790c3f643259abe5 +8615,9347f1dedce024af9e935ec0196d78ea +8616,e1cd8eee1af92a5522413e2837481a75 +8617,eec9e259ef4f0fc08d1b0d4857b3a799 +8618,cb35598e11bafdded4835a05f4514d16 +8619,698db3e27b37fd0c12acd8e6bc6e5319 +8620,0b59cedff1b72eded1a19f37e1b4a231 +8621,1751bfdb8b08f25511f127000a5c34fe +8622,370f060c8a8d1adfbbb137b2807f5a1e +8623,8eee4be971948e977dd0f9e1012f3ac8 +8624,bcb71e4d2af1c738dc70fc571c91a437 +8625,2a4edf1b131c5da8a74b54310db87b33 +8626,0c13e70bad624900fbf9d5bb55c812d3 +8627,c8cd5f6ab2ac67b9a6d9b6f45cb2828b +8628,b4e7934cf1d8a055093981a2297effa2 +8629,812d6b7f2058eb01f4bdbc1188921f6b +8630,afd1340da29fd45009a66954207f8b6d +8631,1aa3863aa97b5bcb5a8133b22ee2f320 +8632,c1ccd1d9103dad32feced0121b247301 +8633,4f6076cf113bb53156279f0f582f5a97 +8634,164de2816f4807c20d13d360405718d8 +8635,57d91b924ec57b5e8c703e0f34da3c7a +8636,77be7e06471eb0591e2697e6b04cf0c0 +8637,baa6887a108b9b577303c623a2c8d35e +8638,770df90b54b81f1335377bd301f0dbfc +8639,c4ab88f88dc1c966110343b4b1f5c84b +8640,8330e340e61d9ea7501d73d3aad746e8 +8641,e643c6e46b2efb8f6970623936ffef23 +8642,d987be2bf826ee2fbd3c137a8b96ceda +8643,728e82b5014057e6b46caa3c680681f7 +8644,06daf21ebe08ccbd37dca9d2cfcebe76 +8645,671a2c9249e8b270e2ea9eb1445286b3 +8646,24b8f8703eaae213d40fa7e07926818a +8647,3669e962dd4b33ca198288a84683080d +8648,28737edcf15358150e6fee22ad29bf45 +8649,40677b5db1fecd41dfb6ee112310ac66 +8650,44092894514241fc53e85034eeff42df +8651,271610074fd83b0110d2ce8a7f6389bc +8652,19e9693b61a7c64fb0f930c549c8f9fb +8653,5e424e7f787f246fd95c9d24521841e4 +8654,69581b87708048c597aa2320cabd1b1d +8655,fa589ff2658564701984950d99a656ae +8656,20d168be222a82a267341887e8cc7ce4 +8657,764c8ee8d634b581519a8c1b9925a368 +8658,0cbbc26e5f1729a5a53d51dae9bf177b +8659,15ed871a96e147049d4bf47b3aab7bd0 +8660,f2152e53dd4ad011058af4c6e32e0a3b +8661,c3a9b151912aada119f6cea31dfdbdd1 +8662,e0890c1787e7a6503191cbd55c713e16 +8663,262dedcdceb58910688db09d9f124272 +8664,ef87bd0c080d9922f016d075398c56af +8665,4fa76a3fceb7d71b165e3ae53a91bc24 +8666,20aa3991aee5147ef50aafe628dc7d74 +8667,65b027e3e78602b4a0dd03687e7a7072 +8668,ec3b662485c728452d04c402f4c0ef1f +8669,d032607b4162ba448e011c31ea13a477 +8670,5208c0848269b140c07acb86b80c46e9 +8671,c1d14a625e5fcd3471b1406bdbbb9bde +8672,36c7a712d2e614822e49fd20d3186abd +8673,45a8c6a3436c2ceeb04d65786be54ceb +8674,ffe410b571b32414d2b0f9181dba9ac7 +8675,ceb365343400fb424d81c9a15e020b04 +8676,06e125c0d999654273e0102930b45e4e +8677,4fe38bc9301779916f134a233c8ecb48 +8678,cc170560b0cf7eb5caab505d87eea5ae +8679,30431e1cfe3cb4073fa29660a35c6f54 +8680,602084dd27d8930233ecc05791709cc4 +8681,ac8d7bae5429030c8ca86fd4860dde26 +8682,4b15b831bfb0bdc94ffe8ba7569bb4bf +8683,add44e5b02db689ad6f32439878addd0 +8684,1b5511a81085aea8c6e80916eb0bca40 +8685,89c08659020af4d123c1b1e98933874c +8686,696d8fc43ba8da28940b2606a4ff74d0 +8687,097909f535850685763b6cc70b199712 +8688,4fae5eefa280be0f294f2e0b5e2e5589 +8689,a8c7a5247deb4f89591ffeb25613f61d +8690,cc56871b10e3d100b6bcb27b388daafa +8691,922d5c452ed3b289077e3df6fa1983c5 +8692,5632dfbf4864fe15be6a6157fda0e8c9 +8693,58ecb05633db25d42072d414ab865c7b +8694,4b3fa84108b9bcccb2b5c5bc1e8a5384 +8695,cfe608c3d8114567e71dd6c4e96be6c1 +8696,517bb9db83a0ac4926e7a8e924316795 +8697,2b6f1985a84a2431057d2206daa133fa +8698,c383463dd91f77458fdf368bedbe3411 +8699,2a727254e21ce1be89bfc9213f8edf8a +8700,3d315c26202afb559051d0dce499b856 +8701,7208ae35c5de93ec9a021f23c8e41d5b +8702,5e11012e6545117382a0762656cc9e20 +8703,46b71375c19aa4d29d9aa5d04c0356c1 +8704,89e839de079dc986cebb3b15c87ef003 +8705,16b2a8feea52729dc8868a7a4087aae1 +8706,4df71fa9721f69aee297dce7898da364 +8707,0cea68fed97cde08ba2931f88beaca81 +8708,ebe9fca86fe25cbbc4b62e11cfcadd3b +8709,9d6b2206115e10e797cab754a9c594db +8710,8f2b7f541acf43d60f5c867c5b620264 +8711,cb95c6ce5316881c2f42121a8f8f1919 +8712,d13b5858a20cda2843c408c2645144e0 +8713,73a8df46bdb33160a0ee0db59f64e396 +8714,6330205d3edb95ff9b28e57fffc1d647 +8715,45dce0c44a19fdd3ba85a8d0a6515f86 +8716,bf0efcff305747932780d934db63f41d +8717,9450558576d5fa41ccd4e586deb8885f +8718,b4b77523abe9db7777924a682c710bf8 +8719,8e605236aad15dc816bd72433f28f4d2 +8720,41db9b9bd53631856c64dc2e749a65c0 +8721,7cea952cc7c6fcac578c3e83571afac7 +8722,5c2e2b4742de02fbae927c94c01a59fa +8723,b67a521f79016da68d02ea6f474c2036 +8724,677a1a7aa3b51ad72aa862952347cb25 +8725,2ea153376fc91d28144f8e9eaf603918 +8726,13be0e3979521abab59928aeb64a834a +8727,bdc822f23f46129b0c1196a8a1ca7b4c +8728,b018fb923589dbc2c046e7b8dd23ffc4 +8729,66a82fd7285187058038e73311c613c2 +8730,63704aa85bd9faa4c6787e571c166a53 +8731,6b779dd1e89f3d83a66b39e52e2e9e8d +8732,965cbbb2bb7096f2be18bdd38d199a5e +8733,ab451220b2611291e7fac3c6959bf7d0 +8734,9b1d2c2291bf8d074d92c65f0403716d +8735,416c25b388b0cb8a4af9da8bab4053df +8736,2a30644f42d51453ff8787203937b474 +8737,e7df2689e1fa3cf4d33b529d80224174 +8738,32540e86870094166397a7d30df0083b +8739,54e0373e8ce67699028333c009cb9190 +8740,e340498208a39fc40b2594a1ed8999fe +8741,d5485e73134dde5bd9354fd9d0d64257 +8742,ce8f542638f463ed0e3257812d27a95f +8743,a86e9a9d84afe79d8b8c89f4ac5f4664 +8744,b5c4e49001d3c74b5a476926a0c9a6a4 +8745,e4f6be28ec744cbd81b2a68198df288c +8746,4db6c5ff8c1e69dc75c3055d30e6fa3f +8747,ee0925b7c83f757913634571b227df8d +8748,04545957ee86c4210c882877bcbc31da +8749,af2ca7fe7082fd770497c2b6605ab8e3 +8750,361ff2f41d6f6c72feec1a7e84dd2c3c +8751,8de631307a9481b824ba0ac536fbc909 +8752,881d2d20247813c01b60f54cd7f8421a +8753,700ab41ac452c4df39efb376447bb259 +8754,8c45a90922b32f252ad92dcad8672927 +8755,b0b3e59b8ee05d19a27cbdd0409250a9 +8756,3912e05bf334edb616db8df6ee214b48 +8757,f952c35077e4758bfbd14bba286dd196 +8758,9286149cfe81340d1515f6126c4f978b +8759,773f185c7a8dfe976060db6d67bd614a +8760,8d241d1b5e3dbfc56810f10b7269fed2 +8761,fc610e294ce717b9376e8dd5a7152684 +8762,125fee454dda9143a5458a55d07e54af +8763,17483688f4b1ac20974b8ff7cceb496b +8764,80e7b56674b6df2d90b303aa80c1566f +8765,4297aa235a01bd01e52900d7c01a7652 +8766,2f7f196d4414487e25dfe3b3a5d18fed +8767,cd00e0c1fa70532bc4ad31bda6562433 +8768,290f1dfcaf30a53eba9287a989e9c844 +8769,6d8d411b330149bba3774e473b12b49a +8770,3ac12a07337dd892b446a581d4e78e20 +8771,292d9f6ded288ec9f80bc4488c906e18 +8772,2f9f53ca528797427c0eefdba489660c +8773,fedbfe437bdb7933c4b9a6f68cbd5efa +8774,f4b570d08c1cecb0e60caf951fcabf62 +8775,6885b37607bcf657a292a15e66106e70 +8776,25088b1cbda864d6e622ce46087627f6 +8777,b543c89fe6345c1c69b9a47fc82b7ed6 +8778,3d1edc62aca37a92ffca4541bc9ee000 +8779,b14aa70624cadc0549424c7aa2ab7b2d +8780,b4dbf25da3201027353c7b7dfb600766 +8781,f7dee849b806a06fec92bdccfffa54f7 +8782,781ef84bebf6aaf890aa8bcfe0b659f2 +8783,1f90769c09330c0c59f6652773c9b1e6 +8784,2fb783c18931e2afd522b008fd69707a +8785,7d96967b5b7e7a8bb45ba5e35820f2be +8786,d7c45716bec0fbe591e4a4510b168b9e +8787,93524c05b870635cdc89a67973b19503 +8788,c5624ef22a3dc94c14588f91a3ad6bf2 +8789,e7ad1011f73576d94dffd19c15c281a8 +8790,0b9de02cba57c267840f9056d286a88f +8791,08ab1bffddcfb9dedf0282ceea6b3a19 +8792,2c1604952c849fe3e2b7194599de4b73 +8793,ddfed4a1b97cfd455b1b4fc35e02dac4 +8794,61d8315e8ecd6d5b1af80a6275ce7a10 +8795,dd81a96cac326b08eb7454f86582b11b +8796,ea3b82fc4599686e67f8d1286650879f +8797,3a745e1bd2166748ba130a2dd659c091 +8798,048070982872d04f29a8bf5c7faa60e8 +8799,6d67a9c78787bd50bb244999afc5bc4d +8800,33f1e3c21c4f28171a9a99d96fc6d4de +8801,c70730ee2bf0ca49b65588425e5e9b40 +8802,fcb08a529131ce3c90be7df734912a8a +8803,75f74bf78b185abb89112742943176da +8804,cb5bc91a66a21662759396728718d410 +8805,35274ddeb482ab29641cdb806ec2c5eb +8806,857401eefce0ca048032de939cd4d8d7 +8807,e090bff5268ac3b91366a1a2b5a8454d +8808,abfed632f62588ed19f831a3c62662de +8809,4e69a10bc23976fd5fdbd4e8dd368afd +8810,fb3af906d3fe2a005531b0ace3521297 +8811,a1dc465451e3c0dc0adc5834ee396706 +8812,ab5b1a4a69cc87cf1b0ef3c8caa21f6c +8813,7a908aa06ed5b0f82f8d595bb5df4146 +8814,020ea6259d97dc6839001b88e7da808f +8815,81e656c8ef9b9fdc207be5174aa1fe36 +8816,fcaf0162587fad17175458924a88983e +8817,217655fed2d05b8762517d777dda9d4f +8818,3d90a2e35de1e5a94e5cfcbd78345b40 +8819,e073f065022b62199f53f46364f83717 +8820,3adbf4562a7a49604bd4a5e4864a3a6b +8821,e1bf193628bf9d9074bffa6f54e3a9c8 +8822,226e59aa4608ac514153c0337976b574 +8823,043e2f6900028b8a3692c3039bd1464e +8824,8855f585ad03f5b0eeef0e6063a5261f +8825,9640178e3b83bb572653a7770e0793aa +8826,45f0e311fc9535283c2d94a52e82e715 +8827,e523e16dc2715557e249ae89e3288e52 +8828,ee36d6180220c6046c68eb067b1d775d +8829,c277f16fe8c36afa1f56e55331269dc7 +8830,77069e76df004fdd585829944e2e301e +8831,7f4996dd7485280d1d0bbca7917153cd +8832,ff52c724b687b60be4dd557efa30217f +8833,6c85c3e4388bc6ed00387235bea63293 +8834,f720a05b1eacd53471fcef4094ab9715 +8835,972cf4900920f1ff8d5380f2880d901f +8836,864e9e2ebce159490f458515ca2c56e3 +8837,0cf908c19ea513e7075239544aa38c5b +8838,3b719b5abc0b4776acb451a905d25260 +8839,ca4e385c0cffd6e13726359d7aa2f7c8 +8840,a18262550f288a89952b87cd42ae214c +8841,b3b7d4a1d14b8fecc95ab8ffe49f1d75 +8842,1b11cbf362a2354296f043ea22e67fc4 +8843,53e5e303c488050ffc3287f316eed45a +8844,f14762443eb3a9b3328dc4caa89274b1 +8845,1a1c49e1953d9352e5684e12a9509b83 +8846,b1ef9b9d28525dc6f73c2ba423d566a5 +8847,bc81a07ed579b064000199a035184bed +8848,d9db53e7f47b7c5b84dc6c638c735ed7 +8849,e2b6e701e3d3a508e08071307d3c06b3 +8850,9757a549dc3a4ae8895677cef966a3f8 +8851,4b2b9eb5fd25fc78684b53e142aac343 +8852,bc257adefa95bddd9b5bf8e1485176c7 +8853,be46f7096c7d4e17bdc8c7338a6b47bc +8854,e917c1cac9b11d9d51f0448263191f4f +8855,168f88213601702728fc158bbad4360e +8856,8bd0bfeb94b2761966900be01cf6b530 +8857,2076eaa6cdff4ced9afc5bbe1539b595 +8858,f68553904ea33db1c026633c46ad1691 +8859,3a9247b38970f95781405325b67b8239 +8860,4135a24d54b384e906cff080d53ec993 +8861,c1001070df88d31d73f80f3574ea9a59 +8862,87af70c1826a50347254f625fa40116b +8863,52bbb5640de58dc0c402c887c7f9e252 +8864,8feedafb3ed330a24b69ebe7ffcda887 +8865,6f0082404bec94e978a850e243568e49 +8866,4944daf37b039cb9115219a20a00d46f +8867,041cc5e8cc67415b30653a63eb61b7b6 +8868,e4e0c6d9f64d78a38b202efb698847e4 +8869,d62c1bd7b6bd2d3e45e5f61af9f9d57c +8870,2aa3deb71d76f3a625da070fe2419cfb +8871,d7ef3cb70829b2ab713b6f8c913ab055 +8872,84d9e79c6e2241e553973d6601eadf51 +8873,55c305fd989947342a0f5d9d3f4803eb +8874,979e3e67842f0c78ec6799e21cfecbf1 +8875,6a898fef8f4e8dbe98caf02a0ccffd8e +8876,1f25c122ce7f81fb98eeb84f8487bf92 +8877,8bf01e54a0f0a642d901d13c88a9a6fa +8878,75eda134b9ab253a047f2a053ec5a957 +8879,40dee0e281cbf54efae4b8fd600ad517 +8880,127ffe4b7bc3d047fc9e8e659c857430 +8881,6e6885a888e32653e0ae4cb00adb3e1b +8882,fcb7868c91a04cbe47499beba59562cb +8883,6b5b81c3b5232aee24171ec51e1522ba +8884,863638966c51d51c64191c31cb9da243 +8885,87dae0ddc0025873f3d75dc6df45dcbd +8886,40063b08fd9cfaca93349034688afa5e +8887,e182755ff71cd84c82d796a236fcc4bc +8888,aa2e5afb805e293fd340d97894726165 +8889,0d059fa62c880c1d41fbd9cb3c7401dd +8890,62159e8bb2fe68ba946da027f20006c4 +8891,cc486e64ab1cef17019c3e6a481a75de +8892,8be84c9e3937d427f1c94ae1b1a94343 +8893,3e2685c128884df5b626764243ed0899 +8894,1fddb3e3693ddd4b2aa9e0059940fcb0 +8895,78499f8ed563dabcdc291402d6ffb6f2 +8896,1a639a0b7249f4a6a513425edf29543b +8897,fb8ccb74d63a4650b2c2aa41f41800f3 +8898,36ed601d1c9bf9f6e8c1a6ea28251c3e +8899,875f4ed6ec5e39bb71b3e30caac1a1c3 +8900,ab8262dcbf8c50d47354f2004b48f472 +8901,63580ded58a8e9b9b10d49fd47b0cf35 +8902,cf6a05ced307785749da82e27c7522cd +8903,25135b6f5b8de530b5950dd1ec889064 +8904,70eb5dc37c1d248b1facf374a034b870 +8905,34a97c03e96a447a3744df9602a81757 +8906,2829c5882f2b6d6abcd0474c6db2a9e4 +8907,47ea8663ebd80a9f4515019e94efaf5e +8908,7877c6e63b984fc9332554b15161fa96 +8909,9fb6c68fda509cc048fddbc703f68cae +8910,f27fd31226fe9657c424ab27fc6dd73f +8911,4b6c1d3f74b42ae55c9b34d8d4678425 +8912,3da04ad50e86e65c799e54185dc7b823 +8913,607e33efae929dc6af3376828975c94f +8914,67b86d942b2a468a318b051e9e4ebeb3 +8915,ea708cbf1de3d4eef945df3442353d87 +8916,6e65103aefc50c776a0432e1aab35b59 +8917,fb3d7a9c57f4c1b20460c5de60215e5b +8918,1d9c6c0ce63b72b3e366f5763c5819d0 +8919,8d41a528c43de23de0b5cf442d2273c1 +8920,ba80b8a956862baecd344919804a7042 +8921,f7a92a9f2b4c5c546163e88866b91e4d +8922,7f2d2a2ab3e0c8aeec061161b457e0bd +8923,a36ddeb5492f2d22d884757cc522f201 +8924,b1e9b8d80b649b2ed847befa36bb67f2 +8925,3e2c705b886d34a40fcf77b731ba68c2 +8926,4e72d7dc6db77b3b6202dd7acf5c98d7 +8927,96a655d582917d22a71cb447fce1bd18 +8928,8a029258e46f8c48b81597e9f1c57985 +8929,792f5b0bae16c1810d97be7b1e0e6241 +8930,4e7d3c0c88147333bd735967db0e69b4 +8931,63b39b9bf87ef0af0c7c2ba1aa14bbf5 +8932,c9e56c5c227061ee7d78654d3745cfa9 +8933,2b2e72039d55df27d9d0c0384232465a +8934,81d082470a398619d36fa7cb11f998bd +8935,8c931807882b2dd3950bc6a3e88ff73e +8936,22c1fa0e158ed2afea9950415ed8dd1b +8937,50ff4ff0e233ba05b53997bf2755ce3a +8938,d4842640ef4588e6a7a63f47b7839a02 +8939,58b8135d4899a49f84aef74318ae02b8 +8940,2f254c8daebaca3537796eb83f84521b +8941,bdcd7a2319117775fcb9d4176007b88e +8942,44655f21ce4f9a00c5f77e7f7d701f2a +8943,fb0948666799daa880282d7898c3eff2 +8944,4f8499038e078d6fbde1c3bfb4fdb65d +8945,982586cb919dc183bbb1f6292cb6e2b8 +8946,3cba18809f81a322bf884e5d6710c881 +8947,2b11e18c9d7868ac72ac029b6c8297a6 +8948,fd76bbd9db0cfafd29b0b81a58af3cf8 +8949,fb05dd3a82b0041d171dab91bf4107c0 +8950,1c455cc4ae854d5dc05ab9c8526ab2e4 +8951,586a43f8e0d5bfb5b522abb67d0bd1d9 +8952,7679740e1e10d3f461f3f7bbb6ba768e +8953,faf92a63d47fd85806dfbd9c827d214f +8954,b97ca216d77f0d7b337f19e859ecf576 +8955,94233fbe92ecc96a036a1c88319ba29d +8956,caca524e8ee51e1235e509b5ba70ac90 +8957,70f77969ffe55d8eecd43960fb1b65ee +8958,adc4b6155ce4b0e504cb0a747b7f1ef4 +8959,2d951034a8e13dd1781bde69f9de84d6 +8960,149355dd4857232255666dad90a74085 +8961,31fa7a91b6c32dd1c00437451e27da4b +8962,bb6a482d9795d34c2cde26a5c397f32e +8963,89ca094bec938c87401cf33837597660 +8964,ac8569e35e4a5d225f10025c9090dd21 +8965,84a2f91825037e6adf037ddaaac49fe9 +8966,54ecfdc084b3e47aa2858ce2f176d108 +8967,c6d0b630c54ff23c9afed6f1b2da855c +8968,a6d9e3814a1edc206001034a416a3f99 +8969,f097abe46c791e7f2b5bc6263a2d8c55 +8970,9e538a03bc53c684b6dbfbdec1835b7c +8971,6cbdc1ad2fe765980bb91c2eaf41605e +8972,93310cd8873dc72591165666475536bd +8973,7eaf55ddf27da285ef5b84e40ea8340f +8974,f6a39d70d3c390bebf90c71e6fcd9690 +8975,59147e0441d9b7685ae7d6b5bc35604d +8976,2b2368afe6f0fe9459546917e9f500b5 +8977,19a8ced2df139a90022d1b6a776697cd +8978,a2349a84dd50f900fbe52fbe7d1745ee +8979,c25013557af1a7049f3c6e37bf0e1c29 +8980,4f7734713dd13d252f8806f1415467fd +8981,05fadb33e019c5da16e3f8620c4e2099 +8982,1cc988f01a5ab792b9791add5aa43ce3 +8983,82cd7f49b95692054eed8436c49aa96e +8984,3a6d8ae14b46cfc740f2e97243926342 +8985,6b2d245597b787b8baf46fa2b0719321 +8986,f77e82198bd6c8437e9d87ea8c4994d8 +8987,e69b3b6e00536649cf690294da591a65 +8988,11683a2cf90b84008a135b49b6c3a2d4 +8989,db37950ab71edbf995d1d318c18d3237 +8990,6051a7b9a8ace8c8b0477d890f358ea2 +8991,dcec89d8379e1fbe5c6b71629ab15040 +8992,ced2055f8eeeac42effa72d4ee225243 +8993,b11ae472fab484ddf7345af480590f1f +8994,bd7006a522766285de84637c8847ae85 +8995,da161fc9a23b23f9bef3872b55c22fe4 +8996,6feb18fe28512c337c76f32286bd5077 +8997,8b203c6ebfbb0f0a3264cf8630780988 +8998,6635993aab69de2fe4e5103f1525149d +8999,c5eb4032d1cfa7445fa98d0b20f13b66 +9000,a82a328a4fc6ff24396a66704ce89fb8 +9001,8de40febf8ae620ab491851ca82daabe +9002,3800dc1121ecad7cdb97bfa1666a97b0 +9003,9456a1eea81494e96a6d5ad73eb6017a +9004,0829a71f6edb6e3c350c35859ea6e079 +9005,24de0a9f07a2acb336c1c080866a0207 +9006,d0611c1d25923cc74423d7f2f9d7588a +9007,f3de045d17ecc9725d8eb3e6729293a6 +9008,aa415c3671b625913b93dc2d5af483f9 +9009,be7eae0c1ab061daf6c3d013da0c3b65 +9010,15029594ce676f02c8011e90fc7a8e48 +9011,5046a48365ebc1d52713f92197f07cf7 +9012,ba3ce92cc1b9615164005278075acca5 +9013,4d90afd00af07f638d6070e335d18884 +9014,a096dd25b37c16dde463ebfecad39c77 +9015,edb02f2ec609b476713bbe664f86ebd5 +9016,9706a8c4538de5b5267d1a76e8aa7d67 +9017,d1a11b45de8d3d31fef30ed51ee76626 +9018,8c66e2103871ca3313bb9c6f1f0d46a3 +9019,df81a87640ad11dd2187775d4f54f659 +9020,6b944e15d6f08484a4a64b01b80505d6 +9021,c3e87ca203a4f9a1d255ca8254ef4c60 +9022,ac767d72da02afa5e775f1b1f814665f +9023,b1f51f1039e295332229384c6d850fd8 +9024,c6ea85b94c46bc9e60044e320ce9cfa7 +9025,1f9648732dd4b7648a6abb7aac1c2386 +9026,bcc744123fa90ac7ec5470909cd38527 +9027,bdc0c9860534fb84f5ea5125a6caed4d +9028,9e2f3d287a21266a3b9a9f999e900249 +9029,443b9cc8319a5d905571e063a43551d3 +9030,fe2a7a1e1fe5ae1cebba26c12063ac43 +9031,b2de256e64c7d0a69e0f6a5124459889 +9032,9515447137617e1b1c4425486f93af4a +9033,e42996ddb24a196969aafb360087cb85 +9034,d3fab58adf2fc0cee1002f757672df6a +9035,0c4ebcd47a0b04314aad82d5bfd61b71 +9036,7019d0156ea0fd1cf008233a57dd8923 +9037,0c9d7a046fe0d601ae5ce3c102dc1861 +9038,626b176bede103927e9ce70c774cbab9 +9039,bd6c0d737d05ecf41c302aaf1622d1cf +9040,880dea83d8274320f47e9dfc2fd4f786 +9041,6fc1dd7806140b7879d722b523e962c0 +9042,db5dc15aec65dafa26b5b7f5670795e9 +9043,a66c3c48aa04999b87bf1c2e3ce67c6e +9044,9b3730f7cf1dc3a4f6283ac89f9fa864 +9045,bd2c7d7e6ddc596ca454724e6688be5f +9046,f2534c90ff808ad0e75725d8360cc8cf +9047,c75821ef004175436b20dacccad6768a +9048,2453ae71df7fd5b502a8c8325b79a934 +9049,a41b72eb4a39338abd5890cf31728fe5 +9050,288fca3f15914c458af0e78a1796a41a +9051,881a78a8d6594f9d3327fc1a3c29fb74 +9052,6243ba20e4a391f1ee444712a9fffb91 +9053,e187a4192c71d8e1e74efbe928242ffe +9054,c8c1719f1290cd8fdea4adecd4d298e1 +9055,5ede80f83e6e71a3c0c7571564bff457 +9056,7c5e4b4e29864e1bfa7c631542ab1d23 +9057,9bb3d8a203fe776af0d7b4dac5b5423a +9058,1ab2636e5b47625d689dcb6a5ab87f3c +9059,a2b1a9243b6f35bfabbbf64f5161f745 +9060,398dac9688a336514980fc518efcde99 +9061,f52a65a0353d9fcc90173375a3e22465 +9062,5a83928393fdfc696fc6b83e5d9f9f5d +9063,acd7089e5788b9e6897fbf81d41f1c4d +9064,704024e8c5bd8375fcc73396969c003d +9065,27f15eff5defa78c53e2b5cec6733a49 +9066,aa52cdba38684eb35d1567adb5535224 +9067,649e66f5906632020292f06125d05b71 +9068,2d13270ccb1b0f657e81b640c0b381ae +9069,9a6b78d12e4d4821c8e925b2a24177e6 +9070,0f59928bdd467ac6a665ffa7410e55a2 +9071,5519b2f89116421457f1e65bfd90b7c6 +9072,19e2d923e55938b75104934402b43bb0 +9073,9c3b548103accd5f69f059914499b9be +9074,a5b987721abaa97c8bce49f5c0963e5f +9075,6af94421cf61539841af36e3a5f02861 +9076,b1c9cb1f23c6af5df589392c79719c48 +9077,7ad6d634e2e179dd834728d58057005f +9078,88ae6e24267c2959e5dd8b2d29ae4e93 +9079,3853aed10395eba1d111907c81b7daab +9080,d449d1af0c501694553ce693f2e6827b +9081,314875984807d72208243919e750744d +9082,05ab169d5ca41ad42e6e02e70b87a708 +9083,fb8107815916aadf295e736e72633329 +9084,93d4e456972ee7c4066cfd3a5e91418c +9085,c6eb4b7c2c5e2c1a9f573c25a8599a64 +9086,ba1cd03bd1a44886a6b4b6f437adaf20 +9087,77d9b38bb31e1a2125740baf1ddd957d +9088,8919bb86af84894db97e986524393f01 +9089,1eebd356657ae48ed192eee331dc5a10 +9090,ae0b6b3a96bcb42f6945bf0fcd138eab +9091,1191dfc9732bbab60cb090b6471d123a +9092,c5314e29e8541ea370db500706780d4f +9093,a33ec1e8ad45622576c3a5bf331d913c +9094,a1ff87737aadf63e9ad3a4f7aa0b14d9 +9095,7fb38bc45c29060798419e1b0d2f3225 +9096,5b710681efe0773ebac600b8abd29534 +9097,45ab5f08f119970f96518ef526c0e369 +9098,b7e68ad9efe9ef0a8190134f989503d3 +9099,79412709b43955d64f00014aa5bb1967 +9100,67499d3e0869bc24a26ac0f6de6893a4 +9101,42332b0ecb85dd4ae015ce6048b12ff2 +9102,8ee792d7f2a0dd6be9cbf3ef357282c9 +9103,f6829b7a5bfbc731b3ef2c42d37161b7 +9104,af23be4ca96afeb8b881bebc09249306 +9105,633012c74a680aa34291a6227e7b9218 +9106,c294c78c8dc06e323b82b4ab909f0968 +9107,65e2aa674e71af9223700c2b0de49b92 +9108,3c66d783f9a5d6cfcc201b50c7df56ad +9109,ea680019e2e7d02f0c08d443b4ffe9e9 +9110,7893f18cc0e2be4023ec8e7e22ea6eb2 +9111,844235a7f68c815a07d26421abf74d69 +9112,31ebc790cec2bf97dc92d882ea2c1f5d +9113,96a9c0b9b3155f1acca7328c58d2aa24 +9114,fcda0681dcff102dcb09665b2c3bdf04 +9115,1a228a760a87b42ca9922079b56b9501 +9116,bd5a5c93ed67402ebe5f5c451b80664d +9117,63944f6530128638d5fbb94e28965202 +9118,67a54252d31dab48a955f1edbdcfda7c +9119,290883e84f7cea88c4eb621caa72618c +9120,f0ab5d84830aabc1f5eff8a7283c8c9b +9121,9bc19adc08882e8a103d08d9527be489 +9122,8260296284576f6278a1e0135a11d19c +9123,5337f0c50f6d10f8a8f9c2a43d84300b +9124,3a7cb7c2e253c24368e60d0acc2e5327 +9125,3e23fef9409f4a7005aeb20f7715abfd +9126,866b8edbcd6786a7c084dcd46bc67ad9 +9127,cadf304a54f1944de46f79b3b49454a3 +9128,611e4a63a9aa8421db8eb32e472cb79e +9129,bb64434be032835206f0d65c545e1f13 +9130,ddf041ed93af751635238280a7156ae9 +9131,1a86ac9be3cead352a875f85f1ae5a03 +9132,0589e7476eb7a842a8de669795ef3fcd +9133,3fe0fe59bd306ced2c31d078741fc4a2 +9134,0e92fb44d1860a77ceb7a2a7e1249469 +9135,88858368a0a6852398b77ae6b853828e +9136,cac79ab9e20f7ad6377778ac8b2da202 +9137,08c7514deda7277d887a044ee88f9479 +9138,f21fb7f9014b42526e927e90d039a435 +9139,f455e8bd19d06353826a7f6589d25135 +9140,5de724873d756e67c82e552c69a1c900 +9141,792cdf7b613d05eb462daa7bc7353bde +9142,0677acc1ee3efb8232c628911778ec60 +9143,67235eed7012a416670c5691164f0134 +9144,31d8df3677c8637fa58c3578242942e7 +9145,41994a6527b1e399b5031194bd89c13d +9146,0a2f7a52fadfb1eac2a1247bfe35bc7d +9147,39feb40b2bc57f5cf1f61a7f26ba0fbc +9148,3b558c71b95c59571b7d7659ad53f445 +9149,b20c990977647b42c29b6526fdedac7b +9150,26627040e14b707880fc579304e3514d +9151,29f59bff88702bac428a986291794318 +9152,b6e90e28070d5379cc506188cddda1e5 +9153,88540fc1d3901d5144a09b73ca87ff6e +9154,b25083563ce22e4c350e88a4fbdba72d +9155,63aced483b47de15263bd0a5c0671405 +9156,b1a86f35524ab255d0ee9e88caf642f2 +9157,907d33f0c7f15cda96a1ff7a88d36c9a +9158,88b57955da19cff85311e3872b88fed6 +9159,bb3569d8328f194a25813cccbf97bc23 +9160,21637e814d852635121e350028ea3122 +9161,eaec1ae69e95774454152232922897a3 +9162,f2fb069560900478797970dab939e5ff +9163,3c60b417c682201c6b41e8eac0dfa2a3 +9164,8249bccbc44fe69796f9e4fa560dfcab +9165,69979fb08ca260a6af79fb0d3610b952 +9166,4d9ec27d883eef099b3e78a8cbf3a591 +9167,7022cd602374d8c4a506263a7deb4565 +9168,af9a25a0c98daa096aaa815ef6f19076 +9169,4fa8c54a711b542452fa31285b15649b +9170,2ed333abc426cf641c3c910b3232fa02 +9171,1e1a66bbc4de98c459eed1fcb81f645b +9172,1d490cd771c3c94f65a262e87a915240 +9173,e54e82bfcbe00be5854fa42c2621b09c +9174,cf26a827bc497f9db3a3639fb2e10778 +9175,34444469df9411d685eb514fcaab9141 +9176,5489c6a6e58a3a4f643e7c0cd3be865f +9177,4a97a6eb77c03287dde0d87c4b6954ff +9178,ea5b54567a83bf1a8358e602ae77baac +9179,d8259b048db7f1de70c2de7770f34745 +9180,581666b59ed4478497195f2a7f611e1a +9181,a4983a6d5a4dc2032df60872be511bd3 +9182,4f89becc7f47a5497755a4c530276767 +9183,2e18dfb0712bf57e23351f12aa183eb3 +9184,5c33149f9293bf5a930d7e1f0631151a +9185,e1fee8a84e7f67292cfa267da90dffc7 +9186,4412c1b573e907bfbd9ef332409be99b +9187,a51de2e2a331fa49f78c26217a5fd423 +9188,a1c18c2d7f8fb36a032555f9c83379da +9189,0a04a1e22f0fce22b7cf9b9c26344103 +9190,adc11a3166e06f57d45fb8be136e0fb3 +9191,31513c27247b8c445b10c060c6640848 +9192,131e7288d1cd6eff42ffae83e5d85019 +9193,3b2908b4cb44a5b65799d329054988d7 +9194,e8b38bba70aaa7b12f0563d324050985 +9195,2f7f3c5d4f43807b10a24710d1861789 +9196,45fe32adc2c1df874311c4c95fe14e1f +9197,47e24b66ffbca8de79fa47bbeefa6f7c +9198,6618eb7f918aba375e073ac7859ed19a +9199,61290c1cb0fc510060139162854e6c2b +9200,b0c55a8fc969f5483d5fd19382947b35 +9201,526678e52fd199d15c9cfabc61b99b33 +9202,e2b7859e92afdf54361cde8db10d01a3 +9203,4152c9590e8e5681bc9252c4b1a38cbb +9204,e5d687e1ae8a338f4365bdf94098a355 +9205,2c4899e45f60f7430fcb72892ad8c99a +9206,b7f8140e8e4fbf404848e2a762ffb50d +9207,7825592db2a72d1c75a061a213e153a7 +9208,a0777fdbae838a1b656c92574d0a6c58 +9209,382e675e6fa714f7075a29a288067e84 +9210,143cbcd5cdf80ec3a337c8c388c2b365 +9211,276218e130bdc8e0e2ad57b02b6535a8 +9212,2a53f2217434a1c65bcdfc01051f640b +9213,a0c5e411e433cac58b3a2dcb9396966b +9214,bd31f8c70127b12ed3fc7888c1eaefde +9215,d73bc73b705d4699263eb2da3e2392b8 +9216,3db2aac0ada1cc9db659f408c065a742 +9217,60b2b93d12fbfa319c568a9069fe4189 +9218,5ee6411dbd3661b3c0909b6ee6e4cc3e +9219,b4860a66a72b718ece2c938c048a8933 +9220,85aafdeddc2354e270440148698cdc35 +9221,ff6cc2e6f447300929867f4374257636 +9222,3858dd18bd97a22f47e771d671558ca3 +9223,af7dea2a581682b7d3beadef6ae29439 +9224,cd475c764660384f8755b62d82064afd +9225,e8f260ac5776b326d8daa8fc9b463bc3 +9226,582d7d424c7c2b142de06908c25f7e22 +9227,d4ce77413061377b284ae58b2f56ec07 +9228,b69ced40398d4351c695590dcc8fd701 +9229,20b2c4b5561d903d9ac331e854d2c225 +9230,a3b0a691daae470c739f67782e116927 +9231,b28af1871ef1eaf8816e8d2eb56264d5 +9232,e66f71c7d09218e7423205686fc9bbc3 +9233,022853674523f9abd250fd0feb300fb2 +9234,6bea8ba355b7a90512870cd5fab31066 +9235,55083e288886e0e1a99dfb9c5b4981a0 +9236,367afeb25752437f8c05d2f239bc8c64 +9237,bd71dcfd0fb281a4ec3b78eb8c2ba723 +9238,c0c7ed1f807d608fbfd7af62191c6ada +9239,3aeff196567f0a064a44f448dcccd110 +9240,883c49d69e13c5cbc2fc25096b0c02d5 +9241,93101ac4da519969bd78db7e95bb3d58 +9242,1a05cc56316aec9e7a5bb029ff8801b8 +9243,8821aeed8949fdc8560de72b9e475078 +9244,43b03e7a0db8a4e64cbd120058ea780f +9245,8f51a216cd44e8fa38112cf53a777e82 +9246,b0de3dca401e1bc301d520732b4ec091 +9247,cd18fc33b7c2b77cec5069dbd0c88766 +9248,d4706ce6c7ebf6fe5d86c412f0648c8b +9249,8a8456ff810ac2419f5df715bc0a84ec +9250,b11dbfc74bcc17457c3ba0441f8adf5f +9251,c6cc45a350b3b97164d31f3ea89ece4a +9252,8bf65e344330feae50a909d4fc00005b +9253,08c9ad06f3ce285a78eab1ba663a6e22 +9254,fae1ff2aa0fc12f7433a39c4acb9d0aa +9255,5534f605e1e0eeac9574615b2bd0bc5a +9256,64bc3302ca923966ef86b85f9288d3b9 +9257,8c12ad5c984a94ab43ffedd613b7faeb +9258,5971c15e849f78f5feeed6bc2bc63e19 +9259,35b95beaae900c7749b8f00c2e749fa6 +9260,2e0817b3775f3681dcac210fdb17931c +9261,695347fab38f133888fa2e9c0018f0a3 +9262,0de8b81785816cc7de7e459ca02beb2d +9263,afa2e8d2962ef7a27801c3a89c2a3396 +9264,04af59eb961d2caa0cc45b771d0dec32 +9265,74ec22c04173ce2402fa935a2d534741 +9266,2b60f2015b7e8bb01b5730713b3cf40b +9267,bfa768bd9d9466979cb34970e2d1b467 +9268,31ceb139279b2cd5016ff426dc8882c6 +9269,90e1174d5904691fdab3e87aa5bb2e57 +9270,af042e464a2c6d35cd0b536dc2503fee +9271,2227b18847657ecc554881f5f43857d1 +9272,4acb73d55b059a59dc02e77a44277e2c +9273,971e375bb29402885389f014f4bdd8ed +9274,3f0fd393818b240af321959094cc3817 +9275,b4b82fa0d1b72ea567fcd6aedf0a72af +9276,0b20c52a6862bb54794d6f96ff583012 +9277,41ed3ec6a93679d55f4e042ed622e272 +9278,85812e752d655280e57fc5d36c4dbd25 +9279,0deb98a427152fc763109b1027672662 +9280,6abc108563ccdc10c148f66b561aa41b +9281,c166f05eb28f8ec75ccb95225ad9ea7f +9282,c247ea91becf0da7132bae3e3b6c4a48 +9283,16641405fc395c762bd9240f14a0c7eb +9284,ac165dcc61a1c1e20bd8b3f6fb248fdd +9285,9978db89f8e27e1017b4f00bb7f54146 +9286,a20288039172d6fa57ba4edf8b87caf7 +9287,994c8f383e0e889eff5e674ee4f1e3d4 +9288,80469a79026d0322e6791536c36878d5 +9289,70f5784cb3636128496c51131d82d77b +9290,b17286e0448256090276cb129397f191 +9291,52960aeb64f91830b6c0d5b9df0b064c +9292,89462d358aef6af400592f74df8a4bd6 +9293,296aa856f79fe5e94aaf596a18cbd3de +9294,d7a183d154e0fc680a294716f7d31a1c +9295,6aade8152ac8f1c6416ce21b5ae7761d +9296,0cfc358ceb21cbd58fa7dc7215543077 +9297,00d9f63b369c086057bb3cbf6f798c18 +9298,323ccc15530c31fead895646c9ab845c +9299,b901ffca7045bd313d95270c2875a8f0 +9300,2f6bb9e0698b6258d20a0ddef33bae5d +9301,f09afeacea5c48d34659aae5ff56ed02 +9302,eb539b3d88564698fc9d3e6cdba180cc +9303,a706bb0becb284315b33bf446b974cdc +9304,27d56f330f0e3987690a4df67ea90823 +9305,4d2069ae5741855aecf8056cfa0c7420 +9306,b7efc93f0c76b50d5bfb9c06e7045188 +9307,9166b8e9ec18259d9376e62ea41dd8f8 +9308,b6036b69b5999e6aad11d1a7238cffb5 +9309,2183c976c485ad8fa2f9f413f0eaca7d +9310,e99204fc6bfc506c37dac8e9f7cf492f +9311,4986fa333b4d6737f893d167bd058fbe +9312,b830019611f0e2e7fe86d16062bf131d +9313,8928bba4846db336c41a12eeeb8d3228 +9314,98f15a9c7da6a4ef69cd7c3aec932ee4 +9315,b5515ed6accd8c8553b2adac4ce6893f +9316,d9dcdf481d35e3160dc87ac1c64c08ef +9317,8529343479117698badb62ffb500c5dd +9318,a6f41beac62e9fa3b64ffe1c864f6826 +9319,f77b88222ab9f29289b6e6e505bd3260 +9320,589769e60ebd5276ff257a6aba1ece16 +9321,70acf4f9718ea4b0bb094f5a8906a070 +9322,7f778c9ca1db7bde96c5275fcb33522f +9323,596fd73177db0a26c4909feb1ac874ce +9324,9ad74f45917549e86637103799e995b6 +9325,aaba583e54e5a0a6e985585e82ae0eb7 +9326,24e98f98a40091245895ef20de143133 +9327,9a7a388514c0b829d13ee2403338dd4d +9328,39ead172357b128916b95fd0f46d06d3 +9329,84e20a040b686bfc8bf5b9383d4d428f +9330,9de8c59d587c4a6b75a87168e14d1821 +9331,6e849deceafa38705414db781e8fbaf3 +9332,e094acd0fed8ec74320545011bc49f55 +9333,f0352379d4f67819b8e75fed148d8849 +9334,83d3243256615590fae7ec47b36ef1b0 +9335,b06d20e89233f5117ed72110558d94fb +9336,36956fbcfedb2d132d64f5b0eeb531a6 +9337,9836ef5ef2f404606d4a50d2204e06b6 +9338,e71f88c36a6a409f77f1b4c065f5b36a +9339,e61d9bdefc886cd6238a80feb622ac60 +9340,d3584668c8217b04ae0420c14704f942 +9341,294ab7343d84ac24d0cec432c4bd424b +9342,74a87a31d264b0663ebfee1b3e8ccc73 +9343,a88a636eb4d3db59b7f267e21c4ca738 +9344,bb92b5cbf147b75dc179767f4b8a01d4 +9345,7c3ab7daa65bb9c161c9da5dee0ff120 +9346,f38dacab30123789623e99ef3374c9b4 +9347,5c95fc43d8498ec300de01627c8ca9c6 +9348,a427315d240c284ae670d28de71c8a45 +9349,2da184d5ebf1b077857e4d29edc8ff59 +9350,bd1c20d98b053af7f4fe621eff3851c4 +9351,b0af40d94e8d0a26b20775ef7e904362 +9352,c6a16bd5382bd1be219e4cd730fb4110 +9353,93053e318ab2c300240f4d55c76ab7fb +9354,9a5aab2b556324c242557f6cb7d3a1b7 +9355,5b6e61a66b6eeab0d486b1c2be75434e +9356,dfd83aae13d4e1c74c86d49d717bfe3d +9357,48d3be8b7201e7485fe59366cc72b96a +9358,6f3069623671580ba7fbd478fa782ef3 +9359,0f9b5ac0d36966b8ba5ccd19c2a6cda1 +9360,789e67c313e67301f18ae6dccd194320 +9361,a38e4a36984fe9a058380e6728a65749 +9362,92d5ed06e41a34fb50deaad7dced3174 +9363,6bad5c9785642bb04280e89b11a63440 +9364,2f5d69728edeeb5e448008e8448e074c +9365,ce1adad1fd4a5627e5f8b9635c2a14ff +9366,92a9c69b1d2fccc61fb2f9728470d05e +9367,252c40affd41441e1b5ff58d7555a57d +9368,84fa017b0c6fc457857faf714cdf224a +9369,683d5cb7b524dc07b11883a78ae7e57d +9370,818859c6048459b839674d47d7a8e42c +9371,e1229d05d12ba1d78c1728456290829d +9372,d131a8ede8f9b51bb7044d6a24f0e787 +9373,068dd8894c1523a31511af81f9193bc0 +9374,93aab8f001c7cb724904fbcebe6cc59e +9375,16b8f8bd6d9ab2ee4392408e4d8b1006 +9376,f2967e0cfe1736ba8dbdafe0c8ecb0bd +9377,ba269b4bde0a63bff6540b02dcf9a28c +9378,96e309298766cb8d8665e3ca847b642a +9379,76ca3fcc10486261470789efd5fd454d +9380,ea51c3cbde4a9ade9a77779519dc65d8 +9381,83ffbe48996eb7722b009eedc709b543 +9382,4a30229b12c5b853c36cfd276a7c5781 +9383,92188be6f09ff19c6dfcf2e33824fb71 +9384,6fa120406f5902ec0d084d9e702e7fa4 +9385,9161681d4d976763ba1b3899901303fa +9386,ca76179cd98441203f86168d22ab11fe +9387,5fa11e909669d802735c5e76ca134f50 +9388,d1aa43b4fdcc620073d1a25f4fde385c +9389,8fbf3cc653179e509ee7e248b2e4af65 +9390,622575dd56eaa87805ce3443b3a4ea75 +9391,67360adfa8efe6a4d1bed24427454d8c +9392,edebeb544080c2ed12af7ad7cbaec07d +9393,81f73a354848aa6d84f1b6579b4f5349 +9394,06af0aa4e8f398020dea80850890c1c9 +9395,8ecfa44771b6ef003f9e42adab5a6b5a +9396,b41eb52f7f071ee46b9b65239bbc16ba +9397,3dc836a0bacc448bfae988a94c35eb93 +9398,e2c980d0b89bf19e849dd9b74c38d7aa +9399,5ab1e84f2b185a0f332c01df2f3c0e08 +9400,c2d06403d2bab262d402838883d3cad9 +9401,eef4c0ea5243ec51c44a0a5e5e6f3b89 +9402,915cfe59317c73d0db8400f7ab5ec673 +9403,80dba5af557c1b46f9015b6fe44a94e8 +9404,29a07ec49c6a17fef9ddb2d0a08b5acf +9405,e70faa77d92baab5ad3f3a6f59f8d7a9 +9406,a9bf5c73cd09ac9a49f39fa348b5da30 +9407,3fa187d9ad420031f0c8e9d0537bc047 +9408,7960a08632890bad3801a8c958efe3bb +9409,aaa1e25ff1bf270edca5aced670e0f02 +9410,939946d41fe3f468d1301cb74ba89897 +9411,9c54a541f3687ca7a83f606ba01263ad +9412,59ff649d6cb3181b82aa1ff23afce69a +9413,a96bb74c0cc925c0aaeec0347feff746 +9414,bee4d40d46883f9413666f6138b68f4a +9415,d02bc69662e888d56e76cb89c48c4423 +9416,621a587e99692d4e8363ff028e82e6e0 +9417,113d6a3bcb8e915831b7f3f129a9ee13 +9418,1fca3ecbc47c59224479dc0673a40505 +9419,ab6d7a892196b4604b76745e904c01d9 +9420,07f9b1bd595f30a049cb633d570d829f +9421,4f12efe090aa722af86e50ff18a6bd5b +9422,2897ac8c00207ea913240f307cabc9dc +9423,713b6a493de5a68f849d73c10fcee737 +9424,a19469cad626af425182d63dfa4a0156 +9425,9b53002c09172387e3092b2a16ba98f3 +9426,83e68b928a8da0ff58af33b90ab51256 +9427,c01d7411d9f459b16caec1bf8ebe05c8 +9428,c238fb86c7c195121c662c1cfa74cb15 +9429,220948ec4792c4f68f74da9bb316f35f +9430,1976ad6533ecbd4308631f8ae1fceed1 +9431,fb3ae74943f5430105643448d3deeb2b +9432,773ddf4141d574efa54712659d5738a6 +9433,00fee4f1e06d2a8957c3ad275c5ba16e +9434,29d27ec98b140808747cd863a026ee03 +9435,2ead8067f59ea8a96a3b6c87f1c928e4 +9436,0e32c89e1470a3e7f34b23041f30380f +9437,3b63447a8fdd1fd4bcbe5502d9b45cc0 +9438,6a7ac3bb52c7bcbfc13ee97d30261ab8 +9439,c82e7d246686556ea446927f7d71ea24 +9440,92c8d6e53fc4aac7dcbd1a75ddcf3cf2 +9441,a82af4f3944dafe2fa77a3adf7f38c13 +9442,12b204e43cd1b5f1dfe2f30bba3f2625 +9443,6a60b199c151fcc7203216981a129766 +9444,7ab0d389d9f6fbb9e7718277e1654f07 +9445,5824c003b00bf3e20290b28f9b417210 +9446,206c2cfaeb094c4c330f3b7fae16dbf7 +9447,5657ee646653d703d24afaf84c123d81 +9448,2c9dd29a4be253f4c102404f69019a2b +9449,b5ec4177eed7c430b6e3f3267f916f49 +9450,0c8e573378e411bc9bdb5cf228275f54 +9451,e3c0dd5781d3e552a6c89031b90b3665 +9452,640ce8de6dc3482b7292bc2ab6cd55d0 +9453,16b2f61d9a959bae0367764fde55b45f +9454,503949e4cd532b3449ffa227db32d800 +9455,6a4941e7db973335b88af07143511338 +9456,7176fce9b840fbd83632f7af899829f3 +9457,fcadf2487a40a400a7cf5d977b9a9d81 +9458,c3b0f6ec05e6c2f03c008f0ed9fb7874 +9459,667e600492969ad4e75b34df3d30b565 +9460,53d8480d193f6b72deb7f823bedc8c33 +9461,e82e5fbb446599b409f0fc19636737ec +9462,5fcd7fe6726df8d92ee41a5295c0157b +9463,0af9ebd0454c3832cd6da5026a1de944 +9464,ce58c32d751096dcab408e107e7f057e +9465,db2c65e06d41619bb7ba181897ae26df +9466,2a91f1360b2234f792247a0958a1f14d +9467,99958a7b26f568616b94c0678aef507a +9468,da694e2065e4e2197809a31821a1f68c +9469,80fb4fc98de7015929de34cbf082d5bf +9470,f82fdac734bbea27ce4f773d0d2d3829 +9471,23543a3c87767fe7198c5ae247340c6f +9472,a977496acc3f076d706be029321994e0 +9473,242bdee234ac055652e065b9a709ea0b +9474,dc79b0bfc90f9f6f9b44afd0e0ef028a +9475,f0b3b34ff0e0d7abb36e3735192aa610 +9476,d8c81a3a6c3049e04701c6ae9f60691e +9477,75a16c8f05f7c44207af1c64dbba1422 +9478,23d47519980d45f8f647a1192511c9d9 +9479,18aac0686a579ffdbffbd3ef0d88d85d +9480,fe65a53ac23defb99fb257844b4d2772 +9481,9e11c473841d157810aca731c4d16e5d +9482,ec6b2dc1f2c90d2bedd395b2417cd60a +9483,f26557c847f2408e7b5ce182290ecdd4 +9484,f265ab06b8050919e4327f63dca912e5 +9485,45bdecd5693b722452ef85bb9d5de6d6 +9486,9d60880f7c063ff92da91ba9f648234d +9487,98c65fa5e76440b0f692071a353e6279 +9488,9df8d16c677845589d206124acea6b1b +9489,449ab12672853b941ef0b921f9f9306a +9490,26dcc33f99fd610506e07b37f3c1f522 +9491,d8c8c817e4a719f1749616b74ab45e74 +9492,bbfa154181f04047e229e22ebc11ee3f +9493,ab502b70e42e7d091ba9afe6175c4602 +9494,71d6a3ee9f35023cfa792ad4170b81bc +9495,cc0300ced44ea69f767f72c1bd640f9a +9496,39b64509aa1aa793871f9bb4579622db +9497,c17ae102b5a2fbf6ba46cb248e0f3c24 +9498,967b02115ee134d8ad9c8ce02d18d773 +9499,135777abf9fbada20f1b993280f057ed +9500,a69f5d0b018f33ac0b786910cd91a49e +9501,16a16f5669389df7dee780cb6a1af714 +9502,a5a03c519d6bbbb2c25307496a2029df +9503,5fefc2f1b96a213a45e2518f0d2a6032 +9504,8d72dfd9568ff2a64d4d5682d144647f +9505,07924701f38668986532412f3fcd9396 +9506,857c0372829e1ac28fe774dd5ccdf2fa +9507,96676775a94557cc53b3e43231e6fc17 +9508,ec306ac3e4b86cb444a37a7e6b5d00b1 +9509,f45d75e9e9e12d253a1301ca342da0d7 +9510,b2a8ac242fc44a4c6d5873bc64275fcf +9511,94e2d03ba4b8f237b7896407663312de +9512,dd4102c6247bb213a8641a15dba48ff3 +9513,9fbeff52f9a0bb6ed4d29ddc9379621a +9514,997b7153bfdd747f9d4f9a67bf4c5108 +9515,f5dd2f20d1b78dd6ffb78c77861e51b7 +9516,c1792d185dc28f2398fda3961ff67d1c +9517,76bdf1b4731387e14334efc280cdf911 +9518,250e4a8700b020e4bdb9c9197f1022dd +9519,e93211655e2cfcda50d0b0f5ceda6e5d +9520,7118dccea091ddbca2c00f64d9526a72 +9521,15e3a2c473d7236985478820fc4793f3 +9522,0a7bb630ff4390a3885f4174608a7be1 +9523,d0686fdd9a52e977feff182abdd92d9f +9524,0c4a28796626cc27bb107353fd6a15d1 +9525,8ad81a022c5a6b8f700968ce666937cd +9526,99abf892668099e15ba8c24e76ce8068 +9527,9f86357af589f671da3019cad54eba67 +9528,7b7e15c66cc51e590a2feed594e0918d +9529,f0b468174eb8ac2afdefc2507d953519 +9530,2cf157c95893acc3f3ae0ce8778ec549 +9531,f04ca068543f57ff027c553a78c97568 +9532,19fc7c9b022ee6a1436401a2502ec3e8 +9533,cd96c1baa4f7d18075f6df5223bd736b +9534,89e83cb0e2bd4d0d31fd1c8e6cacea44 +9535,16546b24b2893c717ef170ab834116ba +9536,d4275ae9bcd6ef1aa5512cee2ad4f12b +9537,1b845860d962a53468b0de42f759b6ba +9538,568b1ce5517fd17d6629fa5154b144b0 +9539,71aaf9e8618f88c6bc968fe55c3ed25f +9540,9f0a639e0ac0bcdc580133ac9a11c54f +9541,d9ce0383633233dcffd53858f4e6e447 +9542,18862d264e05c9097dad5720c766af25 +9543,296c65df6264c252a75c17b87aa727d4 +9544,69831889edb6348752be71e59461368f +9545,f7503cd48b7861ccc492c414afac2427 +9546,45e147a04c8ec156b414c31eac9872a5 +9547,2e716de61f5434a191aad2f9d6f70fc9 +9548,853967ef2541fb2082ba1bb2df17c7d4 +9549,41139418dec86727cb30fb8f25143d10 +9550,7ddb7488d8b77eeade59f9bcaacd9ced +9551,b00f4c6100e1a5e3a1afb99895b6893f +9552,30f63a5869b25b99fc3baed5495aaef9 +9553,6c8e89a0b27d20c84085c4f6c85b342d +9554,00b3c728849f67194bf4ff7cf7c50852 +9555,a126f47cb5d4a04b7a7b0dd6ca802f34 +9556,314abd17a11996fd1e6b09ee652c3ac9 +9557,ac6c98bad158a892610386094abae795 +9558,f45ed3e9ed7b5a612f28dc2dcfcb87eb +9559,f921a20a22969e98525decb27c9bb7b1 +9560,a3c1ce3c62d27f0bf6ba18254a84270e +9561,e789cd6b6ea883be8030bea601f1e513 +9562,7141a8dcfccdeb0c35d8d3b2416921b5 +9563,80ace61824d21763b4adfbfc958e961a +9564,76acc8fe19b25ffc5fc8bd077a126d1b +9565,ac7eea66b8ecf7c587c461ea003f337b +9566,59fb7218bc161a5d2712c3ad5ee94cdc +9567,942afdcac3a5e8ef10242dbd55b35d89 +9568,152664dee97e00510345ffb3a270d1d8 +9569,dd26d54ec35d4734092dc73bf8e4b06b +9570,a26cb1d33304c6f1ccc87326b87d654c +9571,11f9735ed008159b5b9d16a6c29f7f80 +9572,51a0489285d3db9df462f9757df551f5 +9573,89e3bae247ebab7f83a1d042f5c80220 +9574,5d721349a1d884f263a535ae19c2f5ad +9575,1bce0f4be1f543417dc8b59bf93138a2 +9576,4325726bbdc951b93c956ed98a54d6cc +9577,2aa2c439c5850ac5feeff214a90a8e9b +9578,ab059cd88a323478a861ad7fb8b44a62 +9579,3366984509ebe32bb8236952b398b22b +9580,d9c3890d3173b1904562780890bed8ed +9581,fdef5aad9425b30974a6342c7d2ca3a7 +9582,b0033ee97c0d4374b5e83d3535dbf7c4 +9583,2087a6c9975f6648c0805158da110784 +9584,a6b7a465bb7344edef6a1d3a7ae8d3cb +9585,9e3c688436ac8eae3bc42f5dffc4be51 +9586,7593bec05feb1848f19bdc83eaca034e +9587,1bede616790efd690a3e5c8e94718f59 +9588,bb9a3e4c310e87911fd38434529fec0c +9589,e1cb8245bf4eb979064e93913b5cf80b +9590,ab5f17f15903c68c241e77a0a351c675 +9591,0f52f9b06d77c18777770c02af8282fb +9592,d2ba4454c568aa838d577bf351779197 +9593,9103fb61cff36c637322d786914914cc +9594,e01d7421b8704634f3bfd49ae6c853aa +9595,6596e27e2cabec7c3cec88a57ea00b7d +9596,61aa8690741d39736a7829852ded9ff9 +9597,a0755c39c5dcb5ae839ad024b85ff03b +9598,6ba7420be7d3faff29a66acbedf89cb5 +9599,ccdeaa0be32fb61f779c5b83cdfcc113 +9600,a75463718797d42e9f8697fa0d92ce1b +9601,44ab77c44451c4ab706c9da9e5a6e308 +9602,53e0f82c743049cd10f61b5db8117e67 +9603,58dd912a57cc89b579fdf9bc13c7b4f6 +9604,370e5c4bf4eb49071223b4bde6488267 +9605,ac801ca81e62ce16b887033fd119ebc3 +9606,23f6e56b0d35a5eeffd2bad2cb67bc76 +9607,fd8a6dd2c3b265bee87ec3ea11359e94 +9608,1b24a4147f873e7aa70f2292a7cac4ae +9609,7aa829080fad5076c17aa6cb1a4bfad4 +9610,da240a067f1471dbbb92e754be624803 +9611,046396e60dd1e28ba4687ef86d3dd179 +9612,6fabc7a9edd8eeb10e2027a0f292e5b4 +9613,37276e12d38e289df495eba74a8f2a2e +9614,c7b629acd8d48ccc71a493f84608e74a +9615,995d532508b5b8422293518c118b6940 +9616,334317a8b8dbfbeba43365fcfa4ba482 +9617,fc042777f9e05befce23f7857f1b7062 +9618,6c406f77093e5dafa8b55cd47ef6793b +9619,bcb780d9ff798326782d6dcfcb300537 +9620,0e24ecc10481730595dba7d4da27d8c0 +9621,546eb7830a12f18310efdfbbd5a06221 +9622,a0c46410df55de0ad6a72487a3a5ac3b +9623,7462a73f2904e5c4efcff55b671e5030 +9624,ca4d2ae022ede391be7ca86d78ecc2eb +9625,79417cb0b4d0e08535df28b55dfe8545 +9626,6a2954c28843214211c19d77e66d0a0b +9627,eda2d427216481183d2d973e189a4342 +9628,0b7beb95cf6c7f52c53ef6ef112d5476 +9629,0e8f9129a3cc4c710dbaeaff65b0d7e1 +9630,9b5b7c179d1cda92496e991a9e9d3252 +9631,7d7d7c84f504c94e5b7a8be1970af6ff +9632,0b3fb42c962388f33dadf30929b2dea3 +9633,1efb1d90fb89ecbf0e1098fdde02e5bd +9634,7b66c663446b2ad739b55135690f506f +9635,4065ca293e5a6190f0225c0acd336b84 +9636,028bd945e837188ccba216fd7c055641 +9637,af587f9343555a4beecfb24f8501aa0a +9638,3f2a4f4be9965965952c91f25111f6cc +9639,3b3f4f31584cec56fff0788cee784739 +9640,0d4c6f296fb3ee4db02cd9b6bd8cc9b7 +9641,e076d17d2f849fb3068f11c0893590ff +9642,7f1f70d6bcfa22804cead936c729ba43 +9643,5e71501e010521f8fcd33dca03925b5b +9644,ee88fdf57e2e9f05f54adf9d0dfda1be +9645,8375f23445476df5b49d89d600c28367 +9646,c7e56221fd6507b8beb49af0090c626d +9647,906cb703eaf54dc9cfc1f739ad2c2142 +9648,d89bf3fd7133ad65bcd358c84020777e +9649,eb392e0e44eee2c607a69d31b9b4df8b +9650,595d66065a4ba95292a461f53a3aafe8 +9651,714074af062e6c9183fd26be30215bf0 +9652,17540426ac509d8ab7b18b44794991d4 +9653,694130afb09c1b5ae048063d86acbe6e +9654,001e1f0bd2331318c654dd8ed9cbd1f2 +9655,73b6104323f09376b45c4b50615501d5 +9656,cbddc103584cc6530b8f83aab44041bc +9657,cb055300946c766f01bee9cabf4c461a +9658,974d6380ba37008671cc18453734bb14 +9659,fbd14bda1e7e80fa984b69b4bfdebf9b +9660,3de3879bd04d98f42dcfc04fe131c88a +9661,41a65e8b625ee8ab1dddec5b85744e6a +9662,a230d08b7c4a0eac9d95549c26dc5352 +9663,93fb3122c4cf23aac7f8d97348feb160 +9664,05b3d31834db423901e75ef488920f34 +9665,d4f267f27be1cc3bf0190af7d545157f +9666,1031c085ae67b779bc533f331410ca67 +9667,1c37b89a73a6f3ef39e9dd4dc17f9f10 +9668,ef47223d8652a4ef61ab9c2c8f0edc28 +9669,aa3642f9b35e27b60b6f563fdc8493d4 +9670,90c935a2bb7cffbc9d1a0ea4398e6e9b +9671,822ee4fc4971ef95e319a55bd40091d8 +9672,a7474232e1fd7487d7d7c735cfb1ecbd +9673,dfb8827d237cf2d4207857b3913ae1dc +9674,e36aa3b993e67a00a5be8139efe2570b +9675,58b0774ce1f92d0a0999ea465d1898f7 +9676,c09c3132f67d54e87f3db2f39ff52935 +9677,c449d810243f05f60704d74f2a0e8079 +9678,bc4625b34530e472366364e66cc6029d +9679,843bc2b4f6bce1fb77029783be17e89f +9680,15dc2e9f505a254165c81c8e18b5d155 +9681,f155cfdf5410887f03ed7059ce29c8e0 +9682,b889a17e9c224247b033747f9c6df2f6 +9683,a12dfdd26eee1ebc1db4a4ca1c8b6626 +9684,bc2f19df545b054554ff4900179c9218 +9685,c77f961de8577319d847821977d94671 +9686,6c5381f7f66c0a144eac81fb33df6714 +9687,639c9355aac7d9a49ae0b0ffa9f71d3a +9688,058cf1aa3eb5c86e1730eb29ac251552 +9689,c366cf9c71b206ca26dae150e1df1c42 +9690,ebc954e7272810a9916c5a618b5f6464 +9691,eb4d838d942b4ecf216deb7019d11dda +9692,bc084323db469dc668c6c7f0837d48fd +9693,dc349508e432cd1f75864ad85874dfd0 +9694,225cdf681cf17e7032e56915839ab3c2 +9695,f9918634f53a623cffeb1a6bc80910c7 +9696,ca5b69b877356a2ae99497ab93e3f0ab +9697,9b73ca74ffbb954845d8ce13ccaab383 +9698,33660038975ffdb32e9073ccea1c849f +9699,5708f5ba1690e375a0676e78e32008ae +9700,27c513fb8db10db8d6ddea96eb0c0bf8 +9701,d57a30855ebe3867dce6357b0213e82f +9702,563917cf92984154ead8885b9cfb8834 +9703,cc6681994a48c0cb4300f89636002e5f +9704,2ed5e9762e0bacfbaf463648605572c8 +9705,8689501a53375532aec0d33d2a5c4de8 +9706,d0f9fc7aa7ef5e60f32576b7559650b0 +9707,1d3e4f63fdbe483b6e2dd97e87392db8 +9708,274aeeacb17d3e2a17c930234061be25 +9709,023764a3bb6ec529a65b654b2198198f +9710,debc20b2e141818bc8fff3b26b4e9f89 +9711,d8da2de5e8273f4eb752d4be1ab6849b +9712,365d8580f40e8e8c31f567fbb981a536 +9713,84658b917605afe2b5aa3ee6a3e6aae8 +9714,8671f487118d7c4e5207128a27acd3d9 +9715,2b3a03e663739947ab79fa96f0efd3ab +9716,a3b9f0e4c1eb882afa3313b512ff2e4d +9717,4aa9fcdb3f8d34e27685a87ee7586309 +9718,ae8a571f01a8f753c61d25e39dd4acef +9719,8b6de82d4412f162c6b3cf304f89aa23 +9720,eea110dde464e8b2cda331e5833a72a8 +9721,342c56dad496e4bae321e8bc9a87b3d5 +9722,93e31f25c601fb477bd10444b8f4952f +9723,1516b2f64c3cf87a01644eb9249a813d +9724,80e9d3c716d5fbeeb585d8dd7bcf622d +9725,4b7452ce8f01a88429fdb1560d4ab392 +9726,339a9bf0e4a98feae0014214b003370e +9727,d401bdce5a2b47bb3f75c189921da731 +9728,77495409f9dbf9bb53b95448e67e2696 +9729,ef230a1d3e2f0fe3a9cbfb60108d8757 +9730,76d54e8e56b41aee90504a9363761e10 +9731,1bd39953ebc4171b4c53926ec6d5dc7d +9732,049932603537a733b6272d121b137e90 +9733,a31f5bb26f066fd20e797cf6639eadfc +9734,19b3feb79ecc05e5df1ce7bcf141e1f1 +9735,985444f73a94face2adc49d3067a668f +9736,ee235d2ba9dd1f428e281c4ad1c68f0c +9737,6eeb5dce931f79fb80928296759faa1a +9738,55f4e92d8bfd8fcfeb83c3c66b482f04 +9739,88dbb43c1a38882ed4161f74d76764ae +9740,e748779ec0e19de6235f855ea3f11695 +9741,fe9a8d0b10abaaf0bc95aa56d4f9e1c9 +9742,d448c0d48ae5703a0cfc9ab640085727 +9743,941031bf5b5f69c9980687211373ad4a +9744,725839ae1c078cdb7ef08946a829be74 +9745,ccc8a6daff2e38fe3813411fa5b888f8 +9746,351e4b18a8d5af0a7877a4f7f3f4de7e +9747,9c3230bda130044149669f724e820aeb +9748,98bf53154740dd445dafb59fadaec7af +9749,c3e9b014e005b6c5690446142285baed +9750,df2ff9405fc7b7ee217541e1c22083d8 +9751,55187e01504d94470fc99b00c1bfee09 +9752,4c80c818b7f1454cae8e4c6a5b7b4ba7 +9753,d87dc8175fa85f3308458864beb0360c +9754,c03c721f5ef516d4d4ccf136f0f89c6b +9755,83778b2b1e712a5ff75c23551057ef22 +9756,b454dda561742ba023cc69df40d0ebb1 +9757,ee743ae53622284f03ddf67ea8ff59a2 +9758,bf0eee75e7c6920be93fd3ecd6ddb38c +9759,526a78bf171ea82554bf06a1739b9815 +9760,6eab928a030a446e817949d458edb4ac +9761,c85c83117a77a0f8e377fae1f6e0e287 +9762,0e8d1a93cf144680981b038d120eaeef +9763,40d8da93a8b15c1889e63bdcf4356bc5 +9764,d70aca4f6a5cb6a5c0e3af6cb3651f70 +9765,124bdc50b9ecf7f46b4e9426577c4124 +9766,826f1214a148f3ab342e80f6eae94aaa +9767,e456b94a36875bce9bf39e9fd94856c0 +9768,2af4a4f1efaef47edabe9a23e99ace63 +9769,604e83a70dbb275809748c92e7dadf66 +9770,7a6ab0e21bddaafd2afd5af047854e22 +9771,abe43fd12651667a636c488e8b4d2006 +9772,f621f89203d0dcd5ef95b57c868aa8e6 +9773,51f18ee82598fe28b9bd6d8baecb5d2e +9774,b7d65a12b63ad106029357014339bf86 +9775,e619d6466db4d45f96f247e2472196a8 +9776,8b294899713236bece22b271dd7e0ff6 +9777,324ce95ba76bb0b1c30eaf4bcf9c8d40 +9778,f845cb46220fb3b2fcb0d68f372b6799 +9779,8cc077cc57b9033f86ea93bbef592e98 +9780,3f73c0aaf369ea40f11d9c083291a773 +9781,85c03b11aa2fa9785976e794ea1300f5 +9782,0d3781fff900ef750312b6cfc15c1464 +9783,a7536efcfd3559cd097ac4607747fd61 +9784,6f649a9c87d0f03cbeb7eb20f29f1d0e +9785,dbcdef3c1eb1cc2505c145f4270d5ee6 +9786,f00c8f604b0fac98da38abdea7ae6068 +9787,03803207bae2cb5008c4fb1cff95e4f1 +9788,aba7e093d9626c3f1d2e669bf5603f96 +9789,af669ddf2e0fbfdad7d313c0086ac01f +9790,4b70378179c37a960c8efabb29cbe7a6 +9791,9a0fd6dae3f0bbcc38641d67eb783c5e +9792,218321811e53b48ff91ab2fdaf123692 +9793,f03b1f08ecc9d441df92d8f25fea932a +9794,c799da91b138230e0a94f9e772d102dd +9795,41bb12c280d1295eccf615bce1478298 +9796,c1b9deaae33be7b012ae6c5e7f6b179c +9797,5a5058188337afeca87d7c37ec2d1f03 +9798,d14311ffebf13648227a1ec1a71d4ada +9799,2583b4b7726989beb6422f9ac2214ec9 +9800,b102ff2621474cb10fa2d3a562b40cfc +9801,5a52c014f7f15542436dc0cf396cef17 +9802,04deadd60d417abbb87f49cbb2522c60 +9803,95337b58f3c89d9d4f1022cbddcf3b6f +9804,9a6c60bde8c038c25e49965f9919ada1 +9805,9e115be482491d10f72f0f9529411745 +9806,cdc2c921ef04ee5d2f0326954fe0101d +9807,74cac864fab660e3596cbcfb53461f4d +9808,38a8c70e212c69e99401b249f8c62501 +9809,cf7bfc4ebb7e8685ca81f56a24fed7fb +9810,b2694599d9672296acff5bce093431cb +9811,cef72f87eff3a046c755b6bf1e246273 +9812,481af02d5f2ac0d73c2f17eda39579c1 +9813,06da0165db17c3bfcf74f25543226c0e +9814,5e2850b765f7e80704f1271a20d6365f +9815,347ad05c97dc6bf9617a00b9ebdefd1d +9816,f63b24c6f384568ca4fbd35c5ce913f2 +9817,6043e7f644f1b86b6d16138e11762735 +9818,85f28a226040f934b024a6c88e1dc12b +9819,afb5034ff877753f577ddfb8599dbf36 +9820,2c5273ae6dad9c881e9beed0b42f7b67 +9821,4c6d092a700295101f0f642fada471e8 +9822,3a67b2eaa31f72525eb0ba084804d57c +9823,39cb17bdcc649be4be641f4861531b09 +9824,fcf7d223cd9e57e4e9a65d2cf743aa04 +9825,a2096e36e07edc407ae985f3a36f35eb +9826,0c42dbf872e9623f5c3054a05cf07670 +9827,02624f8cf65d4ad2fdb8085f40f65bb7 +9828,a4c6b77a8fa1a04ffeb74324d570f50d +9829,0ef3bf64c2877d603d17fa04aa570cbd +9830,d0efe97e1216b7e6476b59a6c2ef9387 +9831,6673b293d60a5f9d7d9cd815fe1290de +9832,5ff0525ce45277b8c3da02291d1135fb +9833,4c72d30a566209b9cd933dc032600788 +9834,a355dbff5a841d9b386183a9d4364ddb +9835,45d5309a6b9a39c6b30f83ca2630e74b +9836,220c3ff44836cef241913db74210e91b +9837,fdc436c5d3cc03082f9648f2b424dddb +9838,e4f7dc3fd15757e211680251eda1b016 +9839,d70473a22e623a6e469c918732a1382e +9840,7f0fd352c89251c90aa889b15add9ae7 +9841,7e43f6a0e81c12c1380a618526ce1d19 +9842,82dd44bbc1c1d05f980b73f725a43898 +9843,e0336c8dce297b32afe3f8a543a37718 +9844,6eafd78bd24a9407f5e1b4a1f19109ee +9845,a84a6ef0d137ad8cb8626710830ceb9c +9846,575fb6a0eac28b94e204915d69d33acf +9847,9b0bdaddca30ae16174ce50cbe1b086a +9848,a115afa5624794b53f73de7ab4776b52 +9849,f0a786b76890b6267c7ba0bb82d172d2 +9850,3b807bea8863bdfe777aabc0d2508fcb +9851,43aebca642237d1363897f07c0561b50 +9852,9ba6e29d9c597f7ba2fcfb332c44091d +9853,685a08f3ac8cb5906bd696c98a8d362f +9854,389fcdf6c687cb3f52cd17effd39f0ba +9855,3af844170eabfd1dc4a7a9e2ac97ff8b +9856,c765512327922d48da8b65e247cdb75a +9857,75bac6e9a8501869bb92a1f3610caaa8 +9858,3e85fc4ef664d6303114e54fcfad8b0d +9859,00f3c10320eeec60596b3f8299d413b1 +9860,bf04127eeff17757bab6dfa2984380b7 +9861,606b0b53536937f916530143ce8275d4 +9862,8ec7dcea7a04aac7250ac10dd9b3ead5 +9863,13fc339eeb82baf1febe56f30883ebf5 +9864,dd5e057322e60ab3b9ff472d10448618 +9865,74dec841343650f57667b6bd7d85de80 +9866,0acbcef4be512c61c92708c5b70bda28 +9867,76c7f53bb9c99d1bef8fd3e6e0aaa442 +9868,5c4e618b13214a9ebc9dd0697498ee9f +9869,f54f2d206cdf723ce0a8fbd449ad11ba +9870,947c40d360d4bd5ec5e9cf38a21dd71e +9871,266c6b616e92eb2d960f1003096a1896 +9872,52af46eb40850be2a0ddb84012deabf6 +9873,6c63fc1fec2c491342e11bf83a2f359a +9874,f5eb8e5d34e230215cf2ed29cf57c63c +9875,f7c549401f25361e1aa3f43b48df7c8b +9876,99bf3376590caa590836713e1decfb46 +9877,37e8499abf52330af86328cdc6272d9a +9878,69d7438ae0a423ec8a3c684f312c3c51 +9879,c4054fff0172533360cd017779502fb9 +9880,97a6d1796120dba9e99a74a4510d3363 +9881,240a30bc86550c1c2607c1a900ecb8f9 +9882,92cf2d018e2aef27b38eb8181882559d +9883,c12c162d705b868c61acebf20b872fd3 +9884,224876660e1081888f15d6c43e3af61d +9885,79ad72493d8689fd6ae8570f7c048473 +9886,33b8f3f0005b2ab2b1ac312876a930d3 +9887,18f69eaf5896d4b4272457ed5939bd92 +9888,27cf94082c983aa60c626d977ea59750 +9889,42f2a585100d6f80700351ea4b23bc04 +9890,b71e281544a261c6520062046675271f +9891,360accfdb949e8acfd0f7b95195c7a70 +9892,59d0968f61e0887620e326e59674fa71 +9893,f09979f91918890a386f3f1192a4422e +9894,1cf48fc4ba1ca87207f8a4c933946d9f +9895,5514f49f97802f16a1ad8172ddc23444 +9896,4f88ab6e15be38d42160c099438ed5d8 +9897,7364d7d8f168d4d2a45b88d5e0dd934e +9898,f1036a2cd77416991c3c5e33076d7b42 +9899,bfcf928fe174118c002067253f2b52a8 +9900,61e354baff2d4047f1de011c5cb164f4 +9901,f84545d06a2535c5c5743673a676204f +9902,7a4824f97ef35e9a734ce9486fa6fd83 +9903,db44330b502af4d32d40e3ae7abb976a +9904,339e0bf42beddfb91150237f96fdbc8f +9905,7b1a7907a72d1458fc036fcebd633a63 +9906,3de3b36af7ef9ae6738c162c2275af9d +9907,3d69f55de0b9a7df0b86e842efb02338 +9908,0e3cdf739bbc9a9a77b2f325eb292ae1 +9909,249a8c221641b496214838f6f7fd018c +9910,fb2f10bd1082471cde4428b41d2bfd2b +9911,54d5ac7e26efdb4113cf4b62263d1eff +9912,67fb3b6c804528908b032e5889926e87 +9913,3662d832808dc1d45d8d3e4142cb3d87 +9914,3f7baa9e234a9640d984c9b02b903982 +9915,44110a8117b9ef927e0075a5ab3de891 +9916,0878d121b8e3f23eb556fc00a950a721 +9917,425e219fa2b9cbf360624274d82dc456 +9918,ab2301166eae35d9f3fe880a4b61b0d5 +9919,13de8c5e2c9fc5e29c1695b597a4e9b4 +9920,16a0215cf2ec42527da306d7f399eed9 +9921,1b70b687513025a8d539b301f5f64d26 +9922,5ead4948fe4c7329e93f8e44a4ee0f3b +9923,6345217218127067cf2aaa1691afd45c +9924,8e250e72d8d71e79eaa215d58b8864b1 +9925,1ce9ff3ab32b1f90b6d564196f5e11d9 +9926,24e1eaa761cf7be2ac3931990c9bb907 +9927,97c06c59934c893e9bfadead6385d017 +9928,662716edc4373a7e8447904e76500fe6 +9929,79c9019554434c295d97637c970f2fd7 +9930,76f1b46fd723b33d2302259a3fd83f41 +9931,a21aefc3329e125b03e476c388d6a933 +9932,59a7d8775e755e2f3dd78b577d4d62f7 +9933,35ba843b749e5e8b579e02f4cd5cede7 +9934,30d959892a23487b2d13892c2e5d7527 +9935,90e8309e6cf26cbca986457025c2ff99 +9936,0ab5a894b3cb60b038532dfd3c3fceca +9937,5cd0e3338ce4613b2f7698fa7cce68cf +9938,33da311bfcd52e1130bf8819c0a87322 +9939,c39b36b49f7d8533cb7358feec46d737 +9940,10b545677c9037eb0390b92bb1905300 +9941,69815f268b52e3789fa5d1ce63e7905b +9942,5cdc422536c1ede5ef0e6e7f5d21ce33 +9943,b83d42eda6e156f802aff78ec5493707 +9944,32d27fa67d476bd630e23774cd8626ee +9945,50508c69e6c5e25b5f3b30bae47461a9 +9946,fca37fdd1e4dcf7efad278dabf3eee18 +9947,5cc3ed6d776aea86f74384631aeb9558 +9948,a048e03a7fb2aa303e007320aaf22239 +9949,21fdff6347aa545563c8e782756f4478 +9950,cb8d66babbdeed42ebf3057d39110f2a +9951,a910f8730f15ed51978ff84e3417e18b +9952,009a0cace0ddd7cef65d086fe3c8025d +9953,b8912b3d9af1c6ed76bc5595b8e26283 +9954,f5c28af331b1e6c96d22af96447c5a0d +9955,c0e54f40e3b7c44f959b1d53b1a5149a +9956,00d826a878bdd4c8f9de6760b430a961 +9957,22d2251ddd0d1ab7ca32259a8a426dbd +9958,e63ad0e44c7414601e8d895611ea0783 +9959,581de33654a3d1eed42f8b8cf1ed5cf5 +9960,846faab1108f8671cff945e52393f393 +9961,835c912783d70ab11fce2b06d203a909 +9962,b8d8e31595eb6bbbb0c5ee2247747511 +9963,0a2c2478b71fe500bb5d11d79ef36b17 +9964,392807ed88c0378abcfa4162bb032ac6 +9965,b0328c589c85a6d61c353f2a1ccea9c3 +9966,6ae06271120c941c6405e5a58fddb952 +9967,5e6a42f51222490d1c9815ff42ebb533 +9968,a59318288330aa2db8190d8ae2b9bbff +9969,0ea8522ca0756744bb26475e97506d10 +9970,6e3d39a151f64fb4314f919ff7c5b727 +9971,d0c32fe3643730d27289322ead732744 +9972,1ada78a98c2ec1e6d1baeba48204ce1d +9973,fe3b7671c1386f92e0424e887fb879a1 +9974,af1af7aa3db84e3948287c741600d078 +9975,75a8f3120136debf2f81c447bab1efc9 +9976,5fffcadc0350febeccdccc00f9a07dfe +9977,7dc1a5324d755fed659c01156047d276 +9978,b96752be66c2cc8dc4bfed26022c8f3b +9979,2c398a4da0217a065e421e795ee42e6d +9980,e03fda9406385653c044d18bdb31b932 +9981,f01c35a299c40e531636f8ad25b649c4 +9982,268e01fed8eb5f8a903500123b659543 +9983,87bc33f804486414243cc49e7cde271e +9984,1f8f46ea97402d82ffc3ad6ebb175f81 +9985,8f6e589bca5f27d36cd92a32804685b9 +9986,fe85f1277be6de65a0e28bc69085fc31 +9987,bba1b7922c5729bf84937a2b018d82e7 +9988,16bb081e7aacc1093d850c14b3a31161 +9989,6ab9c934a1dc75b74be24600b500b606 +9990,a79472b6b328a954a06af1073aa7eb14 +9991,05f4db7c57115c2f4363dbda56ed5298 +9992,c61d5fb1201f09adacca547d90989f0e +9993,e997fa2e2dba0dd208b5273ca7fa5c05 +9994,857afb3ea7574784ae4a69c7a5a9041c +9995,4b749995d844e438223c44c0c6319e53 +9996,655656bcc5abe75df48ec2e4d3cb8f48 +9997,96eb103f26e1f6ecd3e1645482c945af +9998,df348e45f84f76ad6ee00eb6a6790ee0 +9999,ab724e1d6813855107dec66810def4cc +10000,69881f78a70533e677c59f09385c77ba +10001,a52298aefffc5701a9a20159fd68c636 +10002,792c7879ba8a91b27936f84ff703f316 +10003,aa25dbb896d82830852e60a07a927633 +10004,429f1474341f1a07924d9d27697b3070 +10005,b52108f8bfa726bc67a5cdfdd0f309ae +10006,34e21986c82b6a0503a9152c2cc29416 +10007,c595f8ea249d06398f26123044e60afe +10008,c0ae4e341b4d75782965bc15e61c1aae +10009,85b787fd93f8e4b98032ff423e9580e3 +10010,d3db2c23885be7f7cafe75f79cd526d6 +10011,8aee625c494786ae782201e9ed992ff6 +10012,36fcd7ca325d2cce3062b09657e10d51 +10013,3be39cd919b5d83497e80dc0f6801481 +10014,5b1151fff457ea71358c7577c23d10bd +10015,296a2b124de5c3868a523fdf42d657cd +10016,14c17658e08f2db3594bf6cdba5216ac +10017,0ca24568399d2e30a93ca4e3e92c7735 +10018,ab1ba9d4cd591f391725384fbfd10aae +10019,d8ba8b619d0c37a08783ed68db02f4cd +10020,295ca5d2ebef10bf40d94d1401c372a0 +10021,158d2465e182a94db98d2f09bfe55284 +10022,303e3332a4d8b4fd8c577e99158889f7 +10023,de8c725157ba712da1d260c56894a1fa +10024,ec79163d8deb77c3fe097f876514dbd2 +10025,35f2ead9c95a3191eb2aa367c08e61ba +10026,d5ed1d0acd1e239630f7653b9e67f418 +10027,49113c6f9682360f829f80ac1cee158b +10028,8f1488e1e94505007b10e74f174a4bdd +10029,2f10107fd41ce02df331ef17bfc72966 +10030,9b2ce8b5ba0390d5eeed8272ec8c7d4e +10031,36b520ce1a3f1e41cd68e693396856c3 +10032,e8e3c498527f37f7b6b0eca2fb332260 +10033,dafeca12bcaa33c677d09813c471e44b +10034,0d710bfc03a5582260921b4c2849debd +10035,d661bccbc6298cf99ebabb31388a7792 +10036,359f84084657377afdb2c0266405f9dc +10037,e9638798eb90523ce56f9751b547a418 +10038,f6744ba87fc98b180db1257c2e8f729e +10039,6b4dac0b407c1bb938a706d33097a3ea +10040,f79ddfbd8fed10e91d4e9665a097ec4a +10041,aec6b0dcf66998cf737909a64197fb46 +10042,a6880b8586bddf457e49b50bad9b46ec +10043,4d6c3b279e30c5fe1917d7a16bf45245 +10044,1139d3451de6d7ff95bd4aa9a65a3709 +10045,cf28149b14210dce83c57fb85d4f53a7 +10046,a1bb7df611aa6ed8ff922609583d1774 +10047,1fb28e7919de28d1140d70d2aa1ddc39 +10048,9e55cd234979714c85aeaecd79a195fc +10049,b4fe111fa2b78d73bb680c1b4ebafc41 +10050,b25266908f45af8e493edf6df134a5e4 +10051,39d54e4c34649edfb0d561e435aeab35 +10052,4b0b4681282f1c89b6b262156162baec +10053,9ce7297f71fe295fb74cdf3516da6192 +10054,f88ca0d17f8019081c905048fb961d02 +10055,d01a97c1cccd15fc3cacd6c58a67b8b2 +10056,90ed90e19e286ec4e12d4fae81b8324e +10057,ea743ad2c856b480de8fe7082920dff9 +10058,1646f74959eb428c3af32642b1788378 +10059,55169e6edf18c3702320e2ffe3621ae0 +10060,77e3d3863af872ce362ce2681b0e0cc3 +10061,c76e8075cef5fe210cc3df3c6c92252a +10062,ea339f494b7cd2d2d7ff1166ad4d93de +10063,f72db3890f5e7950fef74d0966bd2d59 +10064,72d7227a295f648c2f6144901c3fc3fc +10065,8614eba5a75f849700f4c653511f746d +10066,64cc4c77ade1f617a814135893e57903 +10067,990655bb5ac324cbaf46df5f1bfca71b +10068,fc5f4ee9f49891c56d46f446b9995f35 +10069,43cb5e9aaa513a5ef9bb0fb994d0a284 +10070,0a17d95166dfc9b3591153ff10b3ba95 +10071,817d585ee42e3aa59e010cfab8099470 +10072,811bd1fde5215151a77752c4fcb463cd +10073,a96d611457d579830db28d21b647546c +10074,c9bfbf956486b438831405af928dcf29 +10075,6e3561916966fb9f564389cc5dd8b8b0 +10076,c3ad784c0b65f8dbb11f56e75b6478c1 +10077,64858a87c7139e22ef6dec89c3f1909c +10078,fcc2e753fed261f852e22ed6bde67303 +10079,6f13571c15db27fa71d999a56e486233 +10080,07c9233c38a535ce08069df4931517da +10081,54adc445aca17244f0f1f45d6bca3f6e +10082,7061dad6d832a5599e0ffe242865d0c8 +10083,f4f3a406febedfdd61b2f7ed5369ee6f +10084,2cbb91b08e647fa0f24eea17fd2c589d +10085,03785cbf84b1f75864b75615eb56c4e4 +10086,ea1018d0a41e83914aaa1787f93a5a0f +10087,6b83fbf2e0d61cdd5100b0c2b62a3822 +10088,1031e44e4bacc9d4599d12b7b1d4b18f +10089,bd58aac161b9ed899d59569ecd390a0c +10090,2746f4816609cc6eeec058b85452f766 +10091,0fcdc5558af5db26c1b390f23d635f2c +10092,338b74cd8bbb1c3996ba7166d1ca55da +10093,f2e656662244a649853b0545a6de8e35 +10094,2d432159666f886a9dc4fdd15c958bd7 +10095,f3c4fb2f5dd1a5717ba06fcd66261aff +10096,387cb0dc2ff6b10ae2948cce1a051aab +10097,b70c6a1054d8ec4dc503b7e71e3e5fe6 +10098,d30ba2fb23f1815b430314836b8c48f5 +10099,98fc254d3d1af7aa04e78588e71e00f7 +10100,f58b62decbad66e93e0d3463d4c53b12 +10101,97cc3baa40a597e2834014c0c85557bf +10102,079f06079c787aa11f7dcb93e77d7568 +10103,9294d16f75761c4ac0f3f604ea8a91ae +10104,4a5bdc0b2f177f7a0bb7be947f8efba3 +10105,2eeb16a934eff9e4d46afa7edb17c007 +10106,3d974986fa0372704304392959aaac2e +10107,ea0e2fafdff3136fdde9c8bcdce07f89 +10108,7fa40a6e699b337baa92c781626c44d1 +10109,65a6958b9e975b4b86c06c2ecfae273e +10110,4cfdb7c15df3e330f4b6b3cffab62391 +10111,8a1b7fb79b23a67df6fb2a894486526d +10112,b68b73a135cd9b7b6827e518644cc4b3 +10113,58435ca799a1cd3427001200dba953f5 +10114,64f7e5dac4522c33cbbe38f40ce74082 +10115,8d26dba6f70fc17a098b420f75a88a61 +10116,307b7f76b83410377edde2f33eb9ac1a +10117,3faaa8a656c729914f28a7148e428a60 +10118,05e799ecbbc3275f3d574366eb051766 +10119,2336689dd62b9a58807fb557b0ae3aab +10120,6fde4b18fffce0e0f1c5b2d736b834d9 +10121,8dd9d8f3bce4f6af64d196cf71c1c484 +10122,6d392c1474baa61cd8a01fac383f4784 +10123,baeb872b028c644b6cd6b401ade97915 +10124,e068e93a024b4f8ace4ae11e174d066b +10125,6eadef212c1bf8a0644cda7c7b3c5c24 +10126,45264cca77cfdc1f6d5b04e812733eb6 +10127,8842b71f8e289cee7d8aacebc60cfcb1 +10128,dcba7083bf00fb56e4727c7056251a78 +10129,a3e26687f374016c5a00e14b59821fc9 +10130,5a22bc842006d249dca783e08cc9e72f +10131,7662f2fe40ff944529e67baad7a8833b +10132,201e7106d034a59f8d0ddf52940bd7eb +10133,622043a1d45c2aeceb7a0049c47c5cf8 +10134,5162cdda367d53f9f63fd85428f84fe5 +10135,7e47aa5b95a80911fa3863a4d2960785 +10136,b2b449b47d2040d48e0cbf3469c8c8ad +10137,0c9a769f1d702864eabc72cf23b40bbc +10138,13097b10b44cb1018227ed363a594fe2 +10139,8ecc1094db38ad1e920d3393cd19c1f8 +10140,f9cdfb900a5f2cdd08516edc4e535649 +10141,94965f04406d0a38566c4cb538fe2df4 +10142,78e0ce1e05cd49c13f5594bf13f702a7 +10143,7ce7ff929b4dad56d945bad1118aca40 +10144,5a6ad8cfaccfe91e26f65961e060ba24 +10145,9686a6762f6d9f8dd694ba5e71ea60c7 +10146,882ee71ab9d9a6ba0a642ca96bf7a434 +10147,1a1ace7e5a35fdf33a9877b3f7194aa0 +10148,3baf010c2e75e07fbf5fe6afb10d6a55 +10149,724d4d60e7d1b1f92e35876f108ad0df +10150,bf6d0547b702b5e994222afef6e8477d +10151,c3f29d17e4cd3dc5294be3e461ac66da +10152,affe07fd4a93eff7168eb9c616f95c5c +10153,b88b1be21efa3939abb61e3e1de6201f +10154,3f18ef787c9de8d3c5dc07609293a8dd +10155,fe6ea53123db5ff06e9169dc671a5f6f +10156,d11a359d94447eb0aa51484a17b0f797 +10157,80fa536be1aaa378dcbaa4333dd2c56c +10158,3e34c22869fd47a59aaf3717bb9507c1 +10159,a7c4e0f239b1b773e47c0eb46ebc603e +10160,1cc3094e6c345b7667dab81f9150e350 +10161,8a19ea576469cd6c9dc59b5b7bfcd3bf +10162,5de3ede8b2064a43557363c77f0dc34c +10163,38ded204a60544e0af44df9a4b31497d +10164,922895b76c9e5cbd0852c813a9a60861 +10165,6e116dc3909677aed6123a9d31a9e28d +10166,c455d80103fd7065d21452fe1d37ee92 +10167,deddc00af0bcce79ed1e1e5c4e0934c8 +10168,6e200cfe6f68555246386d3727230b32 +10169,eaed179872656aa51ec8bc58d541a598 +10170,6cdae9e12bc696824bcbe4405440b9dc +10171,a4768db65d675d61cdf0fa9d9cf0e350 +10172,02caf2d6edf0d265ac6e5b8afaf49e98 +10173,2ac44488577aa917cccaed50ac4bf402 +10174,4513e8651c7bbef57c60120e3bc5f0df +10175,86c8924b77580cdd8104384316de63ca +10176,5fedcd4e5970e82c7cb6135de6fbcd43 +10177,3ec8a8f40c864c94184539ea7995f953 +10178,b509527bc95d93ca5bec485153dd4d0e +10179,989c6c3284cb4b5f57f4c48e78231e00 +10180,4cce99d7eb1cfe4b15d9afd72307c66c +10181,1c69cbb715e8cfb89b583b449d52a7de +10182,928dc6cac29be9d97ff009c425646204 +10183,2661c982bc1c7422721e5ce78e1b85ce +10184,4bbb471199f8ade0526c916bb80c4ea1 +10185,9212e33747dbd4706c608eb4e10f698c +10186,4b976af9ef76c24abb70e73018bc019b +10187,02b4d1902608adeec8f481e5fc2db145 +10188,ed7febe773a021c532721b87746c5350 +10189,ab0c6722da52804ec9a40d3ecc5f6bca +10190,0e931782a463caa31a209543446bb924 +10191,83d96227fec532ac607ed9b6858ad7c6 +10192,eb88237bb571ca3c653d275c4fd2c09d +10193,14f4ab589a65004728ccd5e6d6f4c479 +10194,de69f9c0f479cc2945c889fd9d6540fe +10195,ad358c3886bdac38fbcf1af0b53378d6 +10196,6027a5a36e73afefe6cfbac746509101 +10197,687400a0a1868898f209cfc38af5ca01 +10198,bd623c12b34b83b0f118d9bbddb5bb09 +10199,44a925bb62a123ffb466548b81a5e2e5 +10200,05884e1ce25595c32e1befd6088eec16 +10201,80b0676a5ef7be7b3715114de774752d +10202,e025b47ea629c40d6f0c6747b8979a3b +10203,2549780d4ab35b285dfc6a804c489065 +10204,f272830966dfd0e9f0166a0fed3a3c3a +10205,9d2da218739bb45fb9f9fd793387b134 +10206,4c69c67f7173e888f08879b9abde758a +10207,dd765f4ec46d09e9cecdc10412c34604 +10208,b7f837dddd8c8cffe5876ca699261bc0 +10209,ffd20d76bd38d8964a0419e33e08feca +10210,bb3797cfd5c38aaebb0f164fbfc68eaa +10211,a72c7cd22698f2bf5b164e4de0ddb86a +10212,4097010cae6212065b858ee55c3f41cb +10213,2e8609253faea783327eee9e78e1c5a1 +10214,b05823d6a90156dd979bd5185d2b5a3f +10215,a243f95d6ebf1c40bc3059d52ca8c520 +10216,02bc744e7b555196a22a490a2bfa2c3d +10217,bc2bc0d4f8e76967609d724b0d55aeab +10218,f024d16c076c1ef44d2a7dbb8d7365ac +10219,d8b02bcd7f6728902940026ade832be6 +10220,1cf2ef228e38c21c99e3fa7ba3b90f55 +10221,48950ec27da86e2aff30c814f6bd784d +10222,1d1fc93e8bc14876428c614ac39e2f9e +10223,c8798c5ee6fa7975416a520542b50411 +10224,f856ae28465f9361980200710e929169 +10225,9b7907e5d6411e8afdfe24645a0b751a +10226,cbca5a1881f33cc95fb04207dbf94802 +10227,4693ed022ef3e75c0a86368583d078f6 +10228,1c420c4ef6e21079bfdbd5a11c5e5e0d +10229,be4602fcc3f64a84e425967e330cc790 +10230,dbbe5c2cbdb1c626ddd469aa8dc73b3e +10231,14e13a8647c734cb1ae19891242ee0cc +10232,3727162d82578152ea47e41b4b49142d +10233,deb954395da8eee0d85bafe6819a0e64 +10234,dceb392edcd338e2430e297691e6d7f6 +10235,cb91d703082d1ee2889e338f28dcaaa0 +10236,81599d9d2b506601d3801ec33eec9367 +10237,7616c237344bff69a26b9b6483012af6 +10238,0be2f0695086359e97b705853c869852 +10239,435c857d9e9ad4973be29ef7c5dddef9 diff --git a/hashlib/test/fixures/xxh3_64.csv b/hashlib/test/fixures/xxh3_64.csv new file mode 100644 index 0000000..111f79f --- /dev/null +++ b/hashlib/test/fixures/xxh3_64.csv @@ -0,0 +1,10240 @@ +0,2d06800538d394c2 +1,77ead0d66864b856 +2,05c08cdb816da6bf +3,fa5bb15de9326deb +4,53aa07f42959aae6 +5,28d742e197c0fc6c +6,b955ef3603293d45 +7,90d63cefc8dbea9b +8,e51be922965c2d64 +9,0f4a2a09b575af5e +10,1a4d82e6bf2ede3f +11,29e2e38a730f05c1 +12,fa170e55447e813d +13,fb426264a2cc4a69 +14,c7dc2b5095fd6e54 +15,c8d6a9297d4192a9 +16,fa3e85343bd1eb85 +17,d0195250b7c091a8 +18,ec6a3c41e54cce74 +19,ac30293411b79370 +20,f7809c18547d31cf +21,3cb90b10611c4ee2 +22,38d341d9f67116a0 +23,bfc8170c100fa2a1 +24,1e58154588131767 +25,afc4bf00d51d156e +26,db2b89e68f540d84 +27,45099d2d95b49f18 +28,3a91d051e2db6ac6 +29,586e86c7372e0de6 +30,f33a2825a7068e80 +31,e33d11fc9119b648 +32,67853ddf6e4cf75a +33,94efd2bd22008cd8 +34,837013a298470d6a +35,a39da6e5f94c2c86 +36,a0cec1454a5dcea5 +37,9cafc51bb372f3e5 +38,b124d0a66c00b966 +39,017e78912832d874 +40,7876dd1bb7ab8e52 +41,e01b0cb2bcacebe1 +42,ce476e35bec02cd7 +43,c6687d2144f10262 +44,e5a17b689b3537e1 +45,c114a7b7cd3429a6 +46,7435bcdaf52225cc +47,cd6e3f3974075818 +48,12f377337d5a5d0d +49,c1873ee0762a0e80 +50,a2cd71e2feaf5544 +51,316d63a887aa2171 +52,bf3f503c15bf558c +53,e91b817bab140f7f +54,1d2945c2ba92678f +55,31ca316ec35d4a49 +56,c9d3ddea9b43183a +57,5c8c585a6f2b0fe1 +58,b750c2e3ede6bf32 +59,d5ea5d32d92f602e +60,daea55e4a66dcfee +61,c46e7b3a7ab9e22c +62,14d9bb4c079a7c60 +63,04e2ed1933b7cbad +64,6dd53939c35d1946 +65,b602e4aab8777e61 +66,cc877997ffce24b6 +67,248e7f85b71c00ff +68,62ec04333564baaf +69,1ae71797150bbb4c +70,72830abd2a7fa640 +71,e7241636efc2378f +72,d473571cd29bd46b +73,6822e7347ffce412 +74,948d419bc3b8c3b2 +75,b9a314e7bfa44abc +76,ef5f5cf624495d78 +77,ae7dde1d97a4bf8d +78,6c42487bd5461c26 +79,ead65a3c15dec384 +80,bc0aa8222172c090 +81,f2ae15292f308919 +82,b69de985c2cee30b +83,b27b95a5797ee018 +84,a2acf51aa3f4e44a +85,debfe9c36c0806db +86,fdcb503bd53e9d45 +87,c0fc567b43b1c779 +88,cc40a57ead9882a4 +89,a22302f1d22e7332 +90,507425dae2e0ae09 +91,34bdb0a3b2df52b0 +92,2d3d08152cd639c5 +93,dced684b42025ace +94,1c88e29d55f7aa0a +95,a1b69f145c6059ee +96,ed29f7fce45b343a +97,c727372dabe74054 +98,413fb1ad61cc2651 +99,fc309ecc6f99880c +100,596cb463752aa02e +101,061be10a0b55072b +102,f7fc1828169e1908 +103,7598cc3c04bc75c8 +104,2f203985ac7fca5e +105,e8de6bf4c477e867 +106,43bfa07e4233058e +107,9460f55207be2f21 +108,e5ce43683c12e71f +109,7ada66c49bf5e7b5 +110,6a80231c92caa724 +111,842653e9752f7cd7 +112,d7c0fc9325387219 +113,8035488f713819bd +114,c372562c8370ebf7 +115,fb1cfbd3f09d5764 +116,1bf9559696ff0acd +117,b2268ae2af520ec2 +118,a54f900fd68143e1 +119,6dbe002ef8e0108e +120,e2258d3c4370de72 +121,7c5fb3e53309c26f +122,df740cbf9f560120 +123,25faa84afdce2a8d +124,b4a3088a793a7bb2 +125,a615792a5f04c544 +126,d14044666c0c2097 +127,dab295d2b949369d +128,b2742b85d442f6f0 +129,c0ed0c2466103433 +130,2b735f2c96c4a8d5 +131,7bd81560ec137ed3 +132,0ed20f410362c4cd +133,d7428b4e8ee8221c +134,d2b39e06b1eed204 +135,af0930660ef35d17 +136,ca8f4f470c8b43e6 +137,92fd3d96ff119119 +138,7dd7b94006a59423 +139,58510f8d95687bf3 +140,b8cded020d272b53 +141,9e0db620f4b4629f +142,dacc0554701f9acf +143,0033c5210c995c77 +144,93a379603448ade6 +145,24dca185aa4aa964 +146,f7712491d459c40c +147,91e362d899ae9c4c +148,aa01e3778e9c9777 +149,3d1708f74fc57641 +150,8e84d715c5130c76 +151,0d876be9e4994f58 +152,8ed94e5097701530 +153,c8dfa24e894677cd +154,1d64be650e6cd143 +155,92809afc6361d577 +156,8ed575ef2204d3c0 +157,c8559f987d94a485 +158,0e04188091ae86eb +159,b8063465891ef6c9 +160,234346471f2fccb6 +161,94330cae742bc8ab +162,cb8b713a41507df5 +163,d715fb51ca9eec0a +164,1899f04f0d761af0 +165,cfc0a9df11a2b0df +166,a585b1fcaefecbed +167,d7d2c5dd6c2f1a94 +168,d4e610d225755a61 +169,78d57b7429cfa54f +170,d5006f28802296e8 +171,861ad4946eb22717 +172,080a1d656e321efd +173,86c733dbf459317e +174,b2143a157f750258 +175,d30d25f38720d941 +176,2d413bb8389f927f +177,50cedc0b55022900 +178,6700cba1cacd7e81 +179,63d5534dea6322a5 +180,c144fc1b28b92f0d +181,c33b870e028996a6 +182,6af016f0b2cb9bcb +183,b3ba29bb56ae830b +184,241f00e1eef231a2 +185,2da64739ccb74293 +186,5f595bb87a317a9f +187,09bfbbf87d71d75e +188,01520965cf452877 +189,ab9607ee0b63b06b +190,08d5948e4ed7b2f7 +191,e4cab9ada740fcc4 +192,bcba219fd3ed2e29 +193,00ecb29a855d62d9 +194,142a96a7ed470445 +195,20686d918a9ca098 +196,9760a04e18689fe9 +197,7e3fea10c3c99594 +198,69b10ced66405088 +199,208f15684645ee9b +200,b743bc28ba9e2410 +201,2e17337a48f49303 +202,f14af6734cb0248d +203,2ace37cd58b02dc5 +204,64a1e21c03d424cc +205,13252fc16cf8b6da +206,baf943d9419f0db8 +207,7f042c5ca46ae629 +208,ea5b289d682fd69e +209,acd7d2b06cb471e0 +210,642dace9ae9bc258 +211,fdf1fb223fc9d353 +212,cdfeea4404419a6c +213,40095168cf8debfd +214,2c3330b7076e75be +215,9c18eaf56a3294c4 +216,2b6d65a5914c0e23 +217,0d14ec13deb1acf3 +218,804ecf75b9926e60 +219,7752df1e7a85ad8b +220,3e1ec727d6ce4f7d +221,e5a6a19ecc0d8a03 +222,8267f6545575d993 +223,64ffc76f9e3683cf +224,c60a487ec511c1fc +225,92820c57eec0bff6 +226,5e826812f474adfe +227,7bed066e25a0fb59 +228,98fb075f6f0f983b +229,c59b88d3e47c114c +230,35c718bc4061c017 +231,25374ea6ea7ee63c +232,02cd5e0e2d227ed6 +233,64a6dc9979005884 +234,c389a07ccffdf0ca +235,6b8951e2e6bf5693 +236,6fbbf09d124d7b7c +237,a395bcdbc059a9db +238,b24ec9a540312d77 +239,d3edc0b602d9118c +240,7ae7545710b555c3 +241,99be286ee0cadc35 +242,cd25b4ae0eb1f30e +243,2f345a20084c415d +244,e4fe1900b4758823 +245,111507439e906b8e +246,4ae37cbb69e6dd9e +247,ae5cd69628159762 +248,55092228169c53fa +249,e3a58c41acda5ba0 +250,59b1249cd17870b9 +251,6548d0234c320037 +252,de8825bb706434c8 +253,8277d3e463f15b1b +254,716862b5619b5c39 +255,bb01d7e7eeb9e64f +256,29189de8bfcc5dd4 +257,0e9fe81ff4d617d8 +258,5ba4821a157e39eb +259,8ae8a0d72e091d19 +260,1c124b722ca44bb7 +261,09687e846b91d89e +262,5d9c483021e72a14 +263,58905ca05de5411c +264,769b85137eaba2f2 +265,6f551e17c871a6b8 +266,8dd3c5b85f026908 +267,ccdecad2203a67ac +268,d0a397d4431cb4cf +269,4c7818b3a269a49c +270,5c0f3b0442231cae +271,146f7e91fe668f28 +272,b29b40ac0f1fd3d0 +273,ce48a1e93f0e479e +274,f71e3b01b2549d22 +275,02879a0b355deefc +276,a13d4e4500500285 +277,e070e38b58d441b1 +278,99e8d5d68d1706e8 +279,60db46e19f79c550 +280,9cc2fee827b3da26 +281,32a06b7a5bd58f0f +282,7de9dd809b8b0f60 +283,7eeb3b61a284efdf +284,b17c87b37ed04f57 +285,576f556c5fa3ee95 +286,2ea95935bbdd6f92 +287,0c283a1e9c517ef4 +288,990fba9d1374bbae +289,0b1603c2a79d3fbd +290,1fb97beca05ac48b +291,6c1a0ce179c9aeca +292,becd2520116899cb +293,d713d84a38b22da6 +294,575cc5557de74527 +295,bc0ea8b791b17690 +296,01998295c2357eb3 +297,3871129ba6bba81d +298,c07261e4352bf028 +299,f30bd3b7ee93928a +300,3dda14d16a77138f +301,64e69ed9ba5c27ae +302,758905ffbd3e8752 +303,7d9211c2be785673 +304,f3550cc6793b89cd +305,d7241123b344357a +306,53feef199ba8595d +307,3094c71284b65f46 +308,60eb5f6e8134f246 +309,71ec86c94d7bb739 +310,8419212c61ecddaf +311,eff61055cfac9462 +312,d0f86694515f4b69 +313,7f136c7bb7dfdba4 +314,2804383b1186cc9b +315,d85197a4b7af7c66 +316,eaf77261467927b4 +317,3119c5592e4a3dab +318,fb5faf5e97feacfe +319,ec4b59072d207244 +320,a27e7af17431f4fe +321,90f9e80b2f1fe869 +322,a4510e240d3b0937 +323,8dcbe37a13b0909b +324,54b6f9c0f11c9463 +325,a7bfaad203816f42 +326,e8bcad11d94eb5d8 +327,8e82e9c81d53f94c +328,3dd18252fe697532 +329,2823bbdf90c80d06 +330,82fb48bd52870acf +331,8dc0f66f19b71390 +332,53cb1600df0fea44 +333,a3af597c2bd02994 +334,8d0dcf9310795f10 +335,be60831e840c5cfc +336,cfd997b6e1b052fb +337,bfe14dd334786279 +338,7dc3821fe6e425fb +339,68b995000629e9f9 +340,59a4ebfbf98ee600 +341,ec56fbe4b9d6e83a +342,70235a3ae4c1c066 +343,3af44bac36789f71 +344,5f5e98d337fd7fd5 +345,4382ac075282051d +346,93a4d5230a26b213 +347,98fefe56ebb7081e +348,6f53dd11b61f977c +349,921f11abd7c385f8 +350,5b21c415e6e554fe +351,9a35c0fdf144922e +352,bd965154a6f61ed3 +353,f1e336ca2156b4d0 +354,cc5d2ffd7c2c913c +355,9ec4fe4dd81f8efc +356,e81ac7a9c3b363ae +357,83fd4cf000b29673 +358,f7c4f35417cd4f21 +359,082aca0383c0ad2a +360,290e6227d9aee805 +361,557f789592025c5c +362,58ad1e3dc47683da +363,435397929cafb1a2 +364,3c781f3fb2c957dc +365,e5331e303090aea5 +366,0983f8f5f301c10d +367,2ed9d48d96e6abba +368,392edd6f8a23efee +369,24cb45927ecf61fa +370,4d38cbf605313604 +371,f29833cc91f73024 +372,627b2ab212bac037 +373,75af21376b9af215 +374,d1d023885ec67f64 +375,783eac72fd7d6202 +376,3c0bbf4bfa84732d +377,f7b9d14ec1dbcc84 +378,a8e8574e22a7d2ad +379,1d74c18eced7ed6e +380,9b273acc66d3eb11 +381,76e7eb5e24f43d64 +382,2886f9cad76dd07d +383,d6ad1f3618874932 +384,cd4b75f77120275c +385,cb179f72269730e2 +386,d94294eed98fbea8 +387,3ee94a91c6c16419 +388,99196699cb352dd4 +389,9ee0ab639a0f3521 +390,a4983a5d5db4eee6 +391,bbd1dd4f60d69a7c +392,9519ffba87fb002c +393,01cf0303e0a47bfc +394,7bb6471ce048a0e2 +395,6cf473c0a7d59f1a +396,8c412cb6c512f54e +397,e64083db32f8ce7b +398,f01b90991dcc4116 +399,335386ad4ded18c7 +400,dde1be8f611984d9 +401,6aea5da6eb5083b1 +402,7f0a68ec238315e8 +403,2bce6e99fa5671b5 +404,1b3dacd30edba65f +405,b553aa8d678ab8f3 +406,b0b8ea11120c8820 +407,36f416989d21e604 +408,11d778491e455482 +409,84ae48f55db110aa +410,5dac71caa81ea25f +411,85d82483fc9ab777 +412,88725ac36bd075af +413,d04c54fd421db1f0 +414,c454d8e79a7e8c77 +415,ecc4a301920e9784 +416,7b7f097e4898b475 +417,8fb44b08eacf1ced +418,df2d32c6429d5426 +419,b574d8c03aaff16e +420,14c228a8c3e10970 +421,bc2705911891c583 +422,a89571320501f4da +423,aca90c495c1839c8 +424,a47eb533df3a8498 +425,a6272f61dc21160b +426,2246eb47fae98af7 +427,254af25b061814ce +428,e69b32a172175f39 +429,6a072e5853ba9031 +430,12366ce722c71b68 +431,b8297a8997d71acd +432,cdf6d6e6929ad2a8 +433,6b207bb925cb755f +434,3e24760846c2e54e +435,2ebc8c13567cba36 +436,2397bf75131d5857 +437,646f5967da43c1e2 +438,53f6f93b837a26e4 +439,0bb8ee531779ce92 +440,ea455e09251ef3f8 +441,e0f8a4d32f9192f4 +442,21db213e78ebfb95 +443,916463b3f7ac3bb2 +444,dff98b13fe594975 +445,fde9e4be98f5ca3b +446,adfa7ea027058b2d +447,c708cd24bfa0a5bf +448,1821605669e4a80f +449,80cee0112cb83c2a +450,c8505c3d4afb76fd +451,79274a9d7f530455 +452,738ec45486925130 +453,f266bd99210e2c27 +454,5c5f06422bb3cf69 +455,808b289307faab30 +456,8df1611c95f54bc0 +457,8c4f56139e5c3f63 +458,babfb8751eb4a99a +459,b6ce96d958c44006 +460,71aff67b62fd201d +461,9e6ba7faaedc38b6 +462,00bbeb3499a84ea4 +463,55be2b18dafd3901 +464,e08dc14ddbd62ad1 +465,632b0bd646653e7f +466,b229623c9ee5366b +467,34dad2efa1f7cacb +468,67883b818d9e59cf +469,8f6903c6ed79b1e7 +470,5f73fae41851a44f +471,853525f7cf6d83e6 +472,a5bf9391cbac42cf +473,d019a4a1658b7326 +474,1c38e7431d720307 +475,21ce26ee2fafebf0 +476,a26acbfd6b2f2dea +477,fac905955ca77ef1 +478,6ee8a8ddd3794a19 +479,6419e90698769434 +480,b78bab92d7756b64 +481,263dcf649858f98f +482,09dc412746abbf4b +483,348e3ff4a917b6b0 +484,1cdd6a735b000f39 +485,e46bdba7a25d2730 +486,4e582727ef97f810 +487,1a8d146ec1f72534 +488,06e1f7dc7e6b839d +489,0101f2ec7df97de9 +490,6401792dd97ab945 +491,34094b816b7b9f7f +492,51829a3a4bb451e6 +493,eb283222adbdfdb5 +494,6206f7697425576e +495,5f7beb20fefb6b62 +496,33410da57438aaf2 +497,542fa7a9486fa3a0 +498,5d0851252cba6356 +499,cd38149dcc4f2d03 +500,8ff0e8e11195ad82 +501,20581e0856547919 +502,cb8b15cd540fe3b8 +503,6a3fafb4402de747 +504,f9dcb14ac21fd3cd +505,29e54ee25d3eb31d +506,de83270ff89b47d4 +507,c272f4aff0ff40b7 +508,6dea145ed7813bf5 +509,56f3d62360dbbbad +510,4552f7dfec612e41 +511,7f2ca356e93571e5 +512,218da7a5e018c37f +513,961db3e43a948207 +514,b883be80c3d46486 +515,1baff6333d3ecb25 +516,0e309ecf31bd1ab8 +517,10372baa11fd7666 +518,8caacb42c1942322 +519,7565588cb475a256 +520,9c538c92b5904296 +521,e2003217dd6045da +522,a2f07a2cea03587b +523,a90771eceb6b80a2 +524,fe39e55b9489bef8 +525,b91ee5a873450129 +526,193bccdcce469306 +527,95d5d64b8b8d36c5 +528,45945c6c790f33f5 +529,a9f500fa8bd51ebe +530,663b1b5a1a2b191e +531,661cf8c31248fba6 +532,ce85bbe44a1d3335 +533,d3afee0eb719505a +534,6b73c3f976a7ae5b +535,026967ef34c4e487 +536,678e66c471ff2eff +537,0c33288ff407459f +538,480d63fbb8f2562c +539,823afeea870ce8a5 +540,b40e5e96781a626a +541,9de4e1286dd25515 +542,8fc5ea5a2eb7ee09 +543,66e086a8c2020f7c +544,c8d4f76cddb3f8a6 +545,8b11bbbd87617cfb +546,6ca5d69d45c8bee6 +547,d0ac6ff48d59d613 +548,7bfed5a77c571cdb +549,e697e44c33e506a5 +550,cb35a21304b47b91 +551,abacf57971307207 +552,be52980f17194f40 +553,ff20900024d4e4ab +554,21e42503a748d996 +555,b1500b136fe9f24b +556,dc842aa007273b25 +557,51b4879c28b8c6d7 +558,555db21fa1101cdc +559,c5307e55c11d4922 +560,e70057528a44e55b +561,3b291706a7afcac1 +562,3c7ed3ceba622e55 +563,067dd2fc5a5f1544 +564,073847c80a859fa7 +565,1a43ffc7dc0b83cf +566,503478e724e77211 +567,f07f4ad99f79c5e0 +568,b0b2a010e3b4ffff +569,aafc1904376a6386 +570,464eee6913d974de +571,0bd09f1a374d0f9e +572,1e34926250bd9822 +573,1e5fd499c3b4aedd +574,3c43afc29c631d13 +575,69663d612905b252 +576,db045b133482b68c +577,ce5fff25732a11a8 +578,2e8a7c407649c66c +579,ee67c54cfff0dd9d +580,e142c8756d932e0e +581,eec22e6c41508f29 +582,c1d453ce1e2419a4 +583,629917871a7a4a89 +584,2d8ae017fbf09693 +585,37fc7c9c78e046a5 +586,dbdb889243be06bd +587,5ac375e36ebf456b +588,fefb6ca4c324a6be +589,e1a1d80629b03c10 +590,da7ece26ba64a78a +591,c47a8304ca699b04 +592,ab831b787e22ce00 +593,1c09b8a831e3d053 +594,d354a5f66fb802a5 +595,f02fc75419d373e0 +596,aa4d29abb87ad74e +597,bbe728e0c25c1fa2 +598,09280187a447720e +599,ffd34ccf3400fbe1 +600,1261a4640ee5a196 +601,3e0ae8a59a3920ba +602,ac3d3783c166cfc0 +603,8832ff4f3f6c31c1 +604,780aa43552db52b1 +605,cc97f6fde10c145b +606,3b5f34f79675e110 +607,af6ba9c65b3c1c69 +608,54752e61210368f1 +609,8491f05c2e708c46 +610,1ee4eb7c4dc53c28 +611,438fe4b224c64274 +612,5879655db9eeeacf +613,e6915cf8ab46f554 +614,7799c7ec87846c27 +615,db9c95b0a19ebed9 +616,50fd8bcde439bb5a +617,9c76e99058476a24 +618,d4c2fc607db544f3 +619,704d9b87ba4347eb +620,79079c92f75c5345 +621,d72eeae82e82118c +622,1b496195c6e68c6c +623,87b3cdc07aa22d84 +624,fd75f8b0f08674a4 +625,ecd9c862de906839 +626,8abd376ff6b389da +627,8a39b7a6240e19ea +628,947c2915b88f2ab4 +629,b28ca246c224f900 +630,68c390f4da4fcefe +631,b812fee594f69976 +632,f3988f8b81f95fa5 +633,28b5071918b4bd67 +634,035bf907f22693ca +635,b5e16d1fc134627f +636,e2d331118a2726d5 +637,68a7fb82a1c412d5 +638,dcc216099d62a29d +639,33c92dba23313890 +640,814e46583f1b4001 +641,ec23cc6ba76ad32d +642,3e22116e90e54647 +643,bb847d333aebe445 +644,aa5a8e699f2a8d30 +645,53ce531403d643b8 +646,5dea21f768aeec64 +647,8bdb550c44886611 +648,1f82c8e229a314b8 +649,4eb5902ca2300c39 +650,fdd0f489c1731e66 +651,e27a2990d9bffbca +652,8637a434ec6c1de8 +653,79987432db3c0555 +654,5269863336495abb +655,849a9df0cd1ac9d9 +656,81c9d4c4f076db8a +657,a2e9ac9ed85a34cd +658,479652216b805b43 +659,fe0296543b60a339 +660,0894a5bdd70024ed +661,0c2a82f868a75d0e +662,ca2a998239591cb8 +663,ce1b4738229b9692 +664,c0e545be2f59e493 +665,0add3170233b75ec +666,4044776043717b29 +667,16a5d2469a0cf03f +668,02ec30ce2081f98b +669,7771f14c5d125082 +670,ea8e04dd6c3000d1 +671,09ec67a34012b066 +672,ac9997658a72e292 +673,1d25753798f8a9c5 +674,814b7f6e2a66ab8e +675,264e7e48dfec9110 +676,52b87806cccdfe33 +677,ff55649c0d6a0f84 +678,03a65fc6e822aed5 +679,894590cece816a5c +680,dce8fa3308960027 +681,b567fc0d036f7ae6 +682,8448195747ef6be2 +683,868ffd4b8129e6ca +684,8fb01954e50bdd4f +685,679c23716dde2247 +686,b70606ca4cab7795 +687,999ea6e912beaa40 +688,238420d843f16f10 +689,4d754d1610e04917 +690,a59cc66524494d39 +691,d07d9d134951b360 +692,271e161972c9ae58 +693,5704617cc4e936bd +694,ee0e29ef567f0e5c +695,f2fa2d83bc378883 +696,5417feb7b3842a07 +697,cdb76b5a8f65ee48 +698,6752a98b1e6be0ca +699,bc35c46eea89c6ab +700,a83cd658b145c2f9 +701,e0c3c2b8b7dcf362 +702,d5c0b21aee5f330b +703,552a0b6262337b23 +704,c3b1ae4fc4d4ad68 +705,1287078b85687d7c +706,544606ced6fa3767 +707,275839ae86bdbd80 +708,154020c5584eaa02 +709,b08a528067dae860 +710,a45f80d67af185b2 +711,2d3d4646dac01993 +712,5c78d89133090c97 +713,863aeccfbda5d323 +714,7bf5d5eae0614bab +715,5d41bcad930ee016 +716,245297bf6a5cadbb +717,0a5bdf6241f0508b +718,02344bdbec297a18 +719,e5f993ed1d7b8c74 +720,81d21a10ea8de6e5 +721,bd3fe9d29fc9534e +722,eaa4e786df3a7519 +723,b2737d0dbfe82c78 +724,9f8af61cfc582ea5 +725,4c9ee71b532870a7 +726,446d08a0a3ec77c8 +727,109f556a9acefac7 +728,b9da5747305e3f57 +729,b8269aac09b8ed04 +730,8e3dde4734a0d461 +731,cd5dad1842f59c39 +732,397a59f00168df51 +733,7cc8ebac20883577 +734,54313db21b3778bb +735,c12ae1ebdc04b09f +736,3349aaefff6c33ed +737,83e40f4eb1114f90 +738,455012e9d35bed9a +739,f9eea57a6037361e +740,22368dd118580c48 +741,dd8f1bf85455e24a +742,4f72eebcbf2038cf +743,73cd5edbb5877065 +744,39de995c64515ce0 +745,8015b49d73f5a877 +746,c8a5204ae6c9e05d +747,ecafbda2119f73eb +748,3c008c28ab4bb6ae +749,c696fc3a104382ec +750,b28444caed8510a6 +751,218d61e65f108e6e +752,2737e84fe46ef05a +753,8d8e8388fb18a151 +754,a3d74298932d7000 +755,a20410f34f3371e6 +756,262faa181d365007 +757,ba60f8bc3036442c +758,9717442516ac0059 +759,99d40496feb58c81 +760,8a60a42c0eaeb1d6 +761,cdeb594acfbd613c +762,9de2c7290bd29236 +763,49f05e7e108d43bd +764,996c1104f9ad2bf7 +765,cc14ca735f28c306 +766,ba45c31880129e6a +767,927dd8044b5efbb7 +768,8edc221f22c30827 +769,c9eacc0d7b1cfe79 +770,3779b894e02c1405 +771,0c8f5409812bb1a3 +772,423e2d7d14d2af50 +773,b8c231a0304e58de +774,9ca5813b49d479d1 +775,b800f7968e9dc9ec +776,b54b9dadc6139831 +777,fb32e3b86f5234ea +778,cf885e9f4a275dc7 +779,530f857f5dc1ce6b +780,2a11d415899963e6 +781,a9f078ddaae42166 +782,f896a9eee4b0cae1 +783,43138b0155be8f16 +784,4c1803c4a7580140 +785,c351eb356d184021 +786,c4aa0789f45818a2 +787,3d6b97e74972d25a +788,cde1ae88d8e166d1 +789,a487a78e1c1b29db +790,8d584fd3f0fc53ea +791,6f68c647289eee26 +792,65fc1e30b8bf9661 +793,baa39e15448db6dd +794,e6cdfe4f057ad8b2 +795,05808ba246f54865 +796,da852d375857c77c +797,1a44534e8c186f4c +798,d8740376bad70418 +799,c42cdce2d13bbf9c +800,b88322d6c4a86d0c +801,e42a0bc6d500b79b +802,0d1e6f45b4f3d5e2 +803,ecbaa9d8e539af67 +804,de750dbe58835088 +805,ac689ec73a20dce2 +806,ba0237d1f9a1736b +807,d6fdea3012c2b8a1 +808,2ce6a86bdb89f15f +809,9677d99a174fd119 +810,1de00211fea48a73 +811,7a84c14511c7a0a6 +812,b3eb964d20ffd3db +813,b1efbf2c57aee93e +814,724ec8af553e1c5b +815,02e1c649ccc284f5 +816,237f195120ad6000 +817,ac571e49e30cbc41 +818,8de0fd1ae2101b30 +819,364b2ed8d74ec4c8 +820,1276894a94e0503c +821,08381cead9c4f7e7 +822,58d2f16c7660f6c6 +823,e352e8a51e8537eb +824,6e8964f77e7439f4 +825,3678f10d0aa080fd +826,8b6bfd73b91089d4 +827,02cabbbe83b6a888 +828,8ba279e49d8079d8 +829,65112a36f2648db3 +830,442302d889fdc639 +831,0163ae781376de60 +832,dac51f7f4d209c99 +833,2f48f4c90fee7442 +834,2d475fca61c3ce1a +835,4b38b441e68ebbf8 +836,b916310276973d46 +837,04b80b5950fd0fba +838,bbbd888e5db70656 +839,bac5b81746a5ad35 +840,83befbac299fb7de +841,05a29b405952bac7 +842,7290ac4066fe136a +843,21b4507cf5f53a56 +844,c396b3571890ff65 +845,e5a893b826cea65a +846,acd3b38def3602dc +847,8dfcfd4e5b4fd565 +848,416146445912620c +849,4451c40bab339907 +850,d6b302b178ff750b +851,93218ad6089a73ba +852,3a82b68d819416b3 +853,ed90cca571d18eb3 +854,95a016a2436c8b3f +855,e3df1f022e5c05da +856,68987a83b56c8855 +857,59e892f90137bfac +858,8a78b6c4055b8e56 +859,63ccc5f39555a8da +860,a3cdcae0cac60f46 +861,e398546da1ab5ca7 +862,5977d2684751cf32 +863,16fa9d74e400e0d1 +864,729d63e969ed18ac +865,eb5de699efe561de +866,c3eb359452d07c89 +867,e8b611f08732b90c +868,78354e74784c1e54 +869,8885060167fbbbdb +870,7ca6b5c79b5373c1 +871,8560c203b0bc5289 +872,4c59dc6742033750 +873,8855872e404d75fa +874,7a0b9b8024adc8ab +875,02163f47c8222cf9 +876,4d6b0e9eaf6b3561 +877,4028813a3f35ad2f +878,937cecc574e8b9f6 +879,b1ba0004b338355b +880,36fed1c4a47fbbc3 +881,463d64848c3b0072 +882,9011a9a4fe3f549d +883,ea0ca6170e910214 +884,0a5efb0314875213 +885,e16b9c325312cea6 +886,9d34e1ade7d6f06b +887,bfe3b7819597447a +888,e8506ff29f508bee +889,5ddddd739ecf908d +890,80e174247ceefe9c +891,3ff6e13a651cc49c +892,e009e7bb12fb6e82 +893,0a8210f71c721cfd +894,9dba38d3c8c34aa1 +895,4cf8f32b6ae5dd85 +896,ad8ae1ebce7db334 +897,e92c2219d5b2b411 +898,9ee966522695748c +899,e54eb09bc6657290 +900,48d56c73f6adb3f5 +901,0d0dadc6926a932b +902,caffb049855f00b1 +903,7d62e32a1a0d16d6 +904,f93841b5c9df2361 +905,130cc58492924551 +906,54181565b482721f +907,770f487d218e0310 +908,4715b3a5969407a6 +909,3c478580aaa09397 +910,34fab57632cb8ce1 +911,a42e4f2a3c2df0c5 +912,6fc90eb06a9f22e7 +913,6b12c7d001f8377c +914,463dd713aca0a51e +915,0b1b4bccfde22e75 +916,cc528bf43d544325 +917,67e4975b051eeb2d +918,375204c2b16e2611 +919,d1a947a82c238da6 +920,c65a8953c6f719f5 +921,eebd909d46065241 +922,c12741922e72c6cd +923,e9bbb62dd4cac966 +924,9d73acd05a172b94 +925,6c8648a9d6ee5f6d +926,62be173d17c3dcb8 +927,31a173cf44aa4f94 +928,e9eb7554cec88347 +929,924d70774746fe74 +930,7c2a4fadc61c2021 +931,a48e3f3b57b5e150 +932,0dd35d4ea111c983 +933,893bc6c193a63ffe +934,90383d82060f8ba1 +935,5a924daf38a46e76 +936,f76c364e38e8a17c +937,fa076f7dccaa0d57 +938,4935d082aeb9a663 +939,79c3f470549495f0 +940,7f811eb7626027fe +941,f2676feb201c10f7 +942,b850f904d845b03b +943,9d32e9ed962b268d +944,b8233abb0811fd30 +945,6e43292c2ab55312 +946,c51226b22f27fbed +947,ed5157a48f74dec1 +948,6300db283d11ce03 +949,79960dd20e517d24 +950,3f0dd8a2d1fcc1fd +951,ddc76d1d4cc1479c +952,bedf0a7c1fbf9da4 +953,86f5fa35a0b7549d +954,964bf247e30d8fe4 +955,5100ed833c330239 +956,26d9e516a0e36997 +957,6e20760908a1809c +958,f39a8aad5c64d737 +959,3e1da1241cbe7580 +960,2a81bf3df05f2ba8 +961,1690a0e1b2e3bfca +962,bd1e76419e115fa3 +963,134df78252ceb283 +964,9acd45011193230a +965,78f2e99be4ce347a +966,3c4d0a98a46ec656 +967,084ce3854291933c +968,851d34e93e6fec0b +969,9baebf78265c8baf +970,bbcfc21447bd1a47 +971,83b0f9f012460e44 +972,9f00782d041107c7 +973,f64e4cc464ab10b8 +974,3cf11f63bdd517ac +975,f586977984691334 +976,b1d357f07ebebf7a +977,267c3629b5666809 +978,7c9e99d48264aac3 +979,ff111339388bcb0e +980,fc956d8bf7740e58 +981,61cee794caf2a9e7 +982,b0eb64a4d90bd64f +983,abe568e80732fba5 +984,d3c681f45605d59c +985,e2b2a08469652c56 +986,a6f2e7c7daeb4fac +987,b5b66d7f067f7623 +988,455b6f2561801031 +989,b1f12358dc34148f +990,0cdf3193d20324e0 +991,17a59c64fb32319a +992,22f0831705f613c2 +993,0ac25a5f7cd54820 +994,18866f52cd67816d +995,089bed9eb60893bf +996,0870ddc128c8ecd3 +997,e792d591b4978ecc +998,d53fe06185af2f60 +999,44e7c42c924268ea +1000,9e6bc944162b8d17 +1001,c5d7cb06b1a07c65 +1002,0f689c5cf391aa5b +1003,1ccc90f0e487cd64 +1004,5ce809e973c1e910 +1005,21a3ba56855c7c67 +1006,daf8998fac5d2d1e +1007,a2d91dfccd91d347 +1008,ad9e3ac6416e0536 +1009,67860798a18bcb75 +1010,4a94c48533ed1ece +1011,f6c5e9f5089463e6 +1012,6b0dab746836cf72 +1013,ec5509aed9d75ad3 +1014,eeed4fe695da9cd3 +1015,07d72208594809db +1016,4ec528b5ef24a5c3 +1017,eba1570d1dd84940 +1018,724e33aa5097617e +1019,03425249c07143da +1020,13a7a497404e1b04 +1021,376ab9fa01c2a125 +1022,f16b5b177890e33a +1023,2cd035593114f1b5 +1024,4e5a3638fc59c244 +1025,0b33fefe2401629b +1026,acc5e389d7c530da +1027,f84d7b98351c78ce +1028,dbc8b65e0a778bde +1029,7ec83dab72821f97 +1030,a4dca8d08c160a0e +1031,ebf34921ca10eb59 +1032,e0685c9179d4660b +1033,e9b1a92fac547855 +1034,55bc7daacf80c1a3 +1035,f506bee22621e822 +1036,12bd249bc34f5e89 +1037,9c15e58001523931 +1038,0f9c077311620e5a +1039,79967c65226bd1f4 +1040,aa4f09f441bd378a +1041,dd4aacbef7199f89 +1042,4e559da2f4639859 +1043,5b93c081cb976aa0 +1044,d6be2675c07de7e2 +1045,454f9c7afc4035a2 +1046,8bf3ffc7573ae25f +1047,2fa366975a98a0f8 +1048,1a8737d86d770fbc +1049,bb0dfbc049f2d332 +1050,7bb8032ee9241a10 +1051,f7cfc3134d43bd42 +1052,87688ac179808dc3 +1053,a7d2a07e2ff644ab +1054,703c45851307d42d +1055,e8714c7fac2b690c +1056,5a511e18ff5fde05 +1057,87cb640ff53201d1 +1058,1c77d8cc5d71b8c7 +1059,170c5af03b19162a +1060,94bc6b0849898fe2 +1061,1a5588741c02bbe0 +1062,99d69deb73d18e07 +1063,eb6f2ea98fc732d6 +1064,ad3b089369a6327d +1065,4943af35b6498eec +1066,def054460cf89a7a +1067,59fd24fb7ec15bab +1068,87eb69495aebf4cf +1069,bdcc5c9f0d10fd45 +1070,9649413f0bfe5797 +1071,8891524258b6dfb0 +1072,f9485438bf596c00 +1073,fd69ab15ecab69df +1074,14ab4885dbbb5521 +1075,fa637bc6328ca789 +1076,75b28d30cc4d6936 +1077,809877a6ecd047d3 +1078,6f3975bb2f1c99e5 +1079,29507c5bab49528b +1080,c3e2fe9d75d93816 +1081,72b90b37ecd703e7 +1082,842879c4b073408b +1083,9f4cd65275a973f0 +1084,47fb23bdcf66f948 +1085,a47bfaf1ab303faa +1086,ee08505d7e25c954 +1087,8821ed7a834cef86 +1088,673a2a981a15e647 +1089,46548aa9852ae43d +1090,07c16930629f8223 +1091,57866b6927bd8e43 +1092,3ef8a5f883660ac3 +1093,f71eddf8c46e063f +1094,15fed519387b65d4 +1095,ffc87ea3adffcce4 +1096,7ebdf35e62e9c248 +1097,cc30972491a20d85 +1098,729a27fe43744b75 +1099,3535fdfd6ca2deb3 +1100,3f33e9910fcc6d03 +1101,38441cf31c1e75d8 +1102,50ed0153dd6409f4 +1103,6749cd546f8cd496 +1104,98f58be7c13d7319 +1105,8ad8b6e9df458ed3 +1106,f83695515048ab84 +1107,fa3fa19de21e42bd +1108,b9b7581e4a37f90a +1109,d6744bb6f02a4769 +1110,65d152503bba6bf9 +1111,a5e4d9c03776d139 +1112,df29d1c2f27c7465 +1113,0851f4ef253f57de +1114,c8ef4833ae512347 +1115,73efe0b2604e7c2f +1116,5ad744f4704d103a +1117,9a3206a6fdf2c6f2 +1118,b5746a4a9b94769a +1119,97c0bed3ab55143d +1120,6d95a44e063db5ca +1121,be3ad94c3a44b842 +1122,cb78cebbfea24b0f +1123,071eb029431f7acb +1124,9a47dae8df3a7380 +1125,a8ee6ac1059b69de +1126,9676d63551351f9f +1127,eef0a5ff80be73d9 +1128,0c17abb9b473d624 +1129,b8bcdadc3c81c682 +1130,dac87b903256b1b0 +1131,9c5df3b675073b5c +1132,ce2a5b4d52874cb3 +1133,42f3e6613981d500 +1134,cdf94d48f40831ba +1135,84cff5f75a1a1a85 +1136,ce0a370368ce7ca4 +1137,e652387a3b5c6570 +1138,d037c895c8d72c78 +1139,20775f28b311670c +1140,2ed5b4357e132162 +1141,92c7fcb1ff235229 +1142,0e40a82dd8293bd0 +1143,7a55181dd288c853 +1144,f010807490d0bf2f +1145,d85e262847a7edee +1146,9251fac561427dac +1147,2729167b194eea82 +1148,87936c11d01060a6 +1149,22898e1374f2be3c +1150,4d0a05259cb30224 +1151,c25019d07df5d3f1 +1152,d3a6ea593e828b53 +1153,5862b74c003c7693 +1154,f49e5bc5beea828e +1155,7bbb49f60ed89f0c +1156,dfa2d56552f552a6 +1157,a8a7adc710507577 +1158,d4af84f23ada2a51 +1159,48e90389ade7d49b +1160,b015eae38033df00 +1161,6463ae8afb2089e6 +1162,b09697aa87e89d4f +1163,d6e7f5ab1b3194e0 +1164,d4e1827ad4836045 +1165,b189ed0917a9bd4a +1166,459c9f801a32740f +1167,6aaec4fe0762b8a3 +1168,2c0db85e816d78ba +1169,6288e250376827e8 +1170,cfb13d338747d845 +1171,bbd68edd02a6ed20 +1172,8571e232db778b5c +1173,57b7f5387526c004 +1174,04a5d5e5f6d4525b +1175,ccf3d75669728dcb +1176,d7a3c1264fe10678 +1177,fb4cd33db9827c12 +1178,f39e98a17921e338 +1179,efdd19b6f76ea3c9 +1180,c07cb10ae0560a74 +1181,54880d3107f3adc7 +1182,d2b34261a7cb42d6 +1183,d80c3036762c79c5 +1184,bcb5b87638d06010 +1185,3f22f60b5927e0ff +1186,bb6f4f14e8f23837 +1187,8a6ea2d8134b9d1e +1188,50e63116ddc26a87 +1189,78f2e4dd76c1598f +1190,dbb45dab184aa68e +1191,d8e71c2534f30411 +1192,2e6cd3e5f31635df +1193,f8bd3add66b9d391 +1194,ee95fa5069b267c6 +1195,f3634fffe3d049a4 +1196,446ebd4d0d4115d8 +1197,43289a2024a981a0 +1198,55b265e17e44c1ba +1199,580d01fb984d0c6a +1200,9842886d509345dd +1201,edf6ac787f360ee9 +1202,422ef09df63494a6 +1203,c290520faf830966 +1204,abb2793fd557c151 +1205,275ccd88ee1eff41 +1206,f2550149919b0d5c +1207,5013c08f53a9b233 +1208,23df41af933b42e0 +1209,e0c2157b131b393f +1210,9d53f401bc176ae4 +1211,2be763838585e898 +1212,b6285934465314fb +1213,95b86c1ccf8a0592 +1214,3fee3b0f675e7009 +1215,8255b5b4ec6d0a16 +1216,44cdd67ace3a1a4e +1217,029dfcd989dd7daf +1218,cfc6a6426c56beb6 +1219,c7c9253d935c1b53 +1220,d3f28489f831bd69 +1221,31640202da5b10e8 +1222,313c07f02b6cc4e4 +1223,71e19ddc35c4b2c0 +1224,d1ef9477eb4e251a +1225,6a76a0ee79a82694 +1226,446ed51ee484039f +1227,41c64d2ca3f9e07a +1228,7cd00bc9185632c5 +1229,dcf9d260d4d3e6fd +1230,26d937bcc58395fb +1231,d5b48df514574c4a +1232,9520ac369c86b637 +1233,efc2427b0d749f36 +1234,290490249511bf76 +1235,743c23834e13e09f +1236,5c55526041527b02 +1237,29e63c41120c7b4c +1238,91e97f598aad126b +1239,589c6c6c64ae5350 +1240,2f895b7096fd0c08 +1241,3a9155a63f27ab49 +1242,8ad4e85e4aff276d +1243,04a8f2e839b53e6e +1244,34991a4fefb805af +1245,8c55d6c6392df617 +1246,8135c23954f00ca3 +1247,e7b3de2e90995fc2 +1248,b6abf9a104b4b56c +1249,0d3188d5b7098f93 +1250,28fb0036d312b23d +1251,a493a61b2af5bca1 +1252,0db961d7a669b03a +1253,f1ca81eabbbd3063 +1254,99d6c80b7e3a2110 +1255,d7029be4f07c737d +1256,9ccb9fae6ad7b036 +1257,8d05f288078ac8fb +1258,c010a3bb5303a367 +1259,72f1aa685840aa35 +1260,cb1cf87cb39c2756 +1261,14b16d65d9bef1ff +1262,8950e324f2053e0e +1263,171e470af8e6a52d +1264,69d813614f36ed59 +1265,5888795343435be3 +1266,4636e3af530ce1b7 +1267,e91204f3072e59d0 +1268,6973b3f68673ba01 +1269,0c22d0406c497286 +1270,83eb71e481466a7d +1271,a14e1e341d46f33b +1272,2fa4758f8624af22 +1273,104978d0c56fa87a +1274,5781d744bfd6e087 +1275,87741b9f28ccd4ca +1276,755ff5406e4058a8 +1277,19f2d908302d5ddc +1278,9b12d26a4c087a94 +1279,e21ec430e8b57dd2 +1280,e21deedec6a6cfc9 +1281,136e4f22e2715eb4 +1282,7bb8dc3879006cff +1283,6d0a257363a4a472 +1284,d9a41b22192f8c89 +1285,b8ba9f58b7da7d59 +1286,ea9e14dbfdba0177 +1287,005787eeab7c28c1 +1288,7d5fdda0faa1de10 +1289,7447d2876e959bee +1290,4fe8bbc759a0087b +1291,26718a5aa4776d84 +1292,6c6933b0a62fcefa +1293,2ef9edd49ee7be4b +1294,cb8af5d93b999cd9 +1295,f7ae79ba36c15484 +1296,4b3e7f220d0e0b3b +1297,03a84efea5675a59 +1298,de9a9d7b21040bc8 +1299,b0e017c8e9fdfbfe +1300,fa4bed9336616249 +1301,ddbc7a7af46d647c +1302,dc8819998377bd72 +1303,5a2a7ad3013d7368 +1304,9c911b3838a624ad +1305,bc24a60bfbad2cf0 +1306,2398de359896ba87 +1307,4c1e6884ddf0878a +1308,85353cf5541af907 +1309,81a8ddf5bb431cda +1310,e8ec21f256cc2288 +1311,dce93da8d5831ea9 +1312,350eb3145f3b007d +1313,f4f0bf3542aeb357 +1314,63ae0bbbf8200ee8 +1315,fa6a0d7d54023fb9 +1316,8ad112ae7760e82a +1317,56b9382047e9914b +1318,545947e06efa5d20 +1319,f54c6ec6d2464a1d +1320,db0d9bb91cbada77 +1321,db56b1742d18eeec +1322,6635494ebd86a87f +1323,4b0a34e49079579a +1324,46a8302c34568009 +1325,b0827aa13b55166f +1326,a848db03b6740735 +1327,e8a35081c89eb273 +1328,6902a1fb7019d22b +1329,020528e991eae911 +1330,517a2b3e6ba19acf +1331,95379afe12146244 +1332,871e8a80d812d792 +1333,c75adb343ddb8fad +1334,dcf5a5ed302a2966 +1335,a5ffce6325cb918d +1336,ca55ada1cdfbe7ee +1337,55f52206126caf33 +1338,170d9f96ec8f0263 +1339,52eabe089cc83596 +1340,31376a660e879516 +1341,8d911a027ff4f31a +1342,54f10e9fd91d545c +1343,c813b5f7be127ae5 +1344,c3fcde773e85232a +1345,a1e7e3a8e039be1f +1346,f2344fa25d5f215d +1347,4f2c1251cda8b016 +1348,794fa681ac9b0c80 +1349,01d433802db8a0d8 +1350,ee4f810666b15ecf +1351,5db4d229b98b2825 +1352,f79b35f6221f9c41 +1353,befe6047552e7342 +1354,5f5ac332b55caa48 +1355,22979c9b9fccc55d +1356,fbbe044e58453459 +1357,f50919845ebed6d3 +1358,df7ab72f68ea5c65 +1359,d9663cf4817eff00 +1360,dbe5e7b5d7b57782 +1361,cd90db32f211161c +1362,f069fb65533f3f55 +1363,59ba5d99cc182e55 +1364,6d2e82602982d8d2 +1365,63ca6481c34165d6 +1366,13060fcaa3ae992c +1367,26a51f8b9b0906ce +1368,d7d0696f0994bef0 +1369,9081788c5b59b44d +1370,938009b4dd9fe04b +1371,9ce3fca8d1943a3c +1372,cd8dd66eef7c25bd +1373,7665749bc8df84ca +1374,84197439eec83c92 +1375,7714a0b0b6774b1e +1376,a5510f93ec57f6dc +1377,f2aafbd1b1093f5b +1378,040c59522362e9ad +1379,80a3e65000fafec5 +1380,7825d623905651f4 +1381,5a271a0e8f883cc1 +1382,8f91baf5bd9cc47c +1383,61998388aee152e3 +1384,7ff7c816ac38fee1 +1385,635040f71d21d672 +1386,7c8c805ff63d3885 +1387,954afa066f8bbc21 +1388,f505d58b6ac185f5 +1389,75681c64da785254 +1390,36d204d9a7343fd7 +1391,824d0af5177d7cec +1392,063f068ffd0f53b1 +1393,a9d54db75efa89f1 +1394,cfaa258360c9d650 +1395,66149f1df9c44175 +1396,3f30eec83ef8eec4 +1397,5c532d1c0a229668 +1398,1fe2ef04d137ed41 +1399,3bb14b8ca026b8fa +1400,2d2e75adcf3a9637 +1401,6d1d3a7a42a34bd1 +1402,af7307e4e78d1c61 +1403,5d5528ba14473112 +1404,3efa5866bba2b8c1 +1405,4010668e4837c307 +1406,105031c4ce58082c +1407,28652126744c0abd +1408,ad8068b6122b05a5 +1409,98bf41a48690e272 +1410,94d7a6d74ba80bb9 +1411,03819d62503d41ea +1412,b8f4397cb218166a +1413,54311ae0c28b55a2 +1414,62795e0df4635601 +1415,e6de212e4905aad7 +1416,6753f0123e91cb10 +1417,96ab91238bd40ac3 +1418,7f1de817d517be6d +1419,ad3aff3d9688958a +1420,564f67eb414b1425 +1421,a438c46fce193473 +1422,c8412b0fd59cb173 +1423,f2bb30cd70d02786 +1424,0900e54908124581 +1425,7bf7db445470f987 +1426,d79c74395e9c9089 +1427,303a71b5a3c0b247 +1428,33e20290d5fb9598 +1429,eb5a911e02675c47 +1430,d94d1e5279282e4a +1431,1f905bfefc3fc029 +1432,0951df4e6f52889d +1433,1d807c0de4e82cf2 +1434,afc00c2d9dfe3ae3 +1435,5c4d0ddd96d3bea4 +1436,241a0c05af7482e7 +1437,0fce040a3edc6243 +1438,a2bd37709e265490 +1439,3597d5a23d452219 +1440,68e7768af7ac038b +1441,851245be79f906d6 +1442,576725a84c304107 +1443,f4834317048bda2d +1444,bedbf0c2e854a583 +1445,2d3239f288fc7ef3 +1446,f6e438d8dce1ffcd +1447,aea3396b559d963b +1448,605d81799a34885b +1449,95400fbd5e326b6a +1450,61742efc01bf1345 +1451,32b25cf7a2ea3acc +1452,2bcdcd1374ee7674 +1453,d9de003dda29de7e +1454,1b999e3d60fcf207 +1455,0f9681ef36bfe795 +1456,76d292f112a6cda0 +1457,8ff313343d417281 +1458,0acce363665fe99f +1459,9743149be0ba6804 +1460,632baddac8f26521 +1461,061a31e11eb96c7a +1462,febee73425b1a201 +1463,99c40624c6ef2025 +1464,d27e0e2e2a062a32 +1465,f921c6ccb8c9ab35 +1466,8ff9446b2279cb9c +1467,a82949106bd58bb7 +1468,3d1b94f4c7cb7657 +1469,eb11eb9bbcb290f2 +1470,d9538e203efc7749 +1471,00b4ae6a1bd5859e +1472,9f10ad66ccb82b97 +1473,6e9fc04a740fac9e +1474,fe3e2728a709664f +1475,5863f206977eabb4 +1476,20162479dc2a04dd +1477,2d309dbe5d0483f7 +1478,9eda7e7c345de73e +1479,d8a34df64d7402a2 +1480,4e3588ddbaa51c71 +1481,dab825e2a443e9c2 +1482,f5bf6f8939e4b11e +1483,c3f252ab9eae7925 +1484,5452e1362ca53498 +1485,0370928c30eb15b9 +1486,eedbb2b9731c9af4 +1487,6338598c1a983480 +1488,3ad40446978c9aa1 +1489,eae5685f1c9db95c +1490,82e7af65a8d35342 +1491,097609c88904743d +1492,e4f537643ffc82ef +1493,373c8b4ec2c5eedf +1494,849c635a3f7e2498 +1495,d5db1cd16423ab65 +1496,7cbd4cfbf3b009ab +1497,084dd43c4c76b574 +1498,c26579eed4831efd +1499,49e538c74ba61bf0 +1500,1031d7d882441ba7 +1501,039c0a64cdbd50c5 +1502,cca2b813022408ec +1503,bf2af8dd371b5fef +1504,bd3404ccf717a26f +1505,7e1612f335cdaaf8 +1506,8f7e4cf2789d410a +1507,c7b433b20262acf1 +1508,ca9fe0e88470260b +1509,7cef3eaa17a8ad66 +1510,3859ad04318e053a +1511,6d47dea2fbf9c047 +1512,27b158377109d856 +1513,96afa3fa3d22d281 +1514,bf01c74d69f82be6 +1515,ee7c0c122f511ccf +1516,9e94ea84abf7d9cd +1517,3fbe3b42f59b668b +1518,ded530575f7b2f3b +1519,4f78bf6528f382be +1520,be4514800bffdb59 +1521,5c8c73c1bbdc3f4e +1522,0e465952faec37c0 +1523,3f5c5385933c1729 +1524,ba81fa81d231c3fd +1525,6cde3802f91e208f +1526,f2f061eb9c28bde3 +1527,81c7ae8b146707ec +1528,3b7ac95aca87f7f5 +1529,0d9ad577d2a73119 +1530,d9373de742f5c8f1 +1531,5e725800f6144e2c +1532,62b41840ae2e6d00 +1533,bc778d86c7e2b843 +1534,b83d7101c27dd505 +1535,7bbf19f9a90ae465 +1536,625d0dc2003c1fed +1537,1de460a1310a3950 +1538,52bc337c3f11828c +1539,21901f1ef98a276c +1540,3315c1c034dcb376 +1541,21adbdd1a1d91711 +1542,f1cb728205de83c8 +1543,1992230b2aa55392 +1544,3c62a3946a9eb604 +1545,cf019136855b07b4 +1546,ef12be4e351ee89f +1547,d46553adf47dc86d +1548,b2e82143fcda2fd2 +1549,f692f047a546c5ea +1550,f30d027b5f9916b5 +1551,461747f0dc5991c9 +1552,e9f63399e4807b3f +1553,2a8ed5355d755dea +1554,e631a58f55488209 +1555,00c8c12696ce44f5 +1556,2b73aea7cc2ee554 +1557,d9adc441ad5951b8 +1558,797dcf09d993f747 +1559,06865eb0d4c4bf3b +1560,a9e4087b60ca09c4 +1561,7c729c6bcebf73c7 +1562,b71af8a6c2fe3bda +1563,f8d39d439b8666d7 +1564,d7d80d6564999373 +1565,eeb83c2a1a14fe26 +1566,4bf97d2242186dd9 +1567,83286ca1d348dd14 +1568,a1a30b759d4c80d1 +1569,4d17dcd15fb1e21c +1570,ea4adeb5a90a1d4a +1571,bf5129b12a5ba032 +1572,2d20d57572801029 +1573,5320423b20e7da50 +1574,07f19e634c02f0f5 +1575,a71c213dce720fef +1576,468d6beb74c14501 +1577,16958b2379264426 +1578,51859f2901202fc5 +1579,9cffe569c71665f1 +1580,a15a9aa0f2142cd0 +1581,c214981cdd4b55d7 +1582,0ee81e57f7153e36 +1583,1b1230059941ab62 +1584,da91296ba9a51de6 +1585,42faf6095546cd79 +1586,a45793acf462a428 +1587,a9fb4d565c889909 +1588,e155f64ec0b069d4 +1589,6aee942603b8e68f +1590,32e047a093cf3690 +1591,6156eb2ea110756b +1592,6982da80b9a1a81d +1593,24c9c1a23872f387 +1594,3ee033dc14713dee +1595,72b1aa9312db1d89 +1596,86de550a821005eb +1597,937855f6a93d44a7 +1598,57f83a401658729f +1599,29b3678bf079eeef +1600,3b0cde63ab13de56 +1601,e9a112a3f904859e +1602,3f913502e7acbc5d +1603,856ca28ac53edbf2 +1604,663ef61e6e42ced4 +1605,3c58aff2e7e747b4 +1606,51f52a049b7a5668 +1607,552533677436491a +1608,c3f579168c2657f3 +1609,ff1ac3d69d93fd82 +1610,8e413f36a8e356b2 +1611,bb6b0c51ada9dcde +1612,abc123c635d34595 +1613,58670deb46516064 +1614,fcf4d5074c8ad61b +1615,43fe2e61f5af09e1 +1616,0742e15935525a4d +1617,e71b521d496b48da +1618,a195b4b3069cb087 +1619,3e45369ef2d01ee8 +1620,895ecb37fb821da9 +1621,b950395acaa2b318 +1622,9b15771765220dc7 +1623,b1d3cddaddab5ede +1624,aa7ed31d030962a5 +1625,3477458c826781f2 +1626,bd3f3b41014a37c1 +1627,60a145cb42541e91 +1628,402ab15a751e38b7 +1629,20f10601c2436b0f +1630,64f1c8e927f7b392 +1631,a725b036088a7770 +1632,aaea7f3bddf94f9e +1633,8142f6a96d13658a +1634,24d6d127ee54d32a +1635,13e7f5842029b7d9 +1636,0521176a2b1c26b7 +1637,c10137148c97d1ce +1638,fd0c45cb36528792 +1639,3b4a63dde8900fd5 +1640,5de257bb27883216 +1641,c8b6ded4edaca7c2 +1642,462ac5f7e54da4f9 +1643,1849ac7a23a44d9f +1644,629dfca187d66b4e +1645,70a76274ae3ccafb +1646,22ec11b8b8d9ee2f +1647,3db894929eaeb28e +1648,62db69c4171d675c +1649,06254761cb5b5ef1 +1650,69e801e9552bccc2 +1651,36c164e690f67db6 +1652,9e0018b1551a2f00 +1653,21009752b932572d +1654,595ff4918c21547b +1655,693070c180df2134 +1656,fb15bd4c53b7da3e +1657,5dc0eec034174b1a +1658,98fbc1d311f161cd +1659,a05f1503d2766524 +1660,e1e5645569a70253 +1661,08f7129285b3e071 +1662,529d523086cb06f6 +1663,38c5d5ed1bf49050 +1664,6412d5f6b0db0a1b +1665,d540dfcc00336295 +1666,c546106ced064b02 +1667,2bab046a5c777bb5 +1668,1cbbc63813564389 +1669,4b3b10161ca193fa +1670,d981b3946a66208b +1671,19ff945a74b99bee +1672,356278dc75aa30de +1673,885c4d54ecfa4f78 +1674,3abac705b4c11f43 +1675,6e46fc57df24ba4f +1676,4217cba0fba6650a +1677,ee0b0cd884e67428 +1678,eff5cd6683affbd6 +1679,0eeda31cffec5c71 +1680,088124383888a3f3 +1681,210735c5b73c0ae1 +1682,fad437a15493948d +1683,34f3a42ed74b7d4e +1684,421ffc12e795155f +1685,7409ddd854a90aaf +1686,5e4027d9d13dd23f +1687,30a41fed0d82430e +1688,7ecbbdb1ff46ba55 +1689,d9882f799731978b +1690,f721c11ac2c470f4 +1691,fd8f6508a877f73e +1692,4a3f93c56b7a72b4 +1693,ff3c9865d1df8ff8 +1694,6a5329b933750f58 +1695,e80bce42f36a2688 +1696,22ef33a5092d441e +1697,d4b677d6ec8abfc4 +1698,92b3ca6262d7352a +1699,4202e4b4de6ed712 +1700,e5b96fc57e0cc2b5 +1701,69f2650f0f319c0e +1702,0dadd3e403f772cc +1703,aefe142eb1eeb0e0 +1704,a3954f48aa2fbae5 +1705,52d548b113a1433b +1706,44a8310672841009 +1707,a7113ccf690dfbeb +1708,d9eab9bef6bd7200 +1709,8088a093df834ee8 +1710,6f73ff646ee30aca +1711,bb3b9de6097f7758 +1712,6bfb4b9cfa72c6ed +1713,b70db1a9acc500e1 +1714,a63cd4dc5ead9ae4 +1715,b771b20cfb27c92f +1716,c7bed5c2a0d929fa +1717,b6081dd692c709a6 +1718,60ba243a8f7bfa64 +1719,9e881e25ee8de50a +1720,48ebbfe0a8af2d49 +1721,c35c298cc1932763 +1722,3fd272b8e72b0e9b +1723,d8753c3a5b743a44 +1724,7b45d01eb8a7b61e +1725,9d96635a92fdeb36 +1726,6ac6eebc6ca8f4eb +1727,a0e9ba47de5c0b60 +1728,9eba57e483846b5c +1729,0c56ea92a2fc0bce +1730,20c402ca6d4b208a +1731,f80e6ad1be2d79ca +1732,4ce3299453f3e40e +1733,e1df67f37e72a2b8 +1734,dcb2268ed0fbabb8 +1735,d7396b6a5eb4e4fb +1736,dd9cd90b5a28358b +1737,92ecce436478c82a +1738,51cb40995ea9e123 +1739,0375be974e4357b1 +1740,2c5a13bc3d1159dd +1741,028d7992ead89fff +1742,a670c1a37a721592 +1743,af2a5cb99c9672be +1744,41d3c571b700c7d8 +1745,055e37ce59fdf9a4 +1746,ee5ce46f41d1369e +1747,a985bd756f0f31a4 +1748,3eada1a48fa1c382 +1749,52e29e99daf4c83d +1750,16b03aa306858c2a +1751,c3427d6f8523db1f +1752,c0d7f73d194798b8 +1753,17eb276a2ae7c577 +1754,09ecf2d679073aff +1755,19b55b8f703bb767 +1756,45205224e53fbfe9 +1757,3b5996a823220a2a +1758,a730ae34aefa2062 +1759,8f344f4ce4483b4c +1760,49bd68deff04eb41 +1761,7da18964e288d352 +1762,4ff00f8e30ad5bbe +1763,e6a4a11b116838b2 +1764,3d3e1585f71248b6 +1765,3e3449d861817422 +1766,8d5880550040d252 +1767,6c8d6ae3e6a4183d +1768,87dea15f1350d70f +1769,e39fe85c87f0bdfe +1770,da2cbeb1bfcbe176 +1771,10b4bac6043d1d10 +1772,090812226dc209da +1773,349bd1f17a31c2b6 +1774,704a2535db23dbb5 +1775,2fc8aaffddfdd101 +1776,8f88bd65bd5d69f2 +1777,051782a1740411ae +1778,30efc4f44888bba6 +1779,811de9e3a9e71925 +1780,ab61cbb6271a4f51 +1781,b160eb461b13962f +1782,8048fe0f39fa5f5f +1783,99ad33489945b5eb +1784,20b1b44b28f537e6 +1785,017e04237ff77227 +1786,2ab2f4483db1ed32 +1787,3ade24f8f6cc9372 +1788,fe0ae99dd99b963c +1789,74b40c67c0b5efa0 +1790,0bc851a625578ba4 +1791,3db7a59ffd7f4966 +1792,76fac8a33f4bf3f7 +1793,bb257c27d4ad408e +1794,7d45a70bae0ba4ea +1795,41956c45c4172723 +1796,42622a0e195f1f23 +1797,61d2cf5c1b91493a +1798,76f44bb4f53fb19f +1799,1ead525681a69595 +1800,4af5ecac0f468eff +1801,f8029a54397a4738 +1802,1c25b92f0bab78f9 +1803,28b2e1dd1a80fcd3 +1804,4f4f57da65274f3e +1805,a53ddc14aa3bc8ec +1806,3f8fefc1a4bac3d9 +1807,f505f5cec7e77007 +1808,f91e7fc2f418091b +1809,fd99f363ae4d4628 +1810,826292f3a413d614 +1811,3002da3892fd2109 +1812,a75e21a4a7c560e9 +1813,0c2bc0e109335fd1 +1814,c6a0d43f3d1c2404 +1815,ac1371c15836bb3a +1816,1af53010c9224db9 +1817,8f00d2c16f4bc5a1 +1818,ef38971f04a98268 +1819,223d791d4df55d7d +1820,0d2bd4472ae9c688 +1821,440d9692993df7a4 +1822,d773eb4d1fe8cede +1823,c6ad4e08af5e638b +1824,74bdd13ed3f8b978 +1825,29d60d3d44caca88 +1826,7641790582ffb2be +1827,361c47112d8396d9 +1828,98aa790be1d824fb +1829,6c8b66c4fa039718 +1830,cb8ffd5bac2ec395 +1831,80642e6f2f2f0eb4 +1832,245a6ae5c5280f3e +1833,f9f3c4a5933f67cb +1834,82187577ba047026 +1835,fa230ec26947adb0 +1836,089da104e209141d +1837,d17153b747d207dc +1838,ed74205de5f62847 +1839,63700e1b809d762e +1840,081d0c6bcb84a0d6 +1841,3014dfbbfbd20205 +1842,f376d8f94a8d7323 +1843,05506880ac7f34ed +1844,afeb9ca3a9b92233 +1845,6fa83be7839e6068 +1846,d9637365885936c1 +1847,e0dcc87b9b76f542 +1848,d07b1fc55e7016d8 +1849,a0723ed341f01da9 +1850,635181feac88f1dc +1851,3e8066a6fd76f6af +1852,df1292750d010716 +1853,738460999ba0493d +1854,b344e336bdd1d0ba +1855,17dc3da7af665e4e +1856,7190f733d9c5ff57 +1857,863af6144badc24e +1858,a610635b52123336 +1859,a3fae2e30d19430d +1860,df5a9f659eb92afe +1861,9a9faea370e5947d +1862,eeb1b100e27f7fe9 +1863,6bfa285cb1005d1d +1864,00dad18332112e94 +1865,ed80b63bc08fde9b +1866,3452e31b144e79c7 +1867,f3960cdf6d003011 +1868,dbdef53fadf8e4a8 +1869,f99f2adcd9e0b6c9 +1870,0da9d125e5dda9fe +1871,14f5011aa4fead63 +1872,a6413e738ce44852 +1873,697ad2ac23a3c7f2 +1874,015d0e8edb27d255 +1875,0153980fdec39088 +1876,d8d91bc93b40869c +1877,6a865fc802c5e1ad +1878,8cfe44b17595b669 +1879,680b3f32bfbefe37 +1880,a8b5f4ba92f2b5cd +1881,ca2f558c091cd635 +1882,bc6b03d7b8b357f6 +1883,706f0115a13f1b81 +1884,06ed830c73f00069 +1885,7fafb1603a5cd78d +1886,0dccc11bdb4201d1 +1887,8ed37799afe2a69d +1888,a1cbd56dcdd2a2eb +1889,87f29838afb66f6d +1890,1c541e7cd5ffed79 +1891,c9e6cfd5ef7ae234 +1892,bd6a3e579955fabd +1893,113a0bc5e1182499 +1894,c2e12ecc5290f1f4 +1895,e741cbd437589739 +1896,1c43c4ff5f3e6d58 +1897,40a84c21fd868a47 +1898,4f0418c2ab7e89a2 +1899,48aabe934bbd7e55 +1900,bf1cdf9dd19be4c3 +1901,14066f903494264f +1902,127e73765347e4ff +1903,71c4217565a55a7a +1904,18aeb501c303d29c +1905,b024aa26acba9034 +1906,1d61476694ced78f +1907,60642a700f14f3bb +1908,7c64ba52b0ab9f89 +1909,35683472ca1cf1d5 +1910,231ad841b1ae0655 +1911,86393e1eb819c08e +1912,b79e52409f0ecb94 +1913,6d8e152dc1fa60e9 +1914,c68911439c800d21 +1915,ef9e1ed2ee919dfd +1916,a4c5c1ba0be3fe0c +1917,4cf1c103e0adb841 +1918,d6d2574f5e7273bb +1919,fc326d18cbc18c47 +1920,85d01dbce4ec9f3c +1921,c452e186985b2957 +1922,cd778e5397e3851f +1923,8b52e665e644bf82 +1924,7bccb3fa72537b5b +1925,2d4359d8549d690d +1926,bf0b0c584e9ea28f +1927,09f6f6f6b8a50727 +1928,aef7c4f00ac118e5 +1929,fc2795ecf20b10e9 +1930,1c390da5ff546489 +1931,5d8a4de417b5c632 +1932,d00b3fd7c1df6c41 +1933,012f7b51c6e8aa3f +1934,7cb22eceff6a633c +1935,af622e4a8c93e33b +1936,f6e3daa1e8bc22fa +1937,3d2eeb25b2913df1 +1938,9c61dbe4a1ee779b +1939,591960f8713c6bcb +1940,e8050777aa5f502f +1941,4293c9acce389df2 +1942,9c9ee1f982460253 +1943,ae39a07a84ba82f7 +1944,0c7448898c0b28d6 +1945,81d40c7828ed4c42 +1946,3d47c02eccf173f1 +1947,148ca8467711af8d +1948,2e797d4765ea175e +1949,f6b289652837f592 +1950,8364e18be58f7281 +1951,70b477a74d7272f3 +1952,29b489c7ee729e24 +1953,6e724978ab7d1179 +1954,79691b1bf5136360 +1955,0c55706e736d6e8e +1956,55316073f19711c6 +1957,58fe33dd9419f361 +1958,53c5a7081b547b89 +1959,0206b3da435588d0 +1960,2bed1dec4e6e4d10 +1961,bad2623f64e518db +1962,8faeae526a25bb31 +1963,4225ed584622a0b3 +1964,6ba7dfe296127bde +1965,dd4f9d9a84db0a2b +1966,1635de322ef14f44 +1967,d099ba2c3840df71 +1968,d0aed30572bc434f +1969,64396dac1ae6cc5b +1970,77898b3ea5d047bf +1971,ea4536de5683d7fb +1972,b80f95173c9f2689 +1973,03cc37bbba2d7aa9 +1974,90b83c7de997b81a +1975,5923b4cd1f26bb98 +1976,486666404a49acd3 +1977,7d354d1a2f8c86ea +1978,5c821f9f7f9d4f8e +1979,fb65a777e1f6ad73 +1980,2a1bcb144859bf48 +1981,671ee69016b018d8 +1982,c18f7e1bec7089a5 +1983,4dbebf18a4f40f82 +1984,2dedc0382e76d46e +1985,50cc60f13a83336a +1986,80cd620ef7a1cb46 +1987,105ebd021b515bc5 +1988,fafc83fbf4505983 +1989,433ddbfe12e21d38 +1990,44ccd15f70e55752 +1991,232367ed37b7857d +1992,bed9579e40a980f1 +1993,cea7080cdbd9ef22 +1994,5e451cff9b3fe03c +1995,5fc6733fa2b9aeda +1996,fd4a397292a680dc +1997,d4da96c37652d029 +1998,c4ec45a5fb6ce670 +1999,9d0102cf5199d89d +2000,08920ae76c0d388e +2001,85d7d685b185c4ae +2002,67eab4f523ea2253 +2003,cc869ec7dc35eba9 +2004,66222fecb37cadf8 +2005,24a199b538945004 +2006,188f20c98b98a8d8 +2007,947e310ab1dfe809 +2008,9a64ccf8ef7e8cab +2009,d41137c196837339 +2010,5855869ca17491ae +2011,442b86e5f5cf2334 +2012,b9c630aa34bf34df +2013,fd42af1e5f781886 +2014,34b86752545d42a2 +2015,6e34b39bcca9c3e1 +2016,874f998a75768041 +2017,c99da02357650a7d +2018,a9b6ba3a969e354c +2019,0d74f29dfa369d4b +2020,71b7e5d983d1f854 +2021,2d41fb21747cb4c2 +2022,b641521c605e3d99 +2023,92d00cfcd669e67d +2024,8c45e438e2b783ec +2025,fead78d3c59d1644 +2026,b985267309252cad +2027,d0734cf67310922f +2028,91756214883e1db5 +2029,248fe35f800a0862 +2030,a2089498c6765759 +2031,7ec512712f703702 +2032,9d5b9a562be196a7 +2033,b7074a9530e3fb5e +2034,05286259aa2b9a64 +2035,0d3bff0233feaf21 +2036,eaf1ef7a27078295 +2037,9ad679c16018af49 +2038,4f789ccfb5122db2 +2039,4956a9d7bf2c505a +2040,af906af3a6657f8a +2041,4e43b173a5fa335f +2042,d7c4b97c8a475f91 +2043,396350b5269477de +2044,814e59526bfe8dbd +2045,68536cb8beae1638 +2046,3d2d929119c44f75 +2047,3706db0e9d5744ea +2048,b03f1fd34adcd3d0 +2049,d62db9d0814d0a94 +2050,8925ceff77ea4c24 +2051,086e531d699bf846 +2052,8fee2190ba6e3e81 +2053,f79912721d285e7f +2054,5d05f196afe78096 +2055,f2c916027df9b4fe +2056,e546e0ee62bca97d +2057,1964592bdd4ef0f8 +2058,276a8de914355999 +2059,79da56c217023b6c +2060,a7bf025c6f1b49dc +2061,9675c9b04b06e164 +2062,3a240f0f57b36aee +2063,903c7fac43418793 +2064,6193d48c94e96522 +2065,4b63d06bb551dc6b +2066,769c045a9bf4fb27 +2067,15e843f76f63e24e +2068,58a4e0ebb1cdbaf8 +2069,5db99f9dbedd2dd7 +2070,91533932e5bce03c +2071,70b64417a4226087 +2072,7f08a23248fe4c91 +2073,023cf28abb0815be +2074,392c7809001cee6b +2075,e998e780b2d26e62 +2076,20ead26d617b34db +2077,c3398764782e826b +2078,c650b642a1a8086b +2079,2cb78300ee6dd58a +2080,b5d89ec6f342f9e0 +2081,77ae148e43714250 +2082,3c8b28ee1ea5569b +2083,dadb3c662f01596c +2084,7dda443610a27c80 +2085,70c0f8a78c689d91 +2086,fb1c72246a3e2129 +2087,bdf8ea6217e494e8 +2088,deac45c0ed7baa99 +2089,9f629c60a0adbec3 +2090,32b439932b18a7da +2091,8fb5972cc1aced2b +2092,6b8037f22414c9a0 +2093,91069bc025b47b77 +2094,97afffa103c50de6 +2095,3edcc1079f448910 +2096,87b958ced25b9871 +2097,fc8267d5018a92c9 +2098,7a09901c97be77f6 +2099,6bc7434164b4234b +2100,4a83167e5bf5c4c6 +2101,de8167a9cdce97ed +2102,7876521d92eed821 +2103,af41bdfae22e6948 +2104,7239de110b6c8726 +2105,b24c484536744558 +2106,ca88446a7980f094 +2107,3f97b6e488e6635f +2108,21065fef60829af6 +2109,d50f01009409cabf +2110,6d09b474d6cef8a8 +2111,65a51822dd82744d +2112,5d5cd5f37743f034 +2113,cef09108b400d21d +2114,91512f34f8239ada +2115,efaf27d123e8a81b +2116,6cc870371623e495 +2117,e75f3220f66abfd9 +2118,9b5ffb13e880ce55 +2119,fcfeb1c3f3e3eee6 +2120,ba452a7d7a58559f +2121,2ea9af9566c50595 +2122,16f3f2912cba9492 +2123,bbdc89807d75dd99 +2124,5902e9305af4f05b +2125,4c0baba52d33d73a +2126,c96e7b2101e0a5b3 +2127,79f8a9be31f81c32 +2128,b6e3b8fc82f6d510 +2129,ccf917db55b7010d +2130,b969da0940410128 +2131,b6583fbdb52fa9e2 +2132,e5da8112c7627a1d +2133,5720053c5d6eac24 +2134,e2b883144432b3b7 +2135,0d8ba2f2b6780f14 +2136,e0abb74e8bcdda26 +2137,dbf39cdf83c25881 +2138,9aaa2d06a792d5a5 +2139,c2e6326d4ba977cc +2140,ef1de8d4da602c95 +2141,269e468fbaf75029 +2142,ab33a8a851ca41cd +2143,d93a924c88678b20 +2144,71d21841c6726879 +2145,f5022e933396d366 +2146,d1e747d3f937e774 +2147,bfd54533c40a9ec0 +2148,f772ed13ee619674 +2149,d8102dd268efdd6c +2150,be587665c7caec0b +2151,31aa9eaf01917f9a +2152,bf1413e172c9032b +2153,e12c29cda40098a9 +2154,6454c49f31f1a084 +2155,9367eac4605a5404 +2156,5aca5ca0a727bc14 +2157,338c20143d4cfa01 +2158,c6d9a14094a96ce7 +2159,baac995a8f4751a3 +2160,c7b60e58bf5b7f04 +2161,4cf709c85f1e4735 +2162,37eab6726fd50074 +2163,8e4fb1274c64560e +2164,613910d71bce053f +2165,cea8bb5c95324c38 +2166,a3183db08d27558c +2167,ee94d978cf5a4697 +2168,abe8afb069db2330 +2169,1836132cd871e925 +2170,1328487a2e175a1e +2171,989b799e2901fbd0 +2172,716e7c30a2b869d3 +2173,164104a7ea6b5c7b +2174,bf4e529feccf0914 +2175,500a4a4dc638f145 +2176,cb8499e8065f269d +2177,6a4e85cedfad8d17 +2178,872d2831ea35904f +2179,032ab85ffa936014 +2180,51c41c4ea2f25337 +2181,434b1f12f8ede286 +2182,e4ffafae76e415a9 +2183,e5b40642d14c20fa +2184,7bf7d0094405555f +2185,2e3a26c1a998910b +2186,3aa22267e6730277 +2187,f0e79f2a88d311d9 +2188,f66f1da70458bf1d +2189,e424bdbc5ee8f410 +2190,4e7caf7bdc00e8a7 +2191,fb625f7047c0ae4b +2192,719d6940dc993710 +2193,ac06bea142e45ff1 +2194,ce0b97ad11ec0ccf +2195,a8152a881c04244e +2196,c39b7275d9faa25c +2197,3990b48c4dc6e431 +2198,615894e99a6472de +2199,a84d06fe2b3a6616 +2200,8e6ad8b2a06cd43d +2201,642b42b1f9cbc0aa +2202,945b23bb391a0fe7 +2203,27118e257bc98197 +2204,69fe8319b7aa0cb2 +2205,611b699a2aa72214 +2206,e7f734582b10a5bf +2207,2275dda228db413a +2208,be907db112b987ba +2209,afac234e41bb4fbd +2210,ad1b6d25170705ea +2211,95642183d253d2ef +2212,b35b66f86928303e +2213,d4eca07461a15ac2 +2214,24142f9b084e49c2 +2215,f75b6ff4480e9c60 +2216,044f8c7ab058ac53 +2217,93965a7ab5047555 +2218,9189c13741369941 +2219,617c485121ec6a32 +2220,78a72c6e3a061ed7 +2221,2c1b488eab78fe88 +2222,56ac83f21bef18f5 +2223,cc830a0328e8b254 +2224,2af48c58c410c01a +2225,81d63e8f2bbb33f2 +2226,18dd18b00db0a66c +2227,429f4eb360706e5b +2228,27b354134953e80c +2229,418440a3d85a0331 +2230,1b2868752e47bfe6 +2231,00cdbc5cac96b75e +2232,1a8813f12f950beb +2233,d7668430a956d9c5 +2234,bf2591c75441e409 +2235,e70d790c52fe0723 +2236,251bd20421ce8441 +2237,adf7ac4329835c7f +2238,23ca420d2ec5693f +2239,ef8fba68a1cba342 +2240,178f043c6e8fb9bf +2241,c0d63d0c20915e35 +2242,57191f43dc1270f2 +2243,bfe6096713ea0c4e +2244,39cb249f1c2afddd +2245,cf1a1805483b6340 +2246,464f509f49e60072 +2247,8140e74be6a18d26 +2248,27621868e4c4b571 +2249,01df7b568948f062 +2250,a0c4ee88f6319ff4 +2251,c86f3d9e269b6512 +2252,a705cf1722e70b4e +2253,cd8138970d45d617 +2254,62baeb706a8262fa +2255,eeeecb44676420a6 +2256,922bf177137d902d +2257,5a7ea310ce0705cf +2258,114addbb43159689 +2259,4aaffad05a856257 +2260,45b9c1e9659f1d86 +2261,c5640c444b01938d +2262,29149f34b6322721 +2263,4c031551a000b159 +2264,f6ac790c1ed639fb +2265,6582e60d377fec87 +2266,22e110b030f65698 +2267,49611594b07d27b9 +2268,3fc99a8c28a34b19 +2269,4aad3b7e5f2a8597 +2270,219f31b06738adc6 +2271,ebfaebe2e0ddac05 +2272,7128d279d359e6e9 +2273,8e3e352dc237dbc2 +2274,869c877bed309e1b +2275,6ea63f8f1baebf86 +2276,e993e6aa231db868 +2277,01182c154337efa5 +2278,c8b9a7574be7a11b +2279,5198b84dc810194d +2280,fb8f18a6ca326c46 +2281,de4285b1e28d940f +2282,ec2a005d9d59cc61 +2283,4211b353c53d83a6 +2284,f72966597c5729b4 +2285,ae5c7d4cd5f3b446 +2286,b5a0279debe88aa3 +2287,8e9e581e47638b0c +2288,dc8c3e71adef2fb7 +2289,5fab3143a429157b +2290,62112081e5aa2319 +2291,4ad440d46d83eb4c +2292,7604bc41c438c0d8 +2293,899d183b8bb5b585 +2294,bf833e34aa653be2 +2295,f80c0f4a3f5a83ff +2296,467e042b566673f4 +2297,ed3285953bf8a7a8 +2298,63f51a1cb92e9990 +2299,86df230be08d20bf +2300,ab8adaf1a41cd36f +2301,3afee56f306e1f22 +2302,9e6513a9f9b11a7f +2303,96d93e2d61413015 +2304,80ec7f9d20acda32 +2305,0b651e5584ec1eb4 +2306,7459cbb40af28681 +2307,ccc0295a25c804eb +2308,ee893cbd7a47a539 +2309,eeb4a7d1287636bf +2310,1965d5a9ebca0cc4 +2311,8b04cf568be4ffac +2312,cc44f33231ba377c +2313,6acc3c932cde3c6f +2314,ba401b7b026b06a5 +2315,1cc282fc0f4486b2 +2316,44162ab13df7fe97 +2317,3de7aa788164e9b2 +2318,f2ed19c498dd0a66 +2319,df4c850a6ca23407 +2320,7d95af70a00bf2a8 +2321,ce3fe4072c73c2b2 +2322,5c2f35ac7ba9e416 +2323,ff09aa85510099ca +2324,88342933f8af62f2 +2325,d0b06e85d200a29e +2326,4c52b820cb225f9d +2327,7022caee09c3ec15 +2328,969a353a756f8a1e +2329,b57b9dd14093a29a +2330,b9ed9bc49e56303b +2331,7e51e4e79cbdb9cf +2332,67b3010fe93d63b6 +2333,5276487613643ffb +2334,d609f779e04108bf +2335,68735168b051bd5b +2336,0e272abb8eb03f5c +2337,c4095cef362fa601 +2338,78541d0739cc1f9c +2339,21819c7e02cf65a1 +2340,7912a8e02575abb1 +2341,45e69a721ea79410 +2342,717ed2e9711e2bc2 +2343,f1620322f1ca03fd +2344,fad231eb93576461 +2345,da6497bfcb709abe +2346,929e4b59bb6ecdb2 +2347,df6c35c720388f1a +2348,fb068db36561c0b6 +2349,205d17be8f5f821a +2350,1eaf7dfa12417f0e +2351,1a32f94d45f99277 +2352,986af74f3c02b8af +2353,3b5ae97902eafe4a +2354,c8db2512bafe38e3 +2355,51f51a95bfa7e08b +2356,e9d7ead4a386fdab +2357,8ede1af691c57d26 +2358,4bbefc42849f0a53 +2359,d6e462a1e4aa5483 +2360,6652ad5e6ab1db87 +2361,a8c7f2c812ff60db +2362,cf33f07e718ca881 +2363,9d81bfff7a46f7ad +2364,65577576d70f408c +2365,f957cacfbaad10f9 +2366,1053657f8d7d22c4 +2367,8de6c264ab4d450c +2368,8f521ef6602640a7 +2369,2d9d38b6c577a3f8 +2370,54fbac504bf494c0 +2371,a885e9be92d8aa59 +2372,deafa41cf35a4187 +2373,61336d566c4affdb +2374,7878c09f13136c63 +2375,a81fd10646381c9c +2376,9a7f7bff6ae64b06 +2377,889dac764f31c532 +2378,0b7fdda0628f3b75 +2379,84f589ad72a1297c +2380,1f7c5a2fb37ad9a5 +2381,999db7567f48cdd7 +2382,4d98623ca3f68a71 +2383,9918856c161d792f +2384,4957abffa10a3834 +2385,fc84c82c89c6f54d +2386,e377141378d129d7 +2387,434a43f1e235d7ff +2388,b09e485104e79263 +2389,450da690aae07b0e +2390,4f849d2df952282a +2391,e4e2e31a9c6437fb +2392,7730c43dd7ea47b8 +2393,7a2ae2e47abf998c +2394,fc6156f3f6011e91 +2395,0ffad6b6f8c5a84f +2396,4b66487617a5ef36 +2397,02a19313352992ca +2398,b7e45a47e796301d +2399,b3e25dbd51adaf0d +2400,2b0f2597a3a6f723 +2401,a94e47053a3e23d5 +2402,ecbac1bf58bb6db5 +2403,5ac34f8a7873ec79 +2404,d95d417285a934b0 +2405,e719dea19773c1ab +2406,f22a36832c8687e8 +2407,e3c9f24b1d34a18f +2408,1ff418000bdeeb4b +2409,e8502aeecb05ab92 +2410,99f3868e7d4bf339 +2411,b9503fd0d6433465 +2412,8bf28fb20b5743be +2413,293ea42a02970b55 +2414,87ebc0f49fea2f97 +2415,a5d3c02e548144d2 +2416,ad60b5128f9b8cc0 +2417,430f52a356fa80ba +2418,1b65e009db01f097 +2419,f34f0dcf6f3a5571 +2420,73fa27f21d274d4c +2421,d42dcb0cbd93e354 +2422,0cf20cb07e47cb57 +2423,be4f9e815ad50076 +2424,1a8bc927009faca9 +2425,edaf50fcf4c893ea +2426,a3fd14fe5a0e4b19 +2427,005839da79caf0a5 +2428,91c571442ca6bdca +2429,475582f1664417db +2430,211224cc68fc53f1 +2431,fdde438a2e7ccce4 +2432,96efa684a5ec0289 +2433,633e16e8589c8e79 +2434,62cf89081d4fb548 +2435,c4e2e5ffe6a0cdea +2436,5306bdc0fd269d12 +2437,cd4d0699f7b43d22 +2438,1454cd2528d4bb4a +2439,76c507be7f588b43 +2440,1ab81656750eed60 +2441,b26ec36ca96a6510 +2442,d0625d4061e6598b +2443,2d1e961ec65b7abc +2444,a1c2af78d1538d86 +2445,2ae27b69a03cb3f2 +2446,e7a812d623c5ba3e +2447,a69492c74114f254 +2448,de8eb3f31cec3202 +2449,36f6fb71f74f182f +2450,c64963b7c733b15e +2451,a1b20177975d57f2 +2452,aa777511824636cb +2453,f49df16648613204 +2454,04ad3af6bd21dd5f +2455,2e3032ecd14aff75 +2456,5acf8e6371a0278d +2457,fdb472c11b28c309 +2458,0475cb6f42d6dfe5 +2459,eb6f24ff6d623dd6 +2460,c59aebd2a2a742d8 +2461,3947b27eafcf0a37 +2462,aa3a2e701db013a7 +2463,25687593cf2baa3e +2464,67354c75cc9a6b86 +2465,0a7f3465fa83643c +2466,a8facabedd1f809b +2467,322b72600fbb18ca +2468,3a0cdfd762314bc4 +2469,1cbf34c2279f201b +2470,2312e82962c83160 +2471,8cdc0b7d52bfee69 +2472,454d0d7908365c51 +2473,5ffef1cfc4b7ae5b +2474,96791a641905104f +2475,de26b175768ac641 +2476,a2de7f5d1be7f10f +2477,a102a9c1603409fc +2478,5a8c038b46c8fb9e +2479,a91a3d37585ae58e +2480,7630ffefe43a2794 +2481,d64a0cfbb054c9a1 +2482,95574abeae355bce +2483,f4406e9e411935f1 +2484,4093074d393bbdf1 +2485,c7969952f2a31788 +2486,694dd2eb7f67811e +2487,a79d6dd65b3b5861 +2488,b5bbb94de715deb7 +2489,2c7820cd8e150214 +2490,8e4cd8ad070b2cb9 +2491,f5b227e94558fdbd +2492,627cf0b7f7c10083 +2493,b5984dab6d662d4f +2494,a2c1eb6c5fbc6ce6 +2495,f872638317f87323 +2496,8e080bab9def2597 +2497,11fc89dc7b698e8d +2498,682661b920dab34d +2499,caaaac39585c3a78 +2500,0504c004faa099da +2501,62651abdb0eecfa2 +2502,47cba5a8c66cf2a0 +2503,d4642b26f733b065 +2504,f0ed6a5961aa86fb +2505,091cb945e3bb570a +2506,05e5d873f7f7e8b9 +2507,0ac08ef70770f602 +2508,5fc8d0b0513ad3ad +2509,692f3f14c4f31ea9 +2510,3d48f8b3d0ed5ad3 +2511,04053e8348762dac +2512,2a4cc0ff60eadb3e +2513,fa33908f6560cdb0 +2514,a68a01ad00c7d254 +2515,a125198d1ab22ea8 +2516,b602f79001c3b2f5 +2517,82af624b0cee6e69 +2518,b07a075545f72dce +2519,1313f79947caa391 +2520,dab45ca7c06ff362 +2521,86c8d07424711013 +2522,9ba1351c7dc25fab +2523,8b879d56c2041a4e +2524,c6821ee6385b0346 +2525,abe64006e5707e89 +2526,a06220e5ba9da532 +2527,23cea0ce87b71ec0 +2528,a027b6cdace68f0b +2529,bb98d67c5a456491 +2530,68502748cb96d770 +2531,13105f31fc4baac5 +2532,10c13951b21d75f1 +2533,bbaec8f43954c167 +2534,5f4e9e58956e9f10 +2535,43a2541be327844e +2536,b140b83279f4914c +2537,915a2969950e12c6 +2538,91274bb326739ba7 +2539,a0e99dc905b99534 +2540,ee442d877c4f9bdb +2541,57d7ffbdbd90077c +2542,42cd55f91d087b1f +2543,bd601d8c6a1b0cfb +2544,db6097c859f5e39e +2545,0815719ec111d271 +2546,0df62b08b5052afd +2547,8811c86b74ef8154 +2548,69f4adf98e5e2dec +2549,08bb8b1cfc26081c +2550,5e0215555a34bd3a +2551,8dbf09788ce6fe91 +2552,848b1d9d7a639fd3 +2553,53693a3b7bf28e0d +2554,cf4e9acdc4a81573 +2555,961009bbe9134585 +2556,57f42d0f4e51606f +2557,44bd71905fb0746b +2558,732c86e42ceb7085 +2559,44826784ba6cb5a5 +2560,606c4b3ed40099a2 +2561,d9c27ac0990808b2 +2562,065e6ab319ab48b5 +2563,82db1989796ee97e +2564,1bbd3108e8280e74 +2565,e4150ce256db4957 +2566,5de367b5d0a34751 +2567,1cf8c15cafd5a832 +2568,68ad1f7e02987bf7 +2569,f2c7b81acf411e5a +2570,b685e0610d381cbf +2571,7c9dad7d5a980fd2 +2572,809b2769a3d745ff +2573,f4ae501e213e0e96 +2574,8badb4a10c21676b +2575,fdd9775e08fc0871 +2576,fa1272141a853754 +2577,fce518057e601949 +2578,b42a8f843f10deb2 +2579,b4373cf3bc77bd30 +2580,28eb981c8130daa0 +2581,8d7e5468e6355294 +2582,24e73dcc13baa735 +2583,68bf632fb10b62f3 +2584,fc05ce548f3edf89 +2585,cf41acc3eb2f8bce +2586,cd989f833b4f7c8c +2587,7f319ce58b077ec8 +2588,f1ac3c2e05a1e75a +2589,f809d1c431408855 +2590,604bfc40b0b0fd28 +2591,202d9cc3768fa52c +2592,d817e5a3da592b08 +2593,24799fcf5b591a92 +2594,3dafabae47220263 +2595,f9028dcf771cc6c3 +2596,686aebeb1c090ada +2597,4b89bc951b0022bc +2598,c7ecef96cd0422e1 +2599,fef56dfa46eb61a6 +2600,50ee8e6b93ebf08e +2601,2fb893a5447bf996 +2602,04bb4f2bf5a3233a +2603,40d2fb6c656f1a10 +2604,3c9db225a0c9dcbd +2605,e50f40d97a04f7f0 +2606,6471c0df9a5a4315 +2607,76bc8da444cbc414 +2608,19bba4d33082dc92 +2609,d0df02fba53187e4 +2610,e51d526d7c4be086 +2611,18a8ce5b4dc5c07a +2612,1acaa719247cdb2f +2613,9bceec1b7137cdd8 +2614,7ed81c8c55d5f7e0 +2615,661946c8b9ae3fa9 +2616,fa59e5509d257292 +2617,f3223642b634dc8d +2618,a6fa0b2a66e5609e +2619,5265b34f048b17ab +2620,c36905aef7b9f322 +2621,d25c3cbeafd96f26 +2622,8be8c0555a8b20fd +2623,f93f8d55eebc7d40 +2624,ca1f3f5fc6b2efb3 +2625,a5cbd17ed8af0f9b +2626,45fb7748bd80d435 +2627,ec91d5f859fe7589 +2628,484bc70aee99fcfd +2629,0a4f0eb41e9a4c66 +2630,52747b146af9ad5c +2631,fea208af8de5326d +2632,bd9ccfd9c545d037 +2633,fafb9aef65d50d0d +2634,fc81da2ab404a435 +2635,925d68d6b9342d34 +2636,049ae2c2e28c3d57 +2637,7dc8d9022db7004f +2638,24956384054cba54 +2639,98030328c175af00 +2640,f6a7d6bfa253b34a +2641,14114f38ae824219 +2642,dd59fd4f0417ccb3 +2643,5675808256d12513 +2644,1ef0e070605836fc +2645,c12a35c298554fc6 +2646,267886c44698989c +2647,d587738833516559 +2648,5b8a10d19f7e85df +2649,7f39400e9edfb52a +2650,9b1c2239e4f80f2b +2651,0b67409cdf3d62cc +2652,773d6cc7793e002d +2653,5f2e95a1c97d016d +2654,77bfc329309f8bc9 +2655,044670b5295d649c +2656,e957bb800d7ccd6b +2657,9cd45a705f43d0d6 +2658,2712c445e53b78a3 +2659,acf749dd4a00c59d +2660,9157df208bbda243 +2661,030dd9a88df93ce0 +2662,f3964340304d2537 +2663,70bed4df2700bb92 +2664,094deb476468b154 +2665,de12a0488cd93dbd +2666,9ce2a6c97ea98925 +2667,2128c0813888fad0 +2668,cce2ccfe41b51798 +2669,31d004c8f36f5ccb +2670,71731553d8a633b9 +2671,f96cd33438ef8d43 +2672,081fdea8723c1f20 +2673,ff167999113d80c7 +2674,35b64ed7d6104d3b +2675,49cf94963f9312fa +2676,0036bcb38d50817d +2677,0b566bd18601f1d1 +2678,2795f58e363d6146 +2679,1c296d83c6152a91 +2680,8ecc6999e8ea6a5b +2681,0199e37e9d0cde3d +2682,2b30b0361acec582 +2683,200684890a79dfd1 +2684,11caba6e6aa38648 +2685,e4f1ce166a088619 +2686,d1e9b08f33753396 +2687,ce2db93a0d93c0df +2688,8cf9679bbb5871ce +2689,9ec93d6fea8ab681 +2690,68f9b7c0be35c32d +2691,233ba41cbb498d72 +2692,7e325ea7cf464927 +2693,3c1bb08480d7b23c +2694,9fa4c4942b9e79ed +2695,018892bf84092fa0 +2696,bc233debadbf3e2f +2697,d63aac9a5c6f2216 +2698,ec80eb56e13e46d6 +2699,e39892d0280c2729 +2700,e8035f6fced0582e +2701,a7a51bac51a8c886 +2702,56979c7d5d907416 +2703,ea90db1e9c342786 +2704,326df13db3f4417c +2705,a6ee8ddcd55d2375 +2706,17e1484299f071d2 +2707,7e5003de316a099e +2708,0f55ed9b3191193e +2709,c111a5036b830e7e +2710,9c07586785e3b2a9 +2711,207bbcb3aa4dfec6 +2712,37f61b55255766c2 +2713,a3098e4d32e75d3f +2714,d393ef832132133c +2715,3cf8b0f5c4b4519c +2716,11f0ec4450f9dd0e +2717,516208cb34594d37 +2718,5db95f59ca611c74 +2719,a8d8524bf38a3ecd +2720,765be5ec6957327b +2721,59050d39b509dc44 +2722,a765a80031ec8a43 +2723,e05a2dcc87c402a7 +2724,9fd16f19bfab91b4 +2725,4058b70c47f4c508 +2726,890bf58aba554ad5 +2727,01f45b5d0ce63d41 +2728,33057fbfc569045f +2729,9e461e5b66dbfdc6 +2730,c28f1250a582547b +2731,7b900d585a788822 +2732,2ef57e61cb3a662c +2733,f895e4eaf9e62bbe +2734,c0fc95995cca8d47 +2735,af5f1fee1791c50e +2736,672d6aeccfa94a44 +2737,f593aa10f56f93c5 +2738,53dede044536b7c3 +2739,e4a68ef489d5d080 +2740,ac4a5b876c1a6b79 +2741,cd99250d96d453f6 +2742,ddc7118deddb4957 +2743,9e368f927d5eebee +2744,8fd0517707d4aff3 +2745,5aac3e4f9760f323 +2746,158c44977feae2eb +2747,317537c85d182b1c +2748,ac2f91381704d3c2 +2749,bb291ba7bc82dbf6 +2750,91e059a01a21e84d +2751,be041c54e11c9426 +2752,8119ce7d91ec2478 +2753,505d2c8bb0710f78 +2754,153c1f84370c310f +2755,323a9bbefabe27e0 +2756,ef27b16b9f1bc969 +2757,ba242ff2bfae9c11 +2758,964f7972dc3ba005 +2759,bbfefffd62cd18d8 +2760,085a73d18a49a29c +2761,f11553e45f4cbcaa +2762,95655b45e0e7d06e +2763,df87206b07ca1245 +2764,5aaf8bbdde0fd337 +2765,1bbbeee88a4ecfe0 +2766,c5f565b0c6f4d20f +2767,630b6fe69da3933d +2768,2d2f69255219b763 +2769,7cea6ec61e180b60 +2770,8872f8e195fd32fa +2771,37a160579a1ab1d0 +2772,03a2d60b85b0034f +2773,491021d72d55e42d +2774,33d6c1fbd699e4b0 +2775,646236377a5bbba8 +2776,900660f67a1d3227 +2777,cbb7bf9fd6723382 +2778,8732d3820551f6bd +2779,4462f6ffb9377a84 +2780,c442def2a4ce6315 +2781,06f88ab76c8e99dd +2782,1405b7c491f2e3d2 +2783,57a5e2496e208343 +2784,3caf519873cd0842 +2785,c88df81de12577d1 +2786,3c7d94b202b07fde +2787,d6f40a18e120734e +2788,f1b925c63a187999 +2789,1fae7eabac87329f +2790,aa9a2ac311283ad4 +2791,fd1f996f7f5fec32 +2792,d28e692109c8e938 +2793,3eacd8c0d93e6978 +2794,23ad68ff1813a329 +2795,081491716648a583 +2796,80c134816bf552c0 +2797,c62e0d4e18fdc672 +2798,487a799154e6f9c4 +2799,7a3c400c6d923203 +2800,c46efb9e9c03b5b4 +2801,c8d374366ba30a58 +2802,0974c2b9b3ab1bfd +2803,fe5a24f8e28f8607 +2804,4ecf7e6bcd702217 +2805,3fa290dc54d46a11 +2806,0c030943ab6e9240 +2807,f8fa1f5b499066b7 +2808,6fdbf0381ccd47b4 +2809,cc444775ace033f3 +2810,9cc90e4e062e0c2f +2811,55de9a285b2cfaf7 +2812,032890664afcc7a7 +2813,7fbea0c2cd5955b1 +2814,b74ca4d46928643a +2815,a801f6cd66cdb380 +2816,2bb2263f9f86f9fe +2817,ab2efc429b8a74fb +2818,9444d2de8026ac35 +2819,cbf1f1114918eeb1 +2820,5cd01af41ef0d27f +2821,b871803861d88c6e +2822,5617ce81b6e9cdc8 +2823,831bd145dd306d12 +2824,3d8513c6c7c36f7d +2825,542ddfa46c61df0a +2826,de4633e982b02f57 +2827,e4ae105f42db81bb +2828,60fac14f9fd63f14 +2829,90b7a02ecd719b6e +2830,0f891d791e4b2e6e +2831,96e9f314630f3e6a +2832,600fed75b006ada4 +2833,998358096616aca2 +2834,2232bfaaa2dcf434 +2835,16b0e71f849ebf37 +2836,e0e463361ac9b078 +2837,ec560f0e249ea4bc +2838,ffabdf5e7da537f5 +2839,59430ad4c371b82c +2840,841fd8150bc2173f +2841,2bef399c36619cfa +2842,5037e7d20a226055 +2843,455fe70922f7e037 +2844,650e0f1b4ff25271 +2845,e9c2ffe6ffb97c1f +2846,cfa8f145a9d8c598 +2847,4ef25dca242d6974 +2848,b306b28971e5b837 +2849,4336e0cba72979b3 +2850,5cb9d0a0075bb281 +2851,95748ff70b1ff155 +2852,c9dffefc89f3f0e5 +2853,9004c977fbcedd29 +2854,a55b41a55468d77f +2855,1c4fe74c9f0e8b59 +2856,8ac30b882e232a4e +2857,3d6653d8acec0afc +2858,2ab13d7afe1091f4 +2859,56d7b826ceec4087 +2860,40ef531220fc56ac +2861,e954d4ae9f163147 +2862,6f6ba11f78402153 +2863,0cb60d1e9ea354a9 +2864,733c8d503a045328 +2865,9bac6772e1c755e7 +2866,d62223978c12dfc7 +2867,7c88e86a7b93fd12 +2868,d90180cec3451c06 +2869,9d0519de14d0f5e4 +2870,90f0be8f05518b59 +2871,423e2bcb00cb592c +2872,9cfe1410a8fd6323 +2873,9fa57112fea5e193 +2874,53a5317c70c4bd0e +2875,49ba1365f23d1a89 +2876,ea546a3bd7685c9e +2877,0a741b690498c074 +2878,45bc6ef9bf739c3c +2879,22708aacf5c5903b +2880,f56e86daf6065c02 +2881,324fb251b5ca6c28 +2882,ef3fca9d4a1c255c +2883,984bbde2d92abd2d +2884,70ed56d64bb650d0 +2885,0bbae4e5c622b9d5 +2886,c53c65f511819856 +2887,5f4c68bea6661a42 +2888,0bf86a808d0d86ea +2889,179d993fce98ad0e +2890,bb4657ad170f3c17 +2891,98766a6c3428df54 +2892,d14d392e43230e9f +2893,9584aeabf15f18a3 +2894,60dae7351d87bfb2 +2895,1e63e8e530e559cd +2896,81853004cf28bdc0 +2897,5488c5a5f1c80e96 +2898,2fe8413444bca63a +2899,cf2bec4fc2e35e53 +2900,00dad544acb51177 +2901,5675c0c934c5e993 +2902,02c9032f4aae22e4 +2903,76a79802e4038ede +2904,72f3dea40870fde3 +2905,03f3e3de476dcccb +2906,8cd52e7093b267fb +2907,d4e1c2ceb762b486 +2908,c7499c53bc6bc1cc +2909,4d38ab524bc75722 +2910,fb9181fa6ae96752 +2911,163304733ddff8bf +2912,c818b9c111713b81 +2913,35262ca4b1886f48 +2914,275180b3bb9c72ad +2915,8685324ef1440326 +2916,cb2e6dc260d2e7a6 +2917,3bd0821bc0badc64 +2918,37ab66c081fcf124 +2919,5c28069c891fdc9e +2920,683e5ecba8506178 +2921,0c23489b18f5be32 +2922,7e37b05dc214e062 +2923,30b7754db6692e0c +2924,cd0fd6e5e6830525 +2925,52ea1014db01c4f8 +2926,462c097794668f25 +2927,dcad3695d56d6292 +2928,397d1dfadafe9812 +2929,40c482c1c33eb4a4 +2930,b0acf6487992e4c8 +2931,d7c5883cc6eb53e9 +2932,816bde3bd42c6539 +2933,2bcc788082a863c5 +2934,f427af575263a98c +2935,30810cf3a0bba137 +2936,1c3e825ac0cbdb19 +2937,8d79f55a8b9ef77e +2938,087d5d48710c9311 +2939,bcd1fa7b549b1944 +2940,4a9d710910ac7a24 +2941,13ec24a7e2331b07 +2942,699305b688c70b58 +2943,e18e331c38b433f2 +2944,cd81296cf3ca8c33 +2945,4f3978dedf1a70f9 +2946,03436d57ffa62b52 +2947,a1acb6dd8ccc5721 +2948,15367a7def3a012a +2949,83b3c871f35921fb +2950,1812ed846dd017fd +2951,aeecf5f5c9b9d640 +2952,fc3e3bb25abb5ab3 +2953,b560a69372c1c3a2 +2954,64708e2fbab03169 +2955,607443a1d7ccdafd +2956,977c11f03357bdb5 +2957,3eaddde323d577cd +2958,d402cc79da756a0e +2959,05feda56ea3e9bdb +2960,6bf23f052d11e768 +2961,1b66994127baac9c +2962,099980655661ab65 +2963,bb08e92b2ff05953 +2964,5e1021b90d8d920e +2965,a9fbe05dd7c0c65a +2966,ed861a0944ee4699 +2967,f50ffcb998be9699 +2968,7753eb07cbbbb463 +2969,b881ddf3092e1602 +2970,5c9714a7e49a3b69 +2971,26ac485efaa358c2 +2972,f01235b44a62c1d6 +2973,017fdb8f36af9342 +2974,f3313e8c5d7bd10e +2975,4d32e56f432bb049 +2976,baa155074e7fdcd4 +2977,765ed519cc168ed4 +2978,e9add07708b6a4c8 +2979,89f1f29b9cc2683e +2980,51683ea0a2fa62a7 +2981,00e33842dca7e8e3 +2982,b24835b0ca2bf8ae +2983,ecc8ef6ac3a1ecca +2984,fa2da66810469914 +2985,9c899b5bfa18725f +2986,1f033ae94a438b1b +2987,04cadc18c7dd6326 +2988,5d8846e7966f1fae +2989,1e1a0a650af181e9 +2990,655ab752ac7bac57 +2991,744cc73919e3b854 +2992,ef2c043943f88b12 +2993,9b13c1effff55b45 +2994,f0249e812096f2a9 +2995,2bc0c771cb4b3558 +2996,11a61f9b8da44cbf +2997,ac963c10a4f12ef6 +2998,9565c7336f6533e2 +2999,138201563eb7c616 +3000,ea6786d8382a5902 +3001,7ac869f1adfa377a +3002,34af92dc932050df +3003,02bd810811cfaab2 +3004,534e45ad8d07cf8c +3005,dc93e2b1624c4a43 +3006,daa29e715ad478a9 +3007,3952bc703064de07 +3008,d778f0f46373fd88 +3009,65cf9701c5aec124 +3010,107197088bbc83e8 +3011,2b64de1627b1dc46 +3012,55229496c99295d7 +3013,0e411ebcd5268603 +3014,c397bb8e5672cb4d +3015,d497646bc943dda0 +3016,eb02a0a50a27264c +3017,539129b77566ae82 +3018,6c714c69990411cc +3019,de10745fa2f6e3ec +3020,77bf6849fe420682 +3021,2fae6ff8ffb2cdfe +3022,2cc1c3cbb4173bbd +3023,bea083a18ea17f86 +3024,86303a737a8a38bb +3025,99e57c9125161f1d +3026,153e4922809e7d54 +3027,9aac95e2350c2823 +3028,6b4bc5109cdbbf85 +3029,51bf6e6aad3e5816 +3030,53c3f2b5dca0bb00 +3031,39b64c0851dcc95a +3032,ef4bd530ba126cd6 +3033,57061ff075cf3bf0 +3034,0c5b95463421dad3 +3035,6cf41009cc070371 +3036,d526e0efd9f95ef2 +3037,c965efbc1fcf3891 +3038,571889fb6febd8cb +3039,7e1008861a20a06f +3040,6db037b8158cf95e +3041,1d629d0d29b11659 +3042,e1a84ed2b0b42ea2 +3043,3697e1dfa44d1466 +3044,bc5280a6b33ef6ff +3045,e8ce422b8cd644af +3046,f9619b79a725271d +3047,075f3c576ba3efba +3048,08f6b5974942c9d0 +3049,62504981fab33f46 +3050,ea5871a211e69854 +3051,23fe9c31dc4dac75 +3052,81ed0f2fa00ae16c +3053,01979637b301f2bf +3054,0c31df284810eb16 +3055,91d1152c55e2d00e +3056,4d17323d20bfaf84 +3057,24f4b0836e1f5f88 +3058,59366b0761f279fa +3059,bfc79419a0740e37 +3060,814e740963707040 +3061,2828366c0879da93 +3062,0d9ace88b3c311a8 +3063,5a74a0336649f280 +3064,e1859d0ba35fb121 +3065,439326641914675c +3066,0f6851b0b01d6a9a +3067,40e0977ba30d85a9 +3068,8d4d4ae11856eb6d +3069,07e805b1d4ee7ae4 +3070,e4d223c63bf02df1 +3071,1f7299f16c0ef45d +3072,6266e07612821b0a +3073,7c7db375ca0d55e7 +3074,4d1ee959f8a97d05 +3075,e8cd85713c5dbd02 +3076,a7da22d66d2ec92e +3077,9b2c5bf8c9df2237 +3078,8d621f4538bf4429 +3079,86d785cc09ecea78 +3080,f91be2a713629ce4 +3081,4e5c7a17d019ac14 +3082,2a56797e1a5127e8 +3083,c43fe1edb095ac45 +3084,e299954100e33370 +3085,07475adac1f0c510 +3086,433b9164273d47ff +3087,49a7ee0dc6342d3d +3088,8282cde74135d8c9 +3089,f0ef928347012d85 +3090,1b981a5e5300c812 +3091,ffaa40726a4191f6 +3092,2def0a29c4e09f8a +3093,42055b76cbde92ed +3094,935fa54982e81c69 +3095,8374ba4e8d5c34c8 +3096,5c95c02c9cea92d3 +3097,6fd5e7ea39dff020 +3098,5327aba14b690a1e +3099,7ff0e0f420b28ba0 +3100,8b6a47e5af581986 +3101,35586a7c9153749e +3102,413e2d2b107f6e72 +3103,813998fae9e88cd0 +3104,2165c80c4d83b110 +3105,87ec0be060f0b44d +3106,8cdc5f7cd4841d8a +3107,c8d3b7691f5e60be +3108,397ac1849ea5fbc9 +3109,c0c3cc2d9e41ed17 +3110,47f9019297eca040 +3111,1812013e34984b00 +3112,837c63cf6e6252ce +3113,e2098d76c915ba78 +3114,9377923fbf28a803 +3115,9b002c4128328e8d +3116,6e742108fbc7ea21 +3117,31913bf33080da06 +3118,0d3dabf66bdea5ac +3119,e03a9a413f6f7951 +3120,820fbfb778052a9a +3121,feedbfb2bc4f8ec2 +3122,640c3f90af042d03 +3123,299de515dd7ea62b +3124,64db8df6d29b2c77 +3125,3ef43f28800d4d7d +3126,7d7330a308525b30 +3127,92c9610cd824c81f +3128,564104182a516d8d +3129,7c81105ebb5bb592 +3130,fcf554c1acd724df +3131,07cc3c5b0dd1e217 +3132,0f88a9216c737282 +3133,6292eb45c3887095 +3134,ec836a5159697539 +3135,942b0595064f57b9 +3136,7b0b6b39343a2ddb +3137,94d08284c8968240 +3138,6f7091ca1e769423 +3139,c660e29f4853a31c +3140,e07b736b4cdc9d7f +3141,e87e6b2aefb07dc5 +3142,9118f283ed23f8e8 +3143,6af1bdb05414a855 +3144,fe16289f2e0427c4 +3145,13c83ee753c328fd +3146,233f89a60bae8b45 +3147,5c143c861c5a5a33 +3148,a68ddd66268eddb4 +3149,f531383f44947514 +3150,af4ef138fd6137c1 +3151,3f3d486fa37062b6 +3152,774451cda8adf048 +3153,692144f920456baf +3154,acc8f5eceeb1fc38 +3155,c3c8bd299aa138c3 +3156,0a1988fd660697fd +3157,c65350b20098069d +3158,a5a3b8d29abd62a3 +3159,b0974842f9f4ebd7 +3160,41a87087e95a3115 +3161,a47034bb4ff13495 +3162,d52a0a8305184774 +3163,3cf1914b5ea7f4b1 +3164,c945544777c5ff0c +3165,875ce77b64ef789f +3166,201e90ea2d828b12 +3167,38bde4ab0f77f2e6 +3168,94bac85d4e479ea7 +3169,e87f308e39062615 +3170,f9be513fbce5badf +3171,23ef68f656044c8b +3172,adbfa94281eee632 +3173,4c6a2539ce580da4 +3174,4fc64d9b258dd93f +3175,fc85bf39cd049430 +3176,f898c5a3bb29422e +3177,fc3a82c602e47394 +3178,bdced8326a844f73 +3179,f0aa35ac35786986 +3180,3d33450f258a73ef +3181,9e3a23ca173a3126 +3182,ac2847a6a5affa51 +3183,761c7aaee42c7568 +3184,b493dbddfa6acd32 +3185,32514cf5934396af +3186,9c78b86ca817207f +3187,3abaedace25939aa +3188,8925b374230d2041 +3189,f1386f8511696b66 +3190,b73caa4230d7f1c6 +3191,36a22e0fa1374655 +3192,642d25946f596d85 +3193,761ddac6a30d3f70 +3194,b6d8c036bad91d93 +3195,ea2cd7c1f1b20883 +3196,7e226998775533d0 +3197,2cb126f83de19879 +3198,6e8fc2d0a8532a9e +3199,93e60f503e909f90 +3200,4fbed078c4c03fe7 +3201,6014de2bda91cc3b +3202,7d497a51dd83df42 +3203,8902ba7a18a5022a +3204,7cedeb91ac7c69bd +3205,0609916aa4a41419 +3206,0f95e441e0abe3a0 +3207,be3e848500b31309 +3208,592a8a90f7b9bbbc +3209,1511d49b2d8064fc +3210,3e2c6020cd92f739 +3211,8b177f74ab1599dc +3212,19321af7919f008f +3213,84d8ef5a8d9fbc82 +3214,ce5a8d61ca2ca423 +3215,5f18a1e527d93844 +3216,b87b13f5667297a1 +3217,1511669de3840adb +3218,4ebbe2188bcfde57 +3219,4dfa1590234f7298 +3220,91e52d9338fddeb5 +3221,149f7a9b1622f3c5 +3222,a945144ff6e30e3c +3223,af092dc6467bbeb3 +3224,2d3c8c224a7fa916 +3225,765c6b10a002e3c5 +3226,d23bbe86a17bad34 +3227,a122a400fdc4eb39 +3228,c0c7b2f04fc07701 +3229,b1389ee4dc041172 +3230,38348e8df4b1629d +3231,13754d15359f6466 +3232,4aff38905af1b8bf +3233,96ba2aa7a60e99fe +3234,040822dd2859c772 +3235,c15cc00011a3eb2c +3236,1d3bc67fa867b1d1 +3237,4073dbaadd1303c4 +3238,017df378f10c1690 +3239,95f564d6df8151be +3240,33b2161a162f7ed4 +3241,e4d4e991db485021 +3242,30263a2b567097ee +3243,071f477634b372be +3244,e464d66f2f6e5616 +3245,d4f912393b89a986 +3246,d87591748f90306f +3247,ab8896285aabe0cc +3248,6223ac71c09b12d0 +3249,a9fd81c6077bd3af +3250,cbc3bba97faed5c6 +3251,27a42aa576cd2898 +3252,bfd6e92345f84d86 +3253,b1b73626d43ad486 +3254,b271edb7b4f9f859 +3255,c9d7231ce676248c +3256,f722c96e82835aca +3257,d3dd672fe35fa32a +3258,42ca565f26b01894 +3259,1f3c2151367c738f +3260,a4787335519c9f44 +3261,0c4798fa7dec99ef +3262,c90e256af474dcc0 +3263,d1b822e1275ff9d0 +3264,960b61141b8d73e2 +3265,8653a8e37bfe9bcc +3266,6b325fed8edf686b +3267,0fe7c9ea78f96496 +3268,6613ba1106dd35d2 +3269,a282723ff11c269a +3270,92479802ffdfd92b +3271,50191a1a4101eff7 +3272,df82de8d7a62d466 +3273,487bad8298dd3922 +3274,8e38e9cb04a8d5c8 +3275,152c206b6b5d36e2 +3276,345dfd7c85901c5c +3277,1dd29abd4ec35514 +3278,1847aae53b211a1e +3279,7cda26cb001c46bc +3280,1b81bfc30c74ce5d +3281,66a49fbf5db5c291 +3282,6d2902bbc31d7091 +3283,9e60c85f2579e6fd +3284,b28671516ac1025a +3285,4f60da1be4d414df +3286,7fd8db72b4290e2c +3287,b77b707d78a16598 +3288,d71e6f26f9f44ff9 +3289,397b30002206ad65 +3290,4fb1cce2b50c4531 +3291,2e0f9c21616f3252 +3292,209994f543bd8192 +3293,fd5d7d72dff243dc +3294,c652c3ca9e97b69a +3295,7c826ef72f82ca08 +3296,bc06a54a68e61217 +3297,eec93d3c15e78979 +3298,3606897678a0878a +3299,2952bcdd8ebe0a47 +3300,1d9fac7d97bcb8c3 +3301,e49ea87bb5e7a020 +3302,7afb3ebcde51b980 +3303,5b37b9f06259d84c +3304,e6d1e48a8bdcb783 +3305,f930969f06de81f8 +3306,81c74e2e6012e9cc +3307,653525f4e1dfe8a3 +3308,1091e45ae25a722e +3309,1907b0040e3f678f +3310,123c97a6f4a18f28 +3311,ee547ef1700e629b +3312,c679c2c452b688bb +3313,eb5bbbc1437b272e +3314,6dbb909c300025d5 +3315,caa740b14f1b0092 +3316,c1e8a3f238eebff6 +3317,c5f94b3f396b7f28 +3318,ff628271754181b7 +3319,83a1b0d5709ef3d7 +3320,4d1797b1dd5b0381 +3321,993dc0bffb52ad50 +3322,38878f0d3b6368df +3323,f3258c8867fd99c2 +3324,6120e13342001eeb +3325,e4711fa00a82c864 +3326,e270f888b88e7f14 +3327,83f07aaccd43440d +3328,b1dc6c3ec53d16b0 +3329,b5c623d931185199 +3330,33b87752e12ad7aa +3331,bcc169c268522f7c +3332,c73441ee46f0f691 +3333,1357a70dcff09561 +3334,15980ac3516dd499 +3335,654fef311e611a27 +3336,0f0ba8e00aefabd4 +3337,c8942928dfb5a9dc +3338,111d00ed95060f80 +3339,47997e13a6b100d4 +3340,481c79611bf48adc +3341,258e18fbc951c9bf +3342,42157687ffd80080 +3343,85839903436b5a00 +3344,6d3de077c3c947c2 +3345,39e3e00f4259c154 +3346,031386c6b8491f86 +3347,e8ed7a6b8b2b4a28 +3348,74ce8de7dc236340 +3349,dfb82ffcdda6a3e6 +3350,c81ae449ec93cd9f +3351,29cfa2f3b54fef2d +3352,a0de4a68dcf551b0 +3353,526ad2ac0d313705 +3354,71a94e8f172c50c9 +3355,533068fc03a95207 +3356,a6f75591e9c1e728 +3357,ec96aa6c41495953 +3358,78efeee05b7f7fc1 +3359,7d9bd6a7a8713042 +3360,0040d5dc8a990445 +3361,d499091940c83557 +3362,b4ef52939a249b66 +3363,6cd6ecbe5e373cbc +3364,ef84799593f6211d +3365,31b62c80ff6b8040 +3366,bb6f8348f09b6ded +3367,ec88c082c95945e8 +3368,e23e11cdfd94944d +3369,e3f78be6acd7da6b +3370,234caa576460d8dd +3371,8b951ae9da228b89 +3372,35cd9124cebc7f79 +3373,afa6854adba731b7 +3374,7b75fc590b28b79f +3375,92df1ba5a94aab9c +3376,d1ff83c34ab9a3d0 +3377,df4a1951fe1a3326 +3378,6d96e09611a403b0 +3379,ae2345102f3195ab +3380,749e91c479bc2cfb +3381,1dbf5938e53b0e13 +3382,19eaa83767f3485a +3383,6007d4b963044e44 +3384,10c4cc0d55747b07 +3385,fdbd96c688a27197 +3386,24a4206549495f76 +3387,925749adfde11369 +3388,b7e0fd896a6bae07 +3389,ed5aa0f35b866406 +3390,a5fef8083a8d471f +3391,d9a516952d3ffd44 +3392,77b4af5604728df3 +3393,8c561a2996fda511 +3394,05cdd5bce86232d6 +3395,45f055d32a1ebca1 +3396,71db66ed15c4402b +3397,f7c18bc5b3fa5798 +3398,7822125338737ea0 +3399,f3c158a9c5f698ca +3400,5c1e74bbb98fca07 +3401,cb8775011a6b8426 +3402,dfa1a62e0482fb28 +3403,4fccf9e7b8dc5426 +3404,7521e63e9ccb268d +3405,eb806b4f9747acd1 +3406,1b0e9817379e6bd0 +3407,bece843a9efe9aa4 +3408,0895099bcccf5715 +3409,f3a45fca4764cd18 +3410,07bd3368abbcc6c6 +3411,141555336307ec1f +3412,3d984a735caa8b70 +3413,84e4f7b51549137b +3414,5e16b52a35b63a29 +3415,99947b1788c078c3 +3416,635adfa134473240 +3417,2d687e9e56b40fa3 +3418,b71003a4e80aa986 +3419,81a75661c1a34a98 +3420,97e3eeb140cd0aef +3421,26879e96d56c88fc +3422,0897ea35be60e6f2 +3423,72bed730ca0e0b02 +3424,6c8a67844057fbb6 +3425,e0729da3baa08094 +3426,b96253383931b8a1 +3427,1a027cb9495a7a76 +3428,adcb5528269b6a68 +3429,045bba9bfe42b9b4 +3430,e3bc37b795817aa0 +3431,18ad02493bae237e +3432,d6925f8c08009c50 +3433,6fb4b6e76a3d4732 +3434,fac1546285ed3ae9 +3435,edbc271d8bfff151 +3436,edba0351bd394c4c +3437,6e4bb5bdc1bec3de +3438,d724b4fefe9d75dc +3439,f50b10d4f12aa9e9 +3440,a482213fceca9f70 +3441,702064c280a9adb2 +3442,1806f6536b05751e +3443,7f15436c52124703 +3444,86d764a0355d4989 +3445,8cf44cfee6af0764 +3446,97033056a5d97f27 +3447,42ef86fa148764f4 +3448,1d9378bf0c0fb0f0 +3449,44f77d810d909d9e +3450,04156d31df7f0e4c +3451,adfe71c9b7ba6440 +3452,7c10b9e3bfc01830 +3453,06920bab52e68220 +3454,9fdca365f6185ba2 +3455,86e8d6fa4cf31df6 +3456,2898bb878fed9b61 +3457,74185e8f1260b1d7 +3458,eb2a149ae9fe7d13 +3459,46989d8f656ed3d6 +3460,0a80bace685eefc6 +3461,897e1ed64f457dda +3462,57e9304aa007ca0f +3463,1a3a175be65f37e1 +3464,e76078c6d3e92541 +3465,4dc29bf3ae3b1c05 +3466,ba56f2da33365f2a +3467,58b987db967d4768 +3468,908d06552661a4db +3469,c9ac6567ae790787 +3470,019596a5647dbcb2 +3471,9bfe1a6b53fb6b93 +3472,4ed89427f47f28fe +3473,4c45b4ca9a90febc +3474,03633d17985572ce +3475,286fb1f4e1f42870 +3476,a8ddb1e5d05ab470 +3477,41fdfd17d5a435af +3478,8bc61286d0fe9430 +3479,a9af92055b25ba7f +3480,1d5e13ba63230713 +3481,d574c0cd1f577f35 +3482,6ee14d48ed199817 +3483,0124e8bc71fec8f0 +3484,c65982ca31c0764d +3485,76e9eb17041be21d +3486,04d7cefd2c3b07eb +3487,bd180c42078d6a1b +3488,68649cb52e280505 +3489,148481eafcb58c76 +3490,3f7f90f0cf4f12f6 +3491,9fec18f45908a2ef +3492,0a48aeeb9db04ef7 +3493,01756833ec6cd124 +3494,a8c00300d04a2575 +3495,f6bf68e6c8ab09f8 +3496,074b2f9a44834bd6 +3497,5909170db0efb665 +3498,2996ac1ec5dd7073 +3499,e9e987b161b11fa3 +3500,e468d1b3cc48c76f +3501,591b4d571efb0391 +3502,da99563bd1f0f863 +3503,ba86ea8ace4c4b66 +3504,3f3f5647a7850768 +3505,c1994f505237bcf8 +3506,e23c9d5437bf59d2 +3507,f46cf301aedad170 +3508,9e7883b72b25fcea +3509,41f6b285ce4ca8e2 +3510,972721e35d988ac9 +3511,9c093ca71cead5bd +3512,14dc6e4e16cc86dc +3513,0fd27e8435a0bce4 +3514,4f9bc71a4d467738 +3515,2ed8bdfa15822ed7 +3516,d9cdbcd6b75c3d55 +3517,1d32436ec3b439e7 +3518,8e042d2a1d3c633c +3519,91bbbe90a19f3578 +3520,9caff53c8af332b7 +3521,a549ae0cd16f46d9 +3522,751002e4db31bd01 +3523,a5086344b257e961 +3524,19a9d591fb948d0c +3525,f6b86a3666fb442d +3526,082bde948ed444f8 +3527,3f2867f013c7299e +3528,25acf0bd088d3a21 +3529,f706a797f5a6eaba +3530,fcec5ae3050026f9 +3531,9b70c63b2023b2c6 +3532,d2a9f5d242188690 +3533,807ac127d1e462c5 +3534,fdd5ac09e9a646ed +3535,03bd6dfe753628e2 +3536,7c8203b914ce0bb4 +3537,40fcb45e1faea8f6 +3538,95528ae074aadd49 +3539,38893c003f0744f3 +3540,e3d25308d3964144 +3541,ba888f44457c6567 +3542,5d5edf636f481b75 +3543,8f08aea8b58b314d +3544,97a893cecacb27af +3545,74d2064fb861d882 +3546,b74795aaca64b430 +3547,790aea584ab48c26 +3548,99b1e6a143b15554 +3549,abe9bdd15e3388de +3550,13025e9449a96229 +3551,fcb4254d80283926 +3552,e97abfbe648cac99 +3553,df06054fc4a4f9fe +3554,74ff8607b1c10cdd +3555,8fe8ab545bf29f9b +3556,f317807fe090356d +3557,e0bac8d9e859a307 +3558,531c94dd77e2adce +3559,7241f91e05cf9773 +3560,a79bf6283045eef2 +3561,7e1089b1a6281815 +3562,ca568282b0ee8113 +3563,472aec7e5ac01852 +3564,d46bab6c733bd234 +3565,772c8b464c3dded6 +3566,56652689a29c1937 +3567,4521551293c5b496 +3568,f29a0e74510b691d +3569,cd9d14d31c5b48df +3570,076ce4f2816ecb7f +3571,990e9f41f2c9b2d7 +3572,38f69f6a671e5efd +3573,d0f8ddded4063232 +3574,ff7c06a1c60f2feb +3575,3229a87f6e277061 +3576,9297330ca51be07d +3577,f487455389ad202f +3578,40695023dd0965b4 +3579,6b5c9c1aedf2565a +3580,9a664a1d3b702cb4 +3581,a41e4b7e3c0ffc63 +3582,704ad1fcb0ade2dc +3583,53ce5ea17f0f38b5 +3584,359d79b57dc7471e +3585,5a75b19b87f55104 +3586,8650771d73d5cccf +3587,b61667c526b966d4 +3588,8b38760aaeee2333 +3589,1b2fcc54ffb58922 +3590,416f57c66cd8398c +3591,92a2b90d10b180a3 +3592,5bc544929adcf950 +3593,7b8209f23c409a9f +3594,a347b6d616ee36ee +3595,5fb56269808aa234 +3596,0d73d81c07f3469b +3597,ef9bf9b7bbf488de +3598,134bb5aa53c088c1 +3599,5bdc815f2a7fc8c9 +3600,c1fefb9c5c0e6963 +3601,5c50eaf26d83e6bf +3602,f842cbda585e7c77 +3603,d914be10f9a3c377 +3604,75a713afa6807cdd +3605,3d2230bfab281e42 +3606,344cb6c63c3d5415 +3607,d6e813ec1ee379c8 +3608,416063c737a997b5 +3609,2439c6ae2e5a79ca +3610,a45bcdd583745c52 +3611,16a4d88b2955b2db +3612,04aee680dbd1a260 +3613,ca0376697deea40f +3614,52f40640e182d69f +3615,526d36d3455233f5 +3616,90600c8485d94a5f +3617,45783baf157826f6 +3618,efceb1d397614d31 +3619,66e5440c138a6766 +3620,06bda7e591d7f71a +3621,bb3e0dabc82e7f7b +3622,d43d09319c808536 +3623,4a73a4f1cacba330 +3624,09185be29b20f9fb +3625,253029e32c11e4c0 +3626,3b4ce9e8d0ff6897 +3627,f9c00412d570eeb2 +3628,8929fa15662c4739 +3629,b9dc4df32ccf3b91 +3630,2fa61c414b8b7832 +3631,25232b7f2b471d63 +3632,a2ca4331c37f402d +3633,060eb8ac1e957e15 +3634,14154ebfe8fbd210 +3635,552c802fa61564da +3636,f1d526e979fbf330 +3637,e057799eb1967240 +3638,6546014cce759853 +3639,383309720f338347 +3640,b09a7663726a326d +3641,5c2e34af1e47df03 +3642,434c8a8cc6a0c969 +3643,ef89b00e8d5fbbaa +3644,80bc2130b741bc69 +3645,9ea4f72354fa41a5 +3646,b3ac4c41303306e6 +3647,a8100f265160fbed +3648,b3cded842cf39e39 +3649,b2f485ccfb5de1ee +3650,3daca91d8c294dc8 +3651,e6d3bb095dfa475e +3652,4dea05cf339941ff +3653,b250bb9890de4b35 +3654,ba89f03958a408dd +3655,93327814522192c3 +3656,fb2913371408669d +3657,1d98b55bd2a6009a +3658,bb468ee01594b8be +3659,9a4e1bd5049218d6 +3660,7762433710ffcc91 +3661,cf7bbb0841e26646 +3662,45286ef1f3ab57cc +3663,a8325b0632412797 +3664,57d02260cd563724 +3665,33fe4f03a60f3ab7 +3666,167c17e1dab487dc +3667,2db90968dc136624 +3668,4bba1015f49593ae +3669,bf10d14f422d9b25 +3670,e39731849ae5cf3c +3671,1c1df4a5dabce2d1 +3672,d803e79c4338b7b3 +3673,4d18e52db7ccbeb3 +3674,5c743012e42176d6 +3675,37dcb85aa1028547 +3676,81c1940c477f49ca +3677,3bc25c3d06e9dc5d +3678,0b3f0beb48f23069 +3679,ede11863d4c94f2b +3680,426966d4492860c9 +3681,6611fa84cde833f6 +3682,14d6614afff0e735 +3683,759c4da3bd1360a5 +3684,3f7e4407167737b9 +3685,d8a21dea944a312e +3686,8fd1f9d4caf9ab4c +3687,dac4d101b903acfb +3688,f97094513429be1c +3689,1f150a2bdab05318 +3690,92aaa6f5db11a4f4 +3691,5ac7ec5e5dbff229 +3692,0715be5746d9eac9 +3693,a437bcf5770d1086 +3694,b36aab4accfd1c17 +3695,65af18ca49838234 +3696,9bc3e4c1595217d7 +3697,ac6d9c0122a33d89 +3698,9b2fcc81d74acf8e +3699,2e3def89d82da120 +3700,129f302d2d2f7cad +3701,e84715be877b4885 +3702,c916d2a9fe5f65f9 +3703,120d360c10fd8dba +3704,29b73155de3fb5fe +3705,ca5eeaff6024d8b1 +3706,c6f68cab1117d70d +3707,e76b1e6d09d4eb9f +3708,e82d9da741794b9e +3709,37da45cdd101c5e3 +3710,1aed5783d4fc2879 +3711,b196ec4185de6812 +3712,4bcf4c4b4d6a602c +3713,c2fca3d5052d4e3f +3714,55232ecd6e476dd6 +3715,4508aa986408f3dc +3716,00868fb364d653f8 +3717,eb9bc5a2a9ed5b9e +3718,abffb091691f2ba2 +3719,fd9953c549d5b1f3 +3720,1c758896c88a6f38 +3721,5f744333c84ecb0d +3722,c38c9fd20a6bd344 +3723,5eff45f1c5b239f1 +3724,d4439bc2efa99c69 +3725,3197bdd36b5bf7e4 +3726,4f8e805d750d7c44 +3727,24c09269f67f56eb +3728,99c375e1e6ca2384 +3729,28eda79472ef03e2 +3730,0e77f9bbcfe22270 +3731,58ad808a11081586 +3732,aab90597de58e8dc +3733,d1f1fdd9b6c37252 +3734,8b38abc0173a5532 +3735,0283a998d3ccf292 +3736,c3fbce9e203f3027 +3737,d93c5efee22314a2 +3738,64366c27c0c12519 +3739,17781a274ccb6bf4 +3740,750fe1be5c128150 +3741,335446e326e95c56 +3742,dd853e0c0e22a0dc +3743,c6cc706dcd7f91ee +3744,28b421471b681405 +3745,b8fa8abdb80f1479 +3746,32e68b24c04f97c0 +3747,9ee3822617a1151e +3748,a00a32652c7f84b9 +3749,e8b64ffc2d244d58 +3750,81ec68ddbf3cbed2 +3751,f7a0399b699366cf +3752,88b0871c6b324bc9 +3753,22ab1890d8761e9b +3754,5800227d7f43928a +3755,63619d227a7cb526 +3756,bf003bbb380b9be2 +3757,cede34af3685b47d +3758,863f9ba61f7c642d +3759,7bb39d50b89dceb4 +3760,9f8622a960133939 +3761,cde5131f4ecebae4 +3762,a34602a6ec9696e7 +3763,17a46071b4bfa21d +3764,dadc646f192ca294 +3765,7b16615e4d6805cc +3766,73d33e12ddef5c35 +3767,696e86b8cd388a6a +3768,7d32d84ddb751454 +3769,21ef8b9a053d4a94 +3770,97e3e837b6abac66 +3771,3b80d8231c6db32b +3772,f26cc3d9c9c60c04 +3773,c8727031b74fdf1b +3774,71d8328ece0333e9 +3775,688f1d7ff47b341e +3776,e14a1e88024d6acc +3777,4dc0e048c5605faf +3778,9b6029d3d265cf30 +3779,b1c560520b18964c +3780,1771ee78388f8e60 +3781,d5f99cfe246bf840 +3782,944ec6d137a92659 +3783,50905d8764e648ae +3784,e534127f6c5fa486 +3785,c1de38ec3a7ea3f3 +3786,420767acff00cb69 +3787,5f2c9ca6e5315fb2 +3788,e2b7821bdb1464c2 +3789,0ff337950eb0de59 +3790,2b1ad2ee1d502561 +3791,43ba7409e2d4d455 +3792,50943ff6f7620b57 +3793,af28789508add966 +3794,d41d523051eea272 +3795,fd3227a05377f951 +3796,ce1781289949289c +3797,877920ad79876a3c +3798,e408fe9d2550b01c +3799,a56831a9bb4e0bae +3800,dfa7689814903e5c +3801,d2e6160711469b2d +3802,64505ad79d175f41 +3803,016c6d7466f96ce1 +3804,8ce21036b04b8694 +3805,61200c6b2e719531 +3806,2292f2cbfc21dae3 +3807,4d698afa8b18e837 +3808,0241031b807ca64c +3809,eac7251122a54269 +3810,bbff756ca6151a6a +3811,2bd0e26b2c311d83 +3812,1647d9ee18b908c4 +3813,791e16bca49e27bd +3814,0dd43e43b027972e +3815,a083ef555d609329 +3816,257b3f66bae96627 +3817,775966da50496bac +3818,a3e630463e2d98f2 +3819,9f1d7266ad7cd04e +3820,253a3f52d65d73a2 +3821,240ebb501070ca06 +3822,87d694d4dcdb487c +3823,ad53bad3375e703b +3824,1e6c4f5e924be65a +3825,8fa36a7074cd5b33 +3826,a63ac48cad5f639b +3827,2d97c3f902133b85 +3828,de7903ac3947e5ce +3829,60a988bfc42c01a7 +3830,2add1f9c533dadc3 +3831,8a2cf075cf5faddb +3832,42c1bfc0f9e9abe8 +3833,c8a4774e9781b598 +3834,21d5c00f9c386d75 +3835,5fa0dac507e87221 +3836,b4dca46a99174659 +3837,73c2a96b4322bc19 +3838,24dc1f23ae64120d +3839,75f00a226b548b49 +3840,a1b97280ef26aca3 +3841,e0c387746d362642 +3842,5a429ed378201ea4 +3843,4546c074b5e0be5b +3844,846dd727bec9a524 +3845,3e7bcd344668ec5c +3846,a225a18f3e999ecf +3847,4417ca3c50221f40 +3848,f1323793f484a678 +3849,c920dad58181252c +3850,af0d502b24eae634 +3851,4980a3c6cc5ab6fe +3852,5d190f3793e84f11 +3853,c3870747156b3112 +3854,75a0d501826e8978 +3855,154051d782950631 +3856,441090eb6926df35 +3857,9541cf922f5ef464 +3858,f94ecd0cc5e33fee +3859,da934b6ba95b43bd +3860,b1b834142ef6b1d9 +3861,2835655660de53ae +3862,732625bb906ce80c +3863,8116808853f413b8 +3864,b16468a2cbfbcc9f +3865,1df22e951cac992e +3866,e8e58371abcd5126 +3867,6cef1f8ecd7fc7f2 +3868,49e6117f2e084338 +3869,98a5d1197125dabb +3870,b2505208c575b022 +3871,e257139a1b56a501 +3872,12a67e9b0eabab6b +3873,22b78801f48ee0ef +3874,1bb5331b21fd7a0f +3875,85cc69e4bd49dc7c +3876,4ac0c89e99a2d6e6 +3877,5f52777e5c872e8a +3878,a28642448fb5c013 +3879,b7abc78cfc7404ac +3880,b5b6b8428558b930 +3881,5223b9f143483721 +3882,3076b497390e851d +3883,20d1a3d82da7b8c0 +3884,c9f4423c4da03179 +3885,a829f29a6c8fea64 +3886,46310e81664ab895 +3887,e58a1f019ddfdb12 +3888,f2b90a082ff54383 +3889,0e82e0194b5f48ac +3890,c315125c530101ac +3891,29e4227bd4bdc8d1 +3892,3cb300363419bc3d +3893,5726ec847ece8f82 +3894,af92f2aa9b355be3 +3895,a28658ee811dc15e +3896,6d6c5bcd73038ddc +3897,20bfa6b0fdee1170 +3898,27bd480621a0019c +3899,6a1d27e4f6494ae2 +3900,0c14414ab5bc8006 +3901,e460cd3f205ee2bb +3902,08acd53704593963 +3903,ce3b774474d5ec4f +3904,fe11133e5f1dd42b +3905,2811f54a8461f04d +3906,cb06279ee2a3977c +3907,efa0becb184c716c +3908,b7ddf912f5692e3d +3909,0a8b93b1f78742f6 +3910,fe65614f7f6c9c71 +3911,8a4797d0ba77cb84 +3912,bdb459167abf1f56 +3913,cf4cd61408f93e84 +3914,84027eb44399781f +3915,a5481ba3d7dfb328 +3916,4ffa307aef0a95ac +3917,a511ed3b52731257 +3918,48441094ff94d542 +3919,ecccb401d9ffe358 +3920,1658499a412c242c +3921,602c646c15f2661e +3922,e11eb412a0cf17b5 +3923,7f5fb0e732ee634e +3924,c7cd2110f6970121 +3925,16e1468c1f04aa9c +3926,1724281a3c9a58e9 +3927,a6e8b894e1874fe5 +3928,ca7c1437f5d662e7 +3929,a9f03aa91478ffed +3930,aa86d6051e488638 +3931,c942c6aed3debda6 +3932,ff7074f480911b02 +3933,28de31c240a5d8aa +3934,d97280ca74eec414 +3935,e14551965c873911 +3936,71875f152f1cb39f +3937,5d271ca9d77fdb41 +3938,55744f881a93c7a5 +3939,1891da08c916b885 +3940,53cb0b527bc64df9 +3941,e1637e69bd941608 +3942,2de3915740b1d5ce +3943,14734086b3c782f0 +3944,50434589642c759a +3945,95e20469721688f4 +3946,c09ea44cec8badbb +3947,32921704c2f0272e +3948,d1769b38c5e0ff50 +3949,d0b7879edfc8edb5 +3950,d64c7ca6a89d5a60 +3951,623a6afab4037adc +3952,a2c2ea7712e5b3f9 +3953,fcd35f0321256a4a +3954,bbf8e452defcfb6d +3955,45bb9992321bbf8d +3956,eec118b2329dba7f +3957,d036179a0cb1df76 +3958,305401e084936c8c +3959,8c9d916e21385ffb +3960,47f5bbfe95bc8d0b +3961,85a904028f12ef58 +3962,785446bdbfc3b9e3 +3963,ff5f5a0dfb86a470 +3964,70e7e4036852f65c +3965,7ab25fde761999b4 +3966,3806cb23d4372bc5 +3967,8e62f4524d92495c +3968,b7e5756e43ac20c8 +3969,73156ac8fb139cc0 +3970,336e564318f1a403 +3971,493a04f5e1417417 +3972,3e94ed3267d41de0 +3973,def77c7d5b78ef4b +3974,c69c3611c3b20746 +3975,dc2f97bafdbb5070 +3976,186d34fb47134f49 +3977,f830471f8f2dc1d3 +3978,ea96834b054abd80 +3979,4f426eaa19bc85cf +3980,7bd3b3b69355987a +3981,12be4d1a98c4ae14 +3982,5973fee84a4819c0 +3983,5d453dd35a36a483 +3984,d1484faf21430a3c +3985,9b669d8145a1fbe3 +3986,df4e6ff0bf25a911 +3987,e6a951429dac2ab6 +3988,5b261ee2234f658c +3989,eb71e916bc39c044 +3990,2b97e0b9ded909e7 +3991,88442dbfc1b07657 +3992,2edf564c6b73fbe1 +3993,0ef783aca1ccd513 +3994,96d823761b4771b1 +3995,393fc52093f23608 +3996,34eed40ecd89e33e +3997,386f0e191680dc6e +3998,116b810ed8bcf71b +3999,c85b18aacc9eba3d +4000,ef83c63e8c87ad3c +4001,8a09af6b9c9ba4b1 +4002,98eadcb64d709b96 +4003,da4d3d322d0225df +4004,c3e34e4aec06b251 +4005,ab6da0d0fd988e88 +4006,239900e95d872a5c +4007,68c6d2290d072a2c +4008,5f8c29d8d75a6a76 +4009,210026f763b24c39 +4010,33df3b4382cbde66 +4011,34497078582ed946 +4012,8c9675db6d2f81e4 +4013,872ae5f60147cb0d +4014,5cbb4137cf2fa2b6 +4015,a52ff89e03c82297 +4016,8113a4678dbe732c +4017,27c17a7491709770 +4018,ddb1c2738751e31b +4019,dd612f32ee6f1a92 +4020,b6d7e269c99c3685 +4021,eb9b3f246a66d9fe +4022,9ffe38ef95047475 +4023,64b19a7c4a46a10f +4024,e3f3bde5ce96b2e3 +4025,c26c595ab8079ced +4026,8790313f4c1df63e +4027,a6477506fb26e570 +4028,e4c084dfacd88c83 +4029,877fb042bb6f2884 +4030,f4c779604ea67527 +4031,0be015bd8cdcce5d +4032,0a345f518c21dd2f +4033,485008c98554be8c +4034,1e39a911da9bf232 +4035,e48ca9dbc86bc1c7 +4036,a96f1647478b6672 +4037,8170646360dd5ecc +4038,7b6c1498026a9997 +4039,51db179c91705b38 +4040,1560f1a29cdea204 +4041,7db1ba7f33a39dc8 +4042,a9bcf1b60ac6599d +4043,a21d7b2fe4c8e609 +4044,d46990d23ab85568 +4045,257a1e31fcc2ee20 +4046,be7933b2f22ae461 +4047,e621f40b7b7bbbf4 +4048,65d0c298d119d768 +4049,9486780715ec5475 +4050,1672c127945220e0 +4051,8b07d67c52118b01 +4052,c88ccc547355bb3f +4053,aded24d5cdace938 +4054,7cd69a6b024d0c2c +4055,dc40625c017ba828 +4056,ecd5c4a0d655708c +4057,b4e88605f3aeadcb +4058,326e6a41fc4b589d +4059,7a4056c13491f0ae +4060,2df08e3236188fcd +4061,594d4d16a2730697 +4062,13137856e33d6726 +4063,a57bd9f87f14f09b +4064,76652f35f0b87966 +4065,f18d91ca192726af +4066,de26422ed54d48a0 +4067,a7d2fdb7b40424b6 +4068,7773fc181e5c1e66 +4069,0f69c0a4b00bce9c +4070,a4051c6d9d5bf98a +4071,ec1e4a4a1d8ed6b6 +4072,ae01ff2c2afcb17b +4073,ab1553cc15d384fb +4074,a83cdc1a30eae687 +4075,f2f8b31a2b8304e1 +4076,684733004f0e1870 +4077,e96be756c5c96287 +4078,82d01d0de133055c +4079,a815ed6fafd6d0d3 +4080,c273b92e686a7f5a +4081,b265c2dc6e25ee33 +4082,735e72b5afdad1c1 +4083,fd7fd4ab02f1c772 +4084,ab57e6d19c8ae378 +4085,278b08c1dd43a8b3 +4086,fba6216e6da1057d +4087,908d6d86634e691b +4088,ca082ee22a83eb7a +4089,1f6ae21a7f0b83f0 +4090,e58178aeec02533f +4091,0d9b89e99fcaa417 +4092,4fddea9d3a51c5e4 +4093,68881fd90e1ef2a4 +4094,3d2ac44ce26a5434 +4095,da440c157b08d277 +4096,7841f956ed8faefc +4097,9752f783bb0ea480 +4098,25b0c77e5510f96b +4099,c23808ff30372505 +4100,0a19fe556b844036 +4101,1b7319a3403978ba +4102,a21c938e437af4de +4103,8a6dd473c2b3f35e +4104,f73b2d29cdae9109 +4105,084f827e9be749e8 +4106,ecb3faf98452caca +4107,3701e20c5a775415 +4108,e5e0c14087d9875a +4109,07bb498abe33b360 +4110,ac27f6ea7f223140 +4111,fb8663854f03332b +4112,cb55841c50952add +4113,f52c120d4ce53dd0 +4114,9bb1a9b6ec69c474 +4115,24df92b1b395a161 +4116,5ff95073dfd1cc5e +4117,b4d02fb34c4ac1eb +4118,f801eb5a96edd441 +4119,7f11a5bf785e49eb +4120,4e0f54014bf4db16 +4121,5fe883a60a302ee3 +4122,ba0c8d185a51b55e +4123,c0f8be6bcd5ef6b8 +4124,95632a9eb0115c5b +4125,4e6a567cb18657cd +4126,1f0ee899973b4574 +4127,2dc3f1c085952e79 +4128,fb23f216efc5f330 +4129,03a61438d5b923fa +4130,ac9de4d8384b1f35 +4131,615b6302b5116b03 +4132,d56ea2c2f801119b +4133,5fa642fc8000523e +4134,d3fa9ab188c21f76 +4135,e132fe11c041ba8d +4136,3eddbce42f0588d5 +4137,7dc8dc9031c69e90 +4138,d1fd9321bbb2b6c8 +4139,a4b5c9aa281a24ba +4140,7a83d21fed44a646 +4141,10d84b9134c696e8 +4142,5cea9252fdd97da1 +4143,4708b4abb1bb79ad +4144,67ecec75d69e2be0 +4145,e87ffd41c1747adf +4146,b7aefea7feabd667 +4147,e9b37b8b7f22d437 +4148,d0a445348d10e305 +4149,11b5dc24183050b1 +4150,f847977b5d4122bc +4151,10c5c70f3907790f +4152,68065ba51c9f8efc +4153,5cc46425cec4687f +4154,aa2542a6077b3e3d +4155,0f158940311450b1 +4156,383a73ac3d2cf244 +4157,a6ec41c37a7bc749 +4158,e83459b6d410ac0e +4159,e4f8c93c180898c4 +4160,39b8174e1ff2ea93 +4161,a1b98791cf910c23 +4162,43651df6ca0f81f7 +4163,a9b24474462e3732 +4164,dceede68a393084c +4165,1521a627b0096e6a +4166,278bab6bf8ee9c23 +4167,e9fb28e65d28a601 +4168,25b6eee14d651e95 +4169,d7c2a34460d9e2c7 +4170,1a9dea83d2f315ca +4171,3ed8ed03bbb83760 +4172,a692b3112864d20e +4173,f43e91f63d24a61a +4174,650d0beb345998a5 +4175,9e6159205ae3800e +4176,9fcf02e4c2d9ee09 +4177,b84f0f23a860762e +4178,f991795d02a80d27 +4179,b27b618d67ad62d1 +4180,385c304d6a4b38d3 +4181,02e1c3ecf64bd3a0 +4182,1736b33ae8ae01b8 +4183,c618d6c6cd11b057 +4184,cd1d3d05b1a26109 +4185,2f7eaebedc49f31e +4186,20a1e03fa4564419 +4187,dca3b99eb140a473 +4188,190c16a3c7c0dffb +4189,bf839e3790eb124b +4190,69308de96e062154 +4191,21537c8793d72ff3 +4192,89234e97cc0d9875 +4193,66c2d04a7e06dfc6 +4194,c6847bd24cbe776c +4195,4912ea3185b5e513 +4196,0fc6e192196d679a +4197,f6f576e0f583fa7b +4198,7f02f3f542a947fc +4199,3bec84e55d423cda +4200,6425bcfe531a6792 +4201,72d1c06cf6ff2207 +4202,e40be10a51565259 +4203,d395814ae49a818b +4204,21e7fa641aba9615 +4205,ec59b2e1b4174521 +4206,40763d24133b0f1e +4207,198e0bd994368b6d +4208,bd2bdceb25f4b27f +4209,46324c6f226092c1 +4210,4ad48f868910cf2d +4211,18c1cc34e4f093ba +4212,f0deae0c629807e0 +4213,62bfbaa8d331d6f4 +4214,45293e21edcb972b +4215,c836fbed0c4134c8 +4216,803af8b9dff0d955 +4217,dd17c0c6b0d9f262 +4218,bdde070cea9c42fc +4219,01b9805c7eb4f65c +4220,67e086790f394f27 +4221,62d378e1e377b11a +4222,aedd1f1efb965520 +4223,f83cc1199fbff558 +4224,fc28ba0d87c75b8c +4225,dca01c2672c707d1 +4226,fa3f65c78b15154d +4227,e62fcdcaaab4c04b +4228,b77acfc2f20f2fc4 +4229,40907e904271bc68 +4230,21a80e4789a547b5 +4231,d6755748ae08cdc2 +4232,5612928cdb7d85d1 +4233,cdd6d9b135e74197 +4234,e7001efcc07cbf79 +4235,dc21b584484f96e9 +4236,158378d08be1068e +4237,f71d8cc7bcf0f73d +4238,2a14f9fd713171b9 +4239,d7ed02d3e4899a8e +4240,8db3714d8dac3f27 +4241,a51ccb9fb263c614 +4242,b4732a2648d950b6 +4243,140cf32e352bbc1c +4244,5170fc734ea1a3cf +4245,b5ade8e7cffc0674 +4246,bd770a1d1fe42827 +4247,5a115e3e895c69d0 +4248,5599cdd1e3088aaa +4249,0656add8a511b717 +4250,43a1e74a01d96f47 +4251,a9f13ce3bbc7d23d +4252,300605972413a046 +4253,ed233a9519ccec95 +4254,a608be0edb048c35 +4255,7eca41ea6820dc70 +4256,1607fb25fd2042e0 +4257,3358524789c0a91c +4258,e0209df9f1fe6a5d +4259,77cd0b58b5cad16b +4260,5225b9af32315295 +4261,84dd79e44eabdf1a +4262,6151ff074af283ab +4263,edca47b8bfb12235 +4264,d5796c91ddd57f9e +4265,e55dc13178b799bd +4266,d74c7c198b36b83d +4267,2828cf74e2c42281 +4268,8514ec172bf78192 +4269,06a3c4916147458d +4270,a59bc2d380a01a20 +4271,d9f8d8c34fb6d35d +4272,fee654099ff505ee +4273,d52171dbb925ed7e +4274,f369ab76a2f52358 +4275,225de1aa415f8d34 +4276,5d8d629b8fd20800 +4277,ce8068e5c70dca80 +4278,c1614a651d53ad3c +4279,b77e02a0094ea004 +4280,ec609e4f4d8d637f +4281,b998e2d5500f606b +4282,8cafd4a71732d89f +4283,59a95c5f64dadf10 +4284,7cca59495e9b8259 +4285,3f8594c8312593d4 +4286,d177fd8b538e96cd +4287,fdf60566a1576794 +4288,bb1bfdd5c84c5f04 +4289,f74b8a61c4496291 +4290,8d8887207993359e +4291,9176bdc79a67e02e +4292,05fb20b7bc391a4e +4293,eb1ac61b78b17ecd +4294,207aec282c6b9eb9 +4295,3d7420fa4d736b61 +4296,d7c8140ee57b5093 +4297,68796434f5d63a5a +4298,e0e0ae64e762b0d5 +4299,5933d066eb8672f8 +4300,a73bb77454d72df5 +4301,8d7001b9b5a132d3 +4302,4d9e49decf3cdec1 +4303,e6c055b654c00162 +4304,ff48ecc76135f27c +4305,594ad1b1569fb35e +4306,89a4d2eef2b99900 +4307,6ba7bed4d4230f00 +4308,3c60942f21f26f0f +4309,00e0e89ed0132828 +4310,d5f0c60ddab48898 +4311,b5dfe4319a9ef054 +4312,370aabcdc8ec7110 +4313,daaf5c295edd52e9 +4314,bb76f85c40a36e16 +4315,7fceba4683d202bc +4316,a24acc2d4dc96879 +4317,61354ba2bb7301d6 +4318,3d19cc2d8a971ef7 +4319,46b217cfd363b51c +4320,dd4ea7f7f9804091 +4321,4d1f392ef506754c +4322,0d61b9a9be0b6416 +4323,5e620c4e214511ac +4324,ed95546c55026f94 +4325,0c8106feec93ddb6 +4326,25117d561438fd9f +4327,01acba0c0eef07cb +4328,95286c55b52b1f29 +4329,d2fef48d80323d01 +4330,794aaccf2a7737c1 +4331,b2a0dbe28b5394e0 +4332,cc4dfc13e3293300 +4333,2a14698304bcec9e +4334,1b556c14e0ba1239 +4335,ec16bd5006096d22 +4336,cf0dabe69bda8001 +4337,c82c79d0fa24309d +4338,6ca3a083db538234 +4339,7b284054fbaf4a67 +4340,61bc022cbf82e331 +4341,74e423275f2249f3 +4342,603bad819813f5de +4343,d0c3b29d0cc78ab0 +4344,1cf6c559286c3ff1 +4345,9fd8ab0d36ea94f0 +4346,b487b112f8c9a464 +4347,f239a91ea45b83c5 +4348,f89487da8b0cb7a0 +4349,460dd22058d06572 +4350,7238a403c4cd9a5a +4351,82fd4fa802da8d68 +4352,0fbdf4a616687cd9 +4353,a019690e32ff0f9b +4354,4ca73d587a32acab +4355,0b27273ad2005561 +4356,038a856c4ee7ce03 +4357,e93354a755067296 +4358,6abf7943cc4b3006 +4359,3ed7e1e372765d3a +4360,ffa4fefac5bc4d5b +4361,2745ba1c8a15f679 +4362,1029b15cb51c6c6b +4363,705b4a9b1c39906e +4364,72d9df186e39ab10 +4365,675616e2fda7864c +4366,79826ff07c7e6123 +4367,f6b6917112e2c46a +4368,3b74c8c1cf962dab +4369,2c57bbb0f6318204 +4370,aa229060e384c197 +4371,1d1020761a54aa86 +4372,6d7c97dbee9c656e +4373,d678fa7cd03ef739 +4374,edf25df9f4e826f6 +4375,1649eadee5131e1a +4376,d94afac2b18e5c31 +4377,d4baa4cfe6e767bb +4378,e01c0409a9222203 +4379,0e7da1b726342a27 +4380,7223c33aa0b6ef60 +4381,8c74574f764fa486 +4382,3be7a8e2b58015a7 +4383,fc015ef779ae6488 +4384,a719c41a8f8314c4 +4385,1732749bfff76a90 +4386,c97c0686f75979d2 +4387,bd88909cb7932f0d +4388,b1bd4857a1ca6f20 +4389,462fd86b58ed203c +4390,2716262119a7e174 +4391,006f6be2dcaacf5d +4392,383029f46eda73c5 +4393,9b32d1253db7c750 +4394,04f93875843c70fc +4395,98145befa0d90c9c +4396,198582a98301b394 +4397,bacb7a99f7bb5374 +4398,b975efa5fd1da2c2 +4399,82615262066de6ff +4400,076a8ed4908404b2 +4401,7f47a963790529c1 +4402,160b59b5d08c9f8b +4403,3f37be15b9d74a64 +4404,cd3a2e41fc7bedc1 +4405,cc2029143e960d19 +4406,4b4859366cea4160 +4407,c8514e8b78bf013f +4408,bf8e55adf382e8e5 +4409,ff397a56d1e99525 +4410,bc4c29b44a799186 +4411,11926f06e2760ec7 +4412,084ea138d1e6ad33 +4413,d8dcbd591a0aea71 +4414,1b2aef0c6830ca81 +4415,f884725bb9b627a1 +4416,69e345ae82b61b5b +4417,85898832b59fad9c +4418,ef835e57ab6675c7 +4419,99ac0494e54f174a +4420,5c52b2346510197b +4421,21fb310009d8605c +4422,ddd37da880157789 +4423,3a94c4fb442b7c41 +4424,376826fcfa133c10 +4425,71cddc4a792954f0 +4426,19bfdf218f7062a6 +4427,75228242a6bf06f9 +4428,f973bc724eef6db4 +4429,05784c48fbb9a38a +4430,b401639b6da61b01 +4431,05bbe114d6f99bf1 +4432,22d3f6b89b4e0ecf +4433,d04d8b829b13027a +4434,113e6214e113fe92 +4435,320876ca67eb6e33 +4436,e0eab61e43943875 +4437,49c5f1e17c5daba0 +4438,25952cb3d8a22a98 +4439,cb3ae23661b39e31 +4440,612e0e798ccbfbe5 +4441,459852b04eade418 +4442,05c7d96f00803287 +4443,7a7ed8c60ae16b09 +4444,7a00156d4d6e4970 +4445,22c93544c35a8aeb +4446,e5ad4f0e651b981a +4447,8b66c01768f31f55 +4448,3d96abcde20d304d +4449,50ccea621317312c +4450,59e9a0d75a24c997 +4451,339f98e442e813cb +4452,2367636350066eb7 +4453,50751d3ac7096e9e +4454,53456f1cb42a331d +4455,74253bc6e797a273 +4456,74db826df98f5e58 +4457,3013955ea4c5d491 +4458,0d1e787f13e4ea1f +4459,a3c5a748fc883cbd +4460,0d0aaa47e2142430 +4461,08c38b5ee70f37d4 +4462,e8b2b8880922e87d +4463,b365c783e9c9d72f +4464,29c6e950722c7f78 +4465,a86a3d60be829b68 +4466,fd59a9325f1a33ca +4467,5f24b171efd29ac9 +4468,37cf3e99a102fb38 +4469,fd59e03c5ca6b42e +4470,df1b959eb03ccdc2 +4471,f7f48d041819ac6d +4472,016508e853b6ac7b +4473,d8065ad2b8dce74a +4474,d8f7211797c7daef +4475,864a80220458adb3 +4476,21ebd231e3b723b6 +4477,261d43f0f89de5e8 +4478,a8cc90f2490964f3 +4479,058ed31ae128dafb +4480,70943352dd10d5d7 +4481,0d2407a1f29b43ba +4482,37be7409bd696e32 +4483,ee93df06e84b5561 +4484,c1fe7b3c37564647 +4485,d14dc0eba90cf594 +4486,6a5a3413a873e465 +4487,c31903c2c093afdf +4488,1f68898202f38b71 +4489,07c1a4a5d213e683 +4490,c30faa92fa3ebdae +4491,28e337cdd334462e +4492,639dc596c3b29755 +4493,316348f2afb70215 +4494,4ca650eb8e164c24 +4495,2bd2f88096c7208e +4496,6afcca5ad4704391 +4497,61d1f503f4f180c0 +4498,a5f20d0cca75c0f4 +4499,d884a4b16ded6458 +4500,c8f9a2e790f55a20 +4501,60183c3f5949fcba +4502,7484382588df7a6c +4503,8d3a5d3f55510f72 +4504,0b5374927333468b +4505,b11239b81bcd7621 +4506,c33a7b62fbee48e3 +4507,284833f0d8328658 +4508,efc31ddd011398cb +4509,3f6780108ba99b7e +4510,31d87d66227df0b8 +4511,db97a86913e51155 +4512,7fb652c02e2a23ca +4513,de9c9324522c430a +4514,670d2b28f62c3c60 +4515,7ef562049a93f886 +4516,a2490fc7a27808b0 +4517,a4214b7f0617381b +4518,43d87a0d444c2e99 +4519,0bfe6b58ef5fe16c +4520,702e5b2086d98129 +4521,5f850902ead92c33 +4522,6ff60b40d3b2e946 +4523,4d33d63af1c5878e +4524,32cecba4b8a6059a +4525,e96d220b58d659c4 +4526,ca4c0d56741ba185 +4527,b41434ea8913fb9a +4528,981779a62dd9660b +4529,24bb0cdcc79331d5 +4530,ba2e45c1bacb9c0c +4531,5146072842bf1b16 +4532,700a49a3a2959640 +4533,ddba3d547027ea19 +4534,1c4abe18d1def7d8 +4535,b01f6cc525b8d24f +4536,fa5508ecfe4f9a8a +4537,14b8ae9418eeaa49 +4538,12dbc8dda4ca4d4b +4539,20986da2cf6948d2 +4540,479ff063340ad532 +4541,479b5be0fd1f8545 +4542,69ba6aeb76ff8693 +4543,a8102e00ae0d64eb +4544,801e2a3df8ffd037 +4545,217b3ee9a55619a6 +4546,86671355ed9a7b27 +4547,059825aa0ad6cb22 +4548,f1362992c085b3b1 +4549,06bd35007fbda2e7 +4550,b11a010e3ef73f27 +4551,73e1bc1c76261f89 +4552,9b015c7bb76567b7 +4553,bae41eb10048afc3 +4554,f8dd9a25072cd140 +4555,ea0ca86cce801a62 +4556,c60f31b18acd032b +4557,f2e232a3d15fd2b0 +4558,c440aa69ce897f59 +4559,bd597ef09828e790 +4560,05215809ba1cf2ea +4561,e9dc98c4019dbf53 +4562,55a31ac14ca9e055 +4563,6e6433a7a18fe82a +4564,39fdf6280e861406 +4565,5582005f35c1b38e +4566,ff313b6286ab7186 +4567,f24feb560e4d18ee +4568,84145c91fa2adc04 +4569,4af2835ae1737760 +4570,d346a14bfb7a0484 +4571,0e1f4d541d24ffc7 +4572,8b635f67a956dcec +4573,a448cd75e7b93539 +4574,19832ddf5a13ad05 +4575,f76a4bdeb9360d21 +4576,43122cfeb16eee9f +4577,91c53ebe23602b8b +4578,0ce84f610c8b669a +4579,9a5c5cd649201f40 +4580,f9091d672fc2c064 +4581,e84a491eeb6b973c +4582,cf8121814b65ee1a +4583,73215fe32ec117b1 +4584,d6014c2f9f09efcb +4585,293defb5644c14a1 +4586,2aa9b69ade482b37 +4587,55b063038876c536 +4588,612442995cf8b6ba +4589,7db8401ae16b1b30 +4590,4525f3d57c6117d6 +4591,592ce53fa84a790e +4592,b69e99a0d76cf8c5 +4593,b61b4edd0d45efec +4594,870ad0b308221491 +4595,81eaf4cc0ff1750c +4596,b369f3759994fcb2 +4597,9873f4dcf89d4d61 +4598,bf0c0b18d49fff87 +4599,886bc85b12a4f0f6 +4600,d2e96a3fcbbec76b +4601,cd18a3d4d0919a82 +4602,a1c8ebb4cf56df97 +4603,185bfebe818cec41 +4604,f4b5b58fbaea66d2 +4605,bf55c8f7b0d67afc +4606,a705ffb0df68be2b +4607,de6498bcc03e0b43 +4608,5c3d8d2cc3b3954a +4609,31e15cdd67d92e10 +4610,c3d0ca39ea9a5d49 +4611,f1754b2f82ecac0b +4612,faa1c0a3d3c1a6bf +4613,f727ff7ee0d2232f +4614,2bfe6b68c3a7c69a +4615,6a05fdd31601c420 +4616,f5420184d6285be0 +4617,57d113437f77f91a +4618,6afeb8431865ebfa +4619,6b018dffdeb4f6a0 +4620,f81a384ab6ebaf38 +4621,9326cea4f8056d2b +4622,a5c3bf00ed681bf1 +4623,1b3acb06590a61ac +4624,4b20424bc54c238a +4625,405a03b1a0221c7d +4626,b9c1e91fcd75e438 +4627,f8afef6e2454e86b +4628,d76e584ca51f808f +4629,c15311abe7106e92 +4630,1345640fa9ce2326 +4631,1a74542622b91943 +4632,0b6f74416a140f12 +4633,02b7824b1b23b91c +4634,a2d9493bf80e2e90 +4635,d7fcb8e65f1e08e3 +4636,14b0c69aec8273ee +4637,5a9cadb0431993a5 +4638,10524a63641fbb2a +4639,def37a1b3d9e7be3 +4640,db23cd99a880b108 +4641,2daccb932335daea +4642,4f1c0a5be4eb7516 +4643,8a5752ab009f2b34 +4644,f256c5b39c206006 +4645,cc5e569a47342daf +4646,0501520e1b2e8f03 +4647,0b142d7a8cb93031 +4648,2ad4c1064ae70dc9 +4649,ef7d81561bcd803c +4650,d4ec8db7d03fa8ba +4651,a337c6bdffa0d928 +4652,c40a40e231177d5c +4653,abd0008b60f8e60a +4654,26128e20bb4f82ab +4655,7d81b2f43a441250 +4656,81b40791b858f0f1 +4657,103b182fae48b2d9 +4658,82d75e2640b76dbb +4659,1e78b634e917eba4 +4660,fc111c234631e8b7 +4661,0ae711d7c7c9eedb +4662,38da3e72f9b91f38 +4663,6f8d1598c5757a88 +4664,01bbacf46ec6906f +4665,a84ba889c03d8eb9 +4666,d0fd5d8271a4d822 +4667,eec279a2c8ffe336 +4668,ff026696697093f2 +4669,5d5539370d38a3dc +4670,ee75202b256ad37c +4671,b971ee7c8c1fbbee +4672,8bba228ea7ed8d50 +4673,39769d154620c612 +4674,7ca4fd9d87b87a27 +4675,873e523e1c945812 +4676,dfeb8fd163aeb6dd +4677,742dbbf6b038e22d +4678,ad177749296fac1f +4679,9650d11ce067892f +4680,643a16a7e41c97a7 +4681,ddc12e15d271e2b7 +4682,5e5e6913cc27ff07 +4683,dd69856d11adb1a1 +4684,18751904841da748 +4685,1697bb20dbf17102 +4686,98a3e8cb1566ac20 +4687,dbf8535546bc541b +4688,55be5dfdd9801daa +4689,9e68d59bea6f596b +4690,3bfc21f44860526e +4691,12d9d49553503b2e +4692,350642ca29c63e75 +4693,c7503f51e2d1c92e +4694,ebcc2f3cd66fa647 +4695,0fc82c58d24bae6b +4696,6e8f04c182182df9 +4697,5d06bf1c5902bdc1 +4698,6108c2fe20865ff9 +4699,6d7ac101f1882049 +4700,4ca560421ec3b435 +4701,fcd55fda1a7a099b +4702,cec592dd160158cf +4703,c2f34cd74c7ce52f +4704,2a351caed3dae544 +4705,f9f5d1760e6c2fcd +4706,d072089aea51b5af +4707,89fd480d4d998cff +4708,9583b0f811b9ca20 +4709,09537a43f54b947f +4710,31a03b4c5ed0b160 +4711,d862d38486c0f9dc +4712,f336467319b9f419 +4713,8d78bcc87d29cb48 +4714,d4ab1906f73180fc +4715,0f1e4edad363319e +4716,d4bcd7a3aaddd659 +4717,0644da2a188f00a5 +4718,2b16b202a41670c0 +4719,8248d49f52d36137 +4720,6a6e098e48a974ab +4721,146494a4ad50cf3d +4722,15d84282e6526379 +4723,3499ce4bea31924e +4724,a425d60087eaaa7a +4725,6970bd0d971dc060 +4726,1c92d41c5ea04412 +4727,df15709ab5b91ff9 +4728,45d6daee7a81a60b +4729,3d0c3399dd0b5c4d +4730,ade11dc1fa24076f +4731,d27676a353060bc7 +4732,f18d46297b7ce146 +4733,e2a3b74933e46ea1 +4734,ec2a89b7667e8222 +4735,f6a77d21152508d1 +4736,c63e7c3741e1468a +4737,00186e516d29bd95 +4738,2509512c0dd0bd5c +4739,5166f9e9a3718186 +4740,6af2f6b817c867da +4741,78875f88241f9da2 +4742,5a9ff36c475adbd2 +4743,d43c4209094818f8 +4744,682266376ea31d4c +4745,4c83e72157cbee36 +4746,7d8cec55d7592175 +4747,39c2419e06d0e0c8 +4748,a1729ce57317dc4a +4749,cad23d213d862c04 +4750,b2f5a52876831331 +4751,1a775add2122ccb2 +4752,a5b518fd3cbb0b5b +4753,5dece07fd9129472 +4754,c344b143fb978704 +4755,f6bf3c93cb4152ba +4756,a610400105e4162b +4757,265746c04c3e650b +4758,7b17f5f95f26bace +4759,f5947b4dc1a4243b +4760,c26d7e66e6e2fbe6 +4761,fa8556266867f9b0 +4762,7f2c6edc63416775 +4763,61b081198cc44ee2 +4764,802c1397019b70f7 +4765,70446d47eb92b873 +4766,44378e785230bc36 +4767,2b47a3b1f4b85a13 +4768,f8316582db45ed6e +4769,dd1d1782626bb54b +4770,552896935eebf8af +4771,5b5ed88649608109 +4772,ee39ec7eae9af0e6 +4773,6c999bbd34e84aa4 +4774,4394c94a1538a22e +4775,1a42c57904336fcf +4776,3832191b8dd41e7d +4777,6855cb67414c84fe +4778,5029d90b8c8944cc +4779,8edc726845c236f0 +4780,70f425aec7515bc5 +4781,32d64d24e09d56b3 +4782,359ed5482bc403b7 +4783,58ed2fee0e66db66 +4784,dac8e55658a6f347 +4785,fb41c0bbd739617f +4786,9ee868eefb3db1e1 +4787,a7fd05d7d67e8fff +4788,a00c225c0c26c10f +4789,628eba87217bce8a +4790,4b013543c407c8c1 +4791,b140f1bc8ba2b093 +4792,77a2ec9f6adebe9e +4793,606a48355f676908 +4794,fbba0030ae0be5e0 +4795,c8c63f85b99cfa6e +4796,2b7aaf01facd3bee +4797,ebba813c91fbcbcd +4798,b3b3adffd834cd45 +4799,5b33f70d0643e5bd +4800,151cc1223b1a63d3 +4801,cb944e0bf33a3c68 +4802,38b00ed80b661410 +4803,a8455119e6efc9d4 +4804,b6dd49ee61888ee3 +4805,d3afcd3fe624d474 +4806,a6b8c94f9b1c5fbb +4807,9f2539c838a18152 +4808,32ecd454bca769f6 +4809,2f73d5ac19f74ba7 +4810,aabbb555853e89d6 +4811,820477b870f34d84 +4812,9e617aa423363ba5 +4813,7e6dd7aba546cf7b +4814,61ebd447ff227264 +4815,b12324709a09d34a +4816,58a62158f9ccee37 +4817,97035be9e3917f76 +4818,c9529e605e401ec5 +4819,f2d9793aa9c65682 +4820,71200c6c0a3cd0b2 +4821,84440bdf8492adb7 +4822,17fdf972cdfe8d40 +4823,bfe4fda8e5c39386 +4824,353a8f3bc9cac3fe +4825,d2d73a494c0955a8 +4826,3dbb062c1ecc4ca4 +4827,789de29220726901 +4828,4181b0fe346f2bd4 +4829,8fb1108376919db5 +4830,0e3c378790ec93a2 +4831,9d7700b9031acdfa +4832,5dd081401b1799a8 +4833,17a8bc2a04ac0af5 +4834,80163ae7e708352d +4835,71e91c6f4ed1bd09 +4836,06dab2b16cdb98f8 +4837,c171cb1264860cbb +4838,a8a5b08d2e96298f +4839,b356f80eded40e50 +4840,c4bedabe4f28a9a4 +4841,8f7a926140a8a069 +4842,165ffd1562020b9d +4843,c9d18910180da8db +4844,510b26a0c0c65fac +4845,aa467336ce7f0596 +4846,31d9ff1503d2c5cb +4847,216e9bead598bcb6 +4848,6bdb248a8006f99c +4849,cc118dee351ed6ae +4850,024d3b17e41a6923 +4851,4a4a679ae6b4a5d6 +4852,c1f3cee47df1f917 +4853,6dc9b5555c276b84 +4854,84aa25fcd4eeeacc +4855,7b0b5d2574a6c6df +4856,4df94d4d53d3ba17 +4857,7a88fb691b5ede8a +4858,efa234cd78fb7703 +4859,bde6d0ce58316c51 +4860,518bc433181d223d +4861,e17da52ab8698335 +4862,32fe3795643a17ef +4863,234b9e188d6a4002 +4864,cae91fd682c37158 +4865,7d3d06b181b95ba7 +4866,03501e778c67a9f1 +4867,8d8d7f8adb1ae874 +4868,dbd3099abb708a01 +4869,af3e2d5d27751758 +4870,3133e1fac5c747f0 +4871,37164ba3c90bc5c9 +4872,74c756536b420ff6 +4873,ccbd5d35eb96e5d1 +4874,e041561a51dc5ca0 +4875,b50d15143bca4256 +4876,3d92113e513432ec +4877,87459df27b2ef5ab +4878,c4254c9d0411d3a6 +4879,4675569b16be983b +4880,089a94926504c057 +4881,bb1ae808d0784d8b +4882,03172547f9256ff4 +4883,3c4adf69a848bdef +4884,7ad90470f279029c +4885,e158ef419a947698 +4886,2d9affe974d5225d +4887,c4d28889bb8f961a +4888,8023d801d068cc2c +4889,7349f9266ec8ce67 +4890,8e3eb796e039ea4a +4891,81ee7c2a1d2bf0b2 +4892,f377fced60ca2c1a +4893,1381ab8cf0089bf7 +4894,c7ae1c166842e9ca +4895,fc950afce519d287 +4896,51ff8e661b0ed29c +4897,0764824c6301365f +4898,19144e599dcdf5bc +4899,659757b46071e4d7 +4900,c62fc55ce25f1d16 +4901,9de0d58cf378e684 +4902,1c72d5e7ef40bcf7 +4903,5fc34784485218bf +4904,3b4a5953eae35437 +4905,87dbd8a1ba7aa9e5 +4906,3739bb87537a5254 +4907,a2dc4979ab9d6ecf +4908,8d54e4e0270ea16a +4909,2e270558c3347b16 +4910,3e807962bff772db +4911,1aeb36654a5b8312 +4912,7499bd7e5f21c869 +4913,48ac29901b7c364a +4914,87f5f920dde76f61 +4915,f824c273d2a0fe5b +4916,a3c5d2f12f5ced72 +4917,a8597900c6a2f95b +4918,f76198f3810b8e7f +4919,0d0b5099cd0790ba +4920,e9548a3ecb9335ea +4921,5c3164ed8374763c +4922,1fd5a5a8903adbfb +4923,5bee4df939fcf57a +4924,521c360df1820ac8 +4925,5ca01b8d5cc9fed3 +4926,bec595b2761279be +4927,ca6b6434382d44d0 +4928,d6fe073d5159c598 +4929,063f344851349d00 +4930,1d7a7b013551ff0e +4931,5734eae0a943d8ec +4932,e969e5155d2f6cda +4933,3d5c3448f823cef4 +4934,89900e8c92c0441b +4935,a4061f6c1476be9a +4936,d20955912c73f9bb +4937,aba3a28a7e795e64 +4938,99360c735efc8bd1 +4939,2e15db021de42b40 +4940,9b979d48c496d28a +4941,8164b1bfc2c6c00a +4942,a870ff4fb23b6db4 +4943,80b7dae2de3bfb1b +4944,da0b190d570dedbb +4945,6f9475ffb12c9a0f +4946,d246a1831513460e +4947,d72280788be5fe22 +4948,048178bbc5482a55 +4949,bed3f82d79e92c54 +4950,238fcb21af76be43 +4951,1c2bbd5363a2916a +4952,992c5e4ab3b8faf4 +4953,6a9648d643f42d47 +4954,1e281dcc961bb533 +4955,5d4bfdfafc588ca6 +4956,63008a3ade22f995 +4957,a920d7bfc847e380 +4958,f0e696f13ff7a8c3 +4959,732614d75b14a6f0 +4960,5fc7195e50abfa20 +4961,96087609b1ae49c2 +4962,1dfddb80628d7c4f +4963,d26b5811e0215f57 +4964,2757cf9e994d0a4d +4965,5c8559c518d5214e +4966,b37d3b3c4598df65 +4967,828e295b0cb95352 +4968,4de0397d13b8ddba +4969,d2daf435b2ffa566 +4970,f85fe600d907ec42 +4971,b8eeeffe02e74cbb +4972,c5976034f7d6dc6d +4973,7832134349f2182d +4974,adb67fb363a276dc +4975,af4f90a86d92d5ab +4976,439c5f7e6fad8099 +4977,3a4e45bfa633ed72 +4978,3792e29a38489ed7 +4979,fc6576c254a72242 +4980,b19b1ad04d277a97 +4981,bf196ef78128e939 +4982,b618080bb0be1151 +4983,f1f8aabf83af471d +4984,d9ce4fc8b8425c3a +4985,5957d453a9a29690 +4986,7b4800f0020a637b +4987,d1b39139b804fa55 +4988,c38b72f95676e939 +4989,1ea588b351cc2aa0 +4990,a8e2b9833953aa89 +4991,4d02f3b9ae204998 +4992,d96c493e8ff5bec1 +4993,c4addd10eb8b224b +4994,685abca463c2e466 +4995,41aa571f450838f5 +4996,74d51af1c9aa5254 +4997,5405d09bb224a171 +4998,7b244b1e24297e46 +4999,78d6732c7c5982c7 +5000,69509210ac9f8394 +5001,f3f74e4f9a010722 +5002,6183decd53ad9384 +5003,432db3cd37f2d99f +5004,557165136bf4f61b +5005,4cf75869ef85350a +5006,e87aaf0c46b02861 +5007,dc599ca9a42c824f +5008,d74b1309ce5d8e1e +5009,a99c9820e57832cf +5010,dff3ffd478b95480 +5011,b9adfc861d795b39 +5012,e6658e7a5b172c37 +5013,61dad7d31fa3c73c +5014,7651c8cb02a188a3 +5015,11aacef6d8ecdc8a +5016,1d8f28a3f3d3d275 +5017,0d755468a50e3447 +5018,4cf0564d3276b9c8 +5019,49fb41fb980c0edd +5020,7a60d0919efdd1ac +5021,63b8ed04a6ffefad +5022,8234f28ec4485a00 +5023,1d2125500c627fea +5024,6d744a01503e1696 +5025,1996f8eea48850b3 +5026,fe571c1b6d704fb8 +5027,b1e0e2049afb3272 +5028,d9ba2b316b271bc2 +5029,091080f2e3495049 +5030,12e914a14fecd060 +5031,e48d11dc985d9f3c +5032,9e71f018c59a5534 +5033,3bcfdce930310d37 +5034,fb0045ea2b6657e7 +5035,19d7b7259c3c3652 +5036,d953bc672bf8bb83 +5037,58b1032f7ff3f192 +5038,6dccfcf95ec73976 +5039,82e827417b08cd5a +5040,d8c5cac48e2d5c86 +5041,9069c16d2ff8eef3 +5042,e73ad9aa218b2b69 +5043,99d16cde46eb1e30 +5044,02ab95599f330465 +5045,a54a9014f1e1b37e +5046,38c4e1d8bf02271b +5047,5a0eb44001cacb84 +5048,e8d9538ae2107022 +5049,6258e0a550956b2c +5050,ef5723e121c6f6a8 +5051,72e2211cd036e5b7 +5052,c01354bf848dce21 +5053,bdfad848fbf3024d +5054,f774c91a22250dee +5055,fa20ab0a47adef39 +5056,d4cb384e8139cf6b +5057,7fec8290bddf7b13 +5058,f9a3b02f830612ea +5059,76e0928d0aa4a2d6 +5060,8a9e3f12f3839b2e +5061,72e220e773aaf6cc +5062,b39c5beb7f12758a +5063,d084db559512a6fc +5064,0ba6e9cb61eff2ce +5065,b053110755ab2b5f +5066,f33c8967130bfb93 +5067,c808a793eca9b3ef +5068,cab07fd9ed873ca4 +5069,7f069cde0f865ee4 +5070,643c9cfb92f8b6d1 +5071,5c376c949417d0e9 +5072,50c3dca9e0ec7186 +5073,f8251e758f675722 +5074,2dd239a5f667dea5 +5075,4fac87a3f3970b13 +5076,9c80c6903d4278cf +5077,71abc7c9d5df54c1 +5078,036cd128d11c456f +5079,c28677d9d85221f1 +5080,9f12ff15d1e598f9 +5081,5dadeca499d31295 +5082,2ade478e278d0111 +5083,24fce8784c18b784 +5084,31c8a8089891a709 +5085,b226b6b6d4538793 +5086,8202e0f5313a2f33 +5087,bd79081b9facf84d +5088,e46a6af271c0f216 +5089,338fbaf8f2020e2a +5090,f7060cdbfe05d065 +5091,4c83fc1010bc4299 +5092,4259e2cf734c8fb5 +5093,0cc9fa374171b8e1 +5094,6ccd6514f4c5c8e9 +5095,5a7963d364fe2e24 +5096,b40a6d462b7027f0 +5097,4e990df7c0eb307e +5098,3d38b95dd3e7b90c +5099,a903285182a1e7eb +5100,e4a562e69a5e6823 +5101,6584ca2def2f99d5 +5102,3523404ad40f1d18 +5103,cb6e60078d47b212 +5104,6ab5de83b057755c +5105,9109150c862ea2b3 +5106,8999460f363fa888 +5107,a9e97ce355d5c817 +5108,f0c2dad271764ebe +5109,4bfcf09c94cb5c9d +5110,ee2f44506e3575af +5111,ceef2447ee70505c +5112,73210d1d0e87686b +5113,4c00d9c3543d06bf +5114,921dedadec88fba8 +5115,46e775f05d15e951 +5116,ecc2b73e9d77e360 +5117,691d69831a56f7b7 +5118,e5dbb6e06835deca +5119,505ed034ad445fe1 +5120,36d23c512e7da2e9 +5121,60425f3617d50fe6 +5122,11c61d38899e449f +5123,d63ea9913b72921f +5124,4d5c16c5d4292e4c +5125,a402c302aa3de7b5 +5126,1b161060b1f87634 +5127,4e3bbdc2d4ca5cae +5128,3e2a3f6b3ebd65c3 +5129,c217da363b96bd48 +5130,ac7cbe00a307beca +5131,f3ecc58f350f7259 +5132,fad3742046ebc554 +5133,837305428e6aa9bd +5134,824f010b1013f30e +5135,b516ad9490796430 +5136,1af7c398b6bffa95 +5137,5b96132dc73df535 +5138,ef03ebbe218f553e +5139,dc0c73a84ee32cf6 +5140,58a58a155f0a8ac6 +5141,f362bde5e4d0952c +5142,73478488d6706a87 +5143,4bde1f8553fe7f77 +5144,2555a3a4ebd9249f +5145,e8f0fa36a2f0c9be +5146,555c9f1c4004c7ce +5147,788eb31de7811b63 +5148,0fe09590ea835f8d +5149,acf878cd866be7cd +5150,3ab0e5a964997c40 +5151,6c3cc4efa341ac7f +5152,f593412a8a67d192 +5153,8c3a2b85e67e4831 +5154,d7f66b4578d18237 +5155,0bcb3ccf04d0d3c1 +5156,3ff138d3e7225a76 +5157,f30d68c2da820f67 +5158,2cec1c9a96aae81c +5159,59e6398dc6536994 +5160,f206501b4ebdc6d7 +5161,d4832bfeba62fc0f +5162,6b3498d26fc05078 +5163,2608f0bfd304c194 +5164,e92a53ed2db58c41 +5165,c76e32f0bd31e3b4 +5166,246917201b6ef2dd +5167,7604c52d24098ae9 +5168,f3603803d5e9ccbe +5169,5316bfead4823c06 +5170,c3e7d560055f74f1 +5171,9ec856d015ec6adb +5172,24400f5a58cd8130 +5173,ab29231961776486 +5174,6c809a2be0502899 +5175,92b4a56d77ba7618 +5176,f834133743d8cd4c +5177,51530c6bbd5d2944 +5178,327f9de35710a843 +5179,006efafd5a7eb1a2 +5180,e2560581cd2f49c7 +5181,7cf9096aac00f733 +5182,72ce3dacbb445f62 +5183,37ea476911e9d492 +5184,66d8538830832a72 +5185,eb5ee50754216029 +5186,f15189fe0e658e53 +5187,e356ea7b01f3284f +5188,e68033298e07dbc8 +5189,76b343b076c71743 +5190,46eb34964caf7368 +5191,7d2702b4babee0be +5192,6bb7e0c0c7c6a956 +5193,1f032d03251edb07 +5194,7430816c79343c73 +5195,665bf417d728e40b +5196,2bbcab92d647bd34 +5197,4586ac35d01638cc +5198,da702d6e7e46a6e5 +5199,7f8cc94ff7c4add8 +5200,2936fe22fe0e6cd2 +5201,715da5d8b0d8d1c6 +5202,f8fa8095cc29163f +5203,a07cdd56149d6f9d +5204,709143fe610170ee +5205,16c788e8f2399b46 +5206,fbd68c55e09407d0 +5207,22da1113d3f08b10 +5208,03456a38d75eadb2 +5209,cd9f9e0cac5fb2c2 +5210,ac0df00862fa4075 +5211,303b3bb19acbbd1f +5212,719b1fc362867206 +5213,2b9bdd3844158c68 +5214,2200cc5e9a39ad16 +5215,07d69e3f2879b1bd +5216,b9cf450a90ef6678 +5217,3c521850d30e12b7 +5218,107c2a592bd02cf6 +5219,f8d0c774a2b5c955 +5220,1e48aeb09874bd93 +5221,a0dfa285886abaf9 +5222,e96610a2b48fe662 +5223,31949b8bc43f3b84 +5224,5d757eae68ed701c +5225,81365168d9adfcb9 +5226,0a3737ed20fea22f +5227,3145914d0a7b02a8 +5228,104c67671a6a0e2e +5229,6c68a70ba599df8a +5230,d44966064d3294e9 +5231,bc061423af1a3fa5 +5232,b19b8ae87385e8e8 +5233,4665760da86ac856 +5234,19d73e0b20368c71 +5235,7b8f4207e4ed739f +5236,d6de9e4eae286943 +5237,f853c7313c0931cb +5238,a90064c66af4cb85 +5239,f2047210462a578e +5240,d486baf63792bf29 +5241,82f58e78bd9d0cbb +5242,0936291759690307 +5243,4de711f7bd1c0f1d +5244,fcd7a5b5e08b28e4 +5245,aad6ca33cf3b53c0 +5246,d31f6b5e2627c794 +5247,be63efe25d0d7816 +5248,00ee0dc70b1927ac +5249,247fdeef80c94b1a +5250,e269f622386bf464 +5251,26fcf7208a4bd462 +5252,06a23c1adcfb32a1 +5253,edffb0a84f15eb85 +5254,eb6bc488cc88bdfc +5255,3bbc0140b0bad26f +5256,361c0a1e416f23f1 +5257,4eaa041a502cc062 +5258,c2e238e8b549b9d0 +5259,443ef99ddd6db71b +5260,7612479df56f9dc5 +5261,9e9472dddf48d39a +5262,cbc5fe46c7a8f3d5 +5263,c7adb13471a3f24d +5264,74e7af5a4b6a27ee +5265,14b8aaf5982a5b08 +5266,ce928f94a50a6e83 +5267,b2821ef1e8a051d4 +5268,90b65fc82bf5cd70 +5269,0dd20e6fdf331539 +5270,d8b5e01e36ce463e +5271,8d3b17939776c08b +5272,62374d19118fe347 +5273,77a09fde69a63c16 +5274,a914d5f56b8a8da7 +5275,229d3952e322e71e +5276,51b50df59439836b +5277,474fd74ac444c59d +5278,a8714782168d6c66 +5279,9ee6f87ef9dc84a9 +5280,6310cc91a6be50f8 +5281,d9b02ac2d57e7951 +5282,09653c5d76464fc9 +5283,bc7b00522f100724 +5284,80f3d38cd4b4058b +5285,e742f5cfc6a5a32d +5286,832ff0e7f2af2f60 +5287,dc3b5428269a9fd7 +5288,b9ce539a90e3ca29 +5289,8e20132c503f199f +5290,ee6d5788d5957948 +5291,6acd53617eebf72c +5292,19dcff38134d0882 +5293,282addbd5e93f827 +5294,fd6d6f95ce038030 +5295,8be64220a1512439 +5296,d5fb60408845cfe5 +5297,bb15783cd982f4a1 +5298,38a9ff36dcaf6178 +5299,56a5d1044fd319fd +5300,9528c76cce341ee1 +5301,140284cb30f94031 +5302,1eb9825c32c2af66 +5303,e6414fdd4357d3dd +5304,5fd64e4481bdb28b +5305,3118dcc33e53ea7a +5306,47c598a175a6f864 +5307,6988ea2fa3ed89ae +5308,8cd4efc415ca76c0 +5309,6585699c70570bd2 +5310,a83518a92d846add +5311,e5e61008a2e3cee8 +5312,f03c3638bdb4ef5a +5313,058ca6c01a353ef1 +5314,dfbdfb57deb3650f +5315,6780b3dd6c9e9aab +5316,d2d46de771ff8448 +5317,7385bf3c420ca555 +5318,723b138bf586019f +5319,b066db02398c7663 +5320,0763abee73873835 +5321,b42581203420f51c +5322,1a41e9d96777dde6 +5323,ab909e7fae46de1d +5324,53bdf6be6a894a70 +5325,a57886ed43ec0244 +5326,f6b0aa96bca011ee +5327,fb75ac107d87710a +5328,22ab9a9c8e4d19c0 +5329,efaf70f982774dbf +5330,5abfa0aa1d2aab55 +5331,b14c0ba61c069d39 +5332,c4f76016e3d89a30 +5333,dcbc2acc8a2a3211 +5334,83f3903fb001f815 +5335,df33eb007dadf4c9 +5336,bbb381a4fa554929 +5337,ac9b58e271cafc14 +5338,ee0e1b887e79e480 +5339,1e4ec7fdce586367 +5340,c3f83e073f492e82 +5341,a9e70b0f7a668164 +5342,0a48ee3b78e1da8e +5343,4041599dd2f43acf +5344,5633bdd5f7523557 +5345,b23bd5e4f8c75f9e +5346,2e157cd5dfd39209 +5347,828741708d2150bf +5348,76a16d8ac835d1a3 +5349,981fd09165d54217 +5350,6bd7ddfa84906d72 +5351,5b2aad5f899dff4a +5352,d6c15180b49d16bf +5353,0e8009b53fc605b8 +5354,ed97e3a1f49e4b90 +5355,5984232beea0b6f7 +5356,11409a0562a0b8df +5357,3b6355fcee1b9192 +5358,00a9573e15042b09 +5359,d0dac28998ea8dfb +5360,c2fb006f6212d89f +5361,0a3ff0dec6d9f7f0 +5362,54e0a96a70be33db +5363,5b9a8fea5961e1ac +5364,fa13deefc590cae0 +5365,125dd1285dcdbe86 +5366,0176f4d1c34658cc +5367,8d65866e7f100b2c +5368,a187af89d6873f2e +5369,7dcc0a39cded6f7b +5370,40c075628dfcb031 +5371,57ff268fcdbb79ad +5372,9c57b52267fbcbd1 +5373,b9cd10594908db77 +5374,4959bdade5c14026 +5375,699e4a5101d75851 +5376,754c167df8884005 +5377,4ae32baabce6f553 +5378,a531c3ccbfea3dd6 +5379,7f3c41d622b61a00 +5380,684844b0959504c2 +5381,26da940033e0693e +5382,eb3e49b6530d221e +5383,e1f00eb92849cda0 +5384,1a31741f41908498 +5385,3551425fae412d8f +5386,2a4404901ef6f96a +5387,12a229198323c49a +5388,c6b3e1cc2668167e +5389,8fad175603ff925e +5390,a44afc2d968eb711 +5391,50ab018c10e8ef6f +5392,1a198edc47a98e16 +5393,c8076c12fe037dc3 +5394,7db8669d9fc35b3d +5395,4dd6a23de921e820 +5396,b741ad6426842d6d +5397,028d126dfd34a96e +5398,d34d0f09bbb749a8 +5399,30d50cc2da5626cd +5400,33a3c651be891cc5 +5401,f8e9875aabc83229 +5402,0ee49f1f1ab9176d +5403,71351fe1cbb514ba +5404,56488ffa6e464efa +5405,40a35eab181a20af +5406,9e54ca6fff30344a +5407,74c7e46a0c5cc98b +5408,70f2779b39f1a333 +5409,56ed24a8aadaebbc +5410,46f9f786c3b91755 +5411,8bfc932f5c41a720 +5412,9aa0aee947a58828 +5413,39198073dfea63b4 +5414,758968ac4c55030b +5415,86016cd7f2d5c018 +5416,030615f488c799ed +5417,7f217140fbc60f70 +5418,f3c266f52caa8769 +5419,3d5d2680f16e263d +5420,4504069c9b129f5f +5421,7d2260717ed24ea5 +5422,38e1a1f2b9fd8a1f +5423,7057a3baf87ede66 +5424,2903c3fba7e66c23 +5425,fa860cf5c29c3fdc +5426,3d14591e8e57a6d0 +5427,c004267089d1521e +5428,202d3dbd7833d5b6 +5429,1d3a0e0a648dd416 +5430,ad7c8684bd61d9aa +5431,5c23790719dbbcf9 +5432,49753c5bc37cd837 +5433,470628029556a83d +5434,7152655271464df5 +5435,8f3bd1ac7ea0e1a6 +5436,0892dae79405bf8f +5437,04f35a632cf3d0d7 +5438,9c65c9b965fdf2b4 +5439,09224dfa98bcec32 +5440,85f55675ebfbb5e8 +5441,5c432fa491784944 +5442,65c4b994f1390555 +5443,73cd9bfcf2c1f116 +5444,0c05d2cd3bad3c05 +5445,0c00300e8c19df6f +5446,1b4bf5ef0595791a +5447,bae8076b1cfc83b4 +5448,f13902469f4c57a3 +5449,161fcd3287be045f +5450,301c55b23df8a3f8 +5451,1e6b03af8f5c1485 +5452,dc6bb62a68f32d6c +5453,4bdce425a5943a60 +5454,07d05c049f16d084 +5455,5e1073870daac70c +5456,d54aaff8d4d61c7f +5457,69442b422903d814 +5458,d009739f87949b36 +5459,f72cf66b6338034c +5460,ddce11b1773a55e5 +5461,a3399042c1db5236 +5462,5c0f0c5e383b1f40 +5463,f2917d41a9db2e47 +5464,8bab31a04f31c9b4 +5465,d19752d3448079ad +5466,1aeeffc029a215c6 +5467,737bf9a31c368a99 +5468,138e7f46a8e8df0e +5469,df48fbded8753286 +5470,27a0f9e442acd7f8 +5471,b8c4426dd32dba95 +5472,b2a3a0bca693ff13 +5473,7cf7fbced79253bf +5474,7230dd239f1543a4 +5475,fc50f2a5d4fb3b0c +5476,f6bb1fee58ea3020 +5477,f42979e02c8bdb58 +5478,be16eca64531edf7 +5479,a17faeb159226f60 +5480,6e541d99ace67e15 +5481,baefc2a644117573 +5482,ac1ab6ffd283ac2b +5483,f6361ed14bdfa3e8 +5484,013dc5f9edd2a320 +5485,eb3202cb951b4960 +5486,be511a206f5aa4b6 +5487,a0744e9f0b965b82 +5488,68ba6e82f97614a7 +5489,ad2f0279098a6cad +5490,a8a97738469dd8d4 +5491,13f0a7d4e7e3a06c +5492,871b1d501c1f3912 +5493,257558e16341fb81 +5494,042e9e16933f415d +5495,944935c55b788916 +5496,dad7f8946f131dde +5497,381eea485812c41a +5498,eb4ea80c47eb8856 +5499,a944a47ffe0c461b +5500,e4b5ba1f28b439be +5501,8b3ce9329986ec45 +5502,2ea0c01fec1db5cc +5503,e284c810f5d9e96f +5504,f88effcc11776194 +5505,ad2e3750c6820c4b +5506,eda5d569e6aa6691 +5507,4aaf07a23d4ca8a2 +5508,0b08ff8aa53481e9 +5509,03c279d69947a834 +5510,83c961edbebc4010 +5511,4a3661f70f394fce +5512,04e664b667a1ad02 +5513,4119ef05e0bb6bdd +5514,7d85a303286d9690 +5515,faaf4b601b15218e +5516,97be930100231ebc +5517,f2b5d56002348359 +5518,3d78f8382b17939c +5519,6ce9ef1d3efe55dd +5520,7cc49141d5123e98 +5521,20b10ea38a20507b +5522,3d677e2e2059f867 +5523,72132224eb57e882 +5524,90a09fef51119535 +5525,b51a467ebcb6373f +5526,e1be4985a9247aaa +5527,6ca9863a73601e20 +5528,22475b0e683c6d5c +5529,6e2ba4e5805b2e7d +5530,f61a224b6fe59fef +5531,32789dae2d666563 +5532,9768cf96b62d6ae5 +5533,eaaa2f55d021ecb9 +5534,0d91e016b7f9293d +5535,35f1b32cbb4b2722 +5536,72203906baa314c3 +5537,5731e8fe811e4693 +5538,1034e7273809e842 +5539,4d66deb67843cf5c +5540,7657c12038d61889 +5541,c6a7d00f4f5592d0 +5542,0fc63c9292ed34fe +5543,e412cff597dd09ca +5544,7d233b1a9bdab6a3 +5545,99bff77de95e809d +5546,261a49974c27d7e7 +5547,5d295a7a09d12849 +5548,63fb5b09b330d464 +5549,015882efd70df97f +5550,1c65600ce89084ec +5551,2d3ba4a102df6b87 +5552,88963bfcdf6e2f59 +5553,76c14bdb48948198 +5554,daacc0787169c3a3 +5555,9de7e3a41acddb09 +5556,abce995be581ac59 +5557,e27e8d20731ce424 +5558,2a8a9e51bdb17413 +5559,e80fb78019346d02 +5560,6711aa11dd44fc76 +5561,af836a7f846bb6ec +5562,422489cbcda4ea5b +5563,debdaab5f6a622fe +5564,844f64a2a3fb204f +5565,decf9f1d5427acbf +5566,55cfab0dc65fb8e5 +5567,facc1320c162580d +5568,92c8e8920716381c +5569,be4f1dc9f30c27ae +5570,62dc9fe6b74b022a +5571,a512cf8d7d543d76 +5572,32f92867ed5608d3 +5573,b4c41083c2749320 +5574,0d80195808fec4b5 +5575,b655ff60136399e9 +5576,4f3e9f115c2745a3 +5577,e1b2601858cb1bb9 +5578,f9344caf7f058afe +5579,8642b2d0f04fe793 +5580,c4e326cab3516b71 +5581,c1d234cfab28d515 +5582,a4320b4931eb918f +5583,f7318f8d598bacb6 +5584,791a3eda54e92dc2 +5585,ceb535a9d009ce02 +5586,1dbe3d7214c95140 +5587,1fa5561e901e30d0 +5588,bf529f5b08fcf108 +5589,b9610597776b5cf2 +5590,1f14672efa8d19d2 +5591,144ca9a23e28f958 +5592,9a6300153f10294c +5593,09394a70c2069e2b +5594,10617e882e5a4c4a +5595,0b4b4cbd265a3caa +5596,ea01a002c74f8657 +5597,e8005ffffc0cd4ee +5598,cc04fae207c260f5 +5599,1265fe9360c20a0f +5600,2edfb4fb4430c2d3 +5601,fef0715310019a0c +5602,385b33972c4cf576 +5603,f8b4b082afdd0e9c +5604,b73043eaf392fe79 +5605,640f9f898d37daaa +5606,84dce0678ff8e33a +5607,ce1a91d280ba4e0e +5608,881dbea78c02c2e6 +5609,2d6c1cbbb762779e +5610,848ec7b3f939eaf1 +5611,d7538652b6792bbf +5612,9ff870a0c094ef1b +5613,6713663d8e73ea32 +5614,9f0fe05371f6c09c +5615,d5112a0dc9673646 +5616,18863fd945735e78 +5617,3984f8192410d1a0 +5618,24d3a8e776f26419 +5619,7c094490f2d00d1b +5620,44439282b63b4170 +5621,d2751753f450adf1 +5622,25d047a47e0bbd7e +5623,3eabfd28f74df246 +5624,87061f9cbecf09a9 +5625,f7949f4618d58bd8 +5626,c2c833ceca9ab5b7 +5627,fe77b2f2a3aa3fa1 +5628,e40e9769d6cfd452 +5629,453cc94a155ed194 +5630,8fc702a4c46b6daf +5631,f212a3e72c9e0906 +5632,51c38d469e477c55 +5633,6b8e795998db6cb3 +5634,7fbf805c082dbf31 +5635,0c47c8155b5d8f70 +5636,edf77be1ba93c5f3 +5637,3098edad829cd6bd +5638,e5b45fd298b2b611 +5639,dec9d87a58942242 +5640,be423405f9abc51c +5641,44a64baf134dbbd5 +5642,934fa2ec18ee32df +5643,afce6e94553837eb +5644,2a54cdbce66e63a0 +5645,4ba9ef77a674dbde +5646,c9e4e1c1d48a1644 +5647,7ce6005fc28bb28e +5648,4ad4400c8265857b +5649,fc464bbe676b1368 +5650,d80718cb71edc597 +5651,00dd092c52757548 +5652,7aa02366d0e02251 +5653,4d01db91586f3d65 +5654,8aeb2dc367188969 +5655,fca841cdd317bd6f +5656,93c5968d0cab5c28 +5657,1946942d4dfed1eb +5658,473b0ae645d0d1b1 +5659,b326651ffc5edec7 +5660,e5762b45941c0714 +5661,a3760182de176fd3 +5662,b44a0fed9dcfb73a +5663,cf09c7f6e6261515 +5664,3c887ebb8d5f20c6 +5665,c0ecfe87b7c3d236 +5666,f2c69bf915df5008 +5667,3f82bc3d74158732 +5668,06c8d61a41af280b +5669,6c61cb55ae5b2e8d +5670,3fd94453e8342c8b +5671,903630a156f6541a +5672,e32d525b9ed65ebf +5673,9ee38497cff91de3 +5674,847055b5f389dbae +5675,7d743d9b35ea41e6 +5676,599ef4731745ebe3 +5677,518cd1c438007036 +5678,10fb03db15166e32 +5679,6053c17a83173d76 +5680,66bb4e23335c0715 +5681,14b8f0d78ec773c8 +5682,9581f4c69acaa154 +5683,2b2e4a1052881871 +5684,858390c3f2fb2102 +5685,38e93e718228a651 +5686,165be49725d8635a +5687,f6bb61d7d2e54ffb +5688,5d19b5d6ff4484db +5689,f5672043c37412da +5690,29ec80414a6f55fb +5691,4861ed309b8add04 +5692,cd63921453770c73 +5693,ed20c1699d116c3a +5694,debf6cb1b01dcb2b +5695,5243533bac623486 +5696,31b3c6ba454b3a6b +5697,0734111d3fa8574c +5698,cbc32a8282700fc6 +5699,7362a92e1071dc15 +5700,edde5d324a4e1a31 +5701,f87565abf0a5a155 +5702,5ac0a25a3fd610e4 +5703,3f966a598f2b5b82 +5704,b582dde86de31a8e +5705,c1c58621f24895ac +5706,371e89f628dfc80a +5707,5804eb603a012917 +5708,0325346386c97a14 +5709,f407aa1ebe5d78c5 +5710,65926d603951ce1b +5711,e3da824cb957cc49 +5712,1ef009f2b23e3060 +5713,f0120a44281a2b52 +5714,8088f1e3bb0b02b3 +5715,cfe8eefbe3ca25ad +5716,296fcff8ac273ccb +5717,a0e7bdaa6285138a +5718,30a1e2b204bebcd1 +5719,b68fd279b593bcd9 +5720,9edac27cf59fc200 +5721,aafd8b8542170cbd +5722,e7bc7f5ee9ff2995 +5723,8aac13e6ac338509 +5724,9dfbb148bbd1c88b +5725,07656b13eec5cbdf +5726,a5d58d5cb33ff4b4 +5727,c79af9512abeb796 +5728,0de61a12bcddd368 +5729,8753d2e571b8c0ba +5730,b225eb5a4bfde699 +5731,3cb41b7189d85a46 +5732,40f3db2fd3169734 +5733,5c51b56de8f78a65 +5734,dff00665a814f1d0 +5735,4ba951a276ca8bd7 +5736,263415f755988153 +5737,ae86ced33aada6fa +5738,69f5d9a44ca82704 +5739,061f3aec2e7bbf95 +5740,b42f35a0c770ea70 +5741,fb057ba788714007 +5742,4a0bd8a2f3b797b6 +5743,e27774bd737272ba +5744,2a318f3109738f7d +5745,2edfe778b4efff57 +5746,35f6331bed525f91 +5747,027095bf72f1e152 +5748,70dafc9d04d1fc7d +5749,b8b8fd99ceb50115 +5750,8ebd7517dd956c5c +5751,4f065890547a13a9 +5752,7e3c617a788ada58 +5753,9292bba74edba97e +5754,b170378510ea5655 +5755,c74e34827fbdb019 +5756,62a8184f97c355d7 +5757,a62992bf302a1dc3 +5758,4a113398b2a6368f +5759,8b4ee97feefebd9c +5760,1b2353bcfebe3eac +5761,acbfa052e23c8c9f +5762,04497d1c670ec066 +5763,7330d411daddbf2b +5764,0107a4661f1c7e50 +5765,78aea5b3df7b3628 +5766,1f655c30f1d25cd3 +5767,b1a8b1d11a397ece +5768,96874c66f870dc66 +5769,e5ab9212267e42d8 +5770,f0358ddfd5ab9dee +5771,e8fbcc34ee29d5c9 +5772,0f80a00f3b1f2fad +5773,a7ae285c8e68a079 +5774,506bc3d30abdc345 +5775,a4dca05f7332f633 +5776,cb55d0380780334f +5777,cbecf72908f20d79 +5778,9e194a22c87f95cc +5779,a5be6e2d822c43bb +5780,96ae057f0c0a03fe +5781,e1c87d3708548283 +5782,35b3f6fa594ad5c7 +5783,c8ccd032fea3a8cb +5784,ebbeb99bc6e0e9ac +5785,a13ab00622a1f79f +5786,b11e8f8c440d64b7 +5787,1696bbd2623ff116 +5788,21889325230d6492 +5789,a98e2f163d0ac263 +5790,5cb2b4db692237ba +5791,a448ec622b5729cd +5792,c9e4794bbe193ea6 +5793,b93870eb1832c589 +5794,b71713ba55f6d369 +5795,fab633f9fa80163f +5796,5c8768d9c0839931 +5797,3bdf6cee5b2e2ebe +5798,164a2af7e5be35f4 +5799,aa98c7a9f8a19d72 +5800,411b011cdd132fcc +5801,d749112b3b2becee +5802,c2f6e26476a4b649 +5803,fc4693b5af966d14 +5804,52b20559704ec7a6 +5805,08d60d6867b65a7f +5806,ae9669cc0736e870 +5807,b6104cde7c68025f +5808,9ad0a13d41a58de9 +5809,67d65597ca92efb5 +5810,84b94c73001dfbff +5811,4a370f897f82bfca +5812,7930bf267a1cd303 +5813,90e05095194805ed +5814,1a1054ec2815ddab +5815,01ee089964199cbe +5816,a10ecf6b2724bc09 +5817,7ba9ca7667ae2c22 +5818,ce60ee0e57dd008d +5819,8d59f552419b0efa +5820,03536d543a718a05 +5821,1e0077a1dfe6609f +5822,7e67e58e900416a8 +5823,101927925afedb8b +5824,dcbd94e0ccd7d2ef +5825,b0b0cfae54c011d1 +5826,f890353a0778783c +5827,25bea92aa3743609 +5828,c0c5913068337b42 +5829,8737690e8ae5fff5 +5830,6db587d1269bc193 +5831,44d3ae5075c271ab +5832,bc07a3c2902f8666 +5833,ff3302b456d8c30b +5834,0d2dea06d8861c26 +5835,bc4b4ca8b4ecda32 +5836,dc74f8fac0420870 +5837,d1c0cbd5b1fa4d7c +5838,028bf94b92952044 +5839,3e696532cab99ec9 +5840,249d700ae40fbdc8 +5841,22b14407358255e3 +5842,9cf33079987ca844 +5843,a4d283abddb970d7 +5844,5fbdcc3d2d739c9d +5845,38548bd08be4862c +5846,e691f165cfeee2d7 +5847,46b44d963a1137ce +5848,8285327bf72ac48a +5849,8e5891a757f4d980 +5850,dbabec2f647bd680 +5851,ee7a7a6634911611 +5852,d6e48dd36d809fc3 +5853,932130c097d9637c +5854,fca168b7cdffd5d9 +5855,d9c5841b30a495fa +5856,de52de076ff0ce4f +5857,4ecf905d1cf1cc9c +5858,2b2ffd4a958a89e8 +5859,17df0cdc6ddab579 +5860,1c1963d89ec78799 +5861,6403a08796083dfa +5862,305a462c1429a596 +5863,eddb28c66693bf03 +5864,227d37f852e3adbc +5865,15226c4349396ed7 +5866,437461da2ec9397e +5867,2fead76b10204a0b +5868,ae781143f6daf982 +5869,accbef3b892c6253 +5870,142f9e6e62776c25 +5871,eea7e83d63df59c9 +5872,b6c6e8946eca9425 +5873,40fe7a75645e616d +5874,d09b3b82135503bb +5875,709ffdd1fddb8e00 +5876,e844c16a99841b4b +5877,a0417aef44f2196a +5878,9f8baf4c47e0aaa5 +5879,7e0fcf6fb9366194 +5880,2685b185419b9111 +5881,5ccd8c740fcef0e8 +5882,c37e568fdb0e065b +5883,dbb28ce52582970c +5884,988dd6e3dc6dc9b2 +5885,5132185a7d70343c +5886,d2dad6624d98cdde +5887,69495fdf185868d9 +5888,892deaa5419d6684 +5889,831dde9c92f4d981 +5890,2abb1d8453a597bc +5891,1ac5b0df01628264 +5892,01169b51e8e585ac +5893,563b976458f63b07 +5894,964f7072994d6020 +5895,e9f8aeafebb6e4fe +5896,2b7ed4d6fc48a0c1 +5897,62e19703896e978e +5898,fff85ecc1d891811 +5899,8d8ddbac103b80bb +5900,1e5ba375acf49c02 +5901,0aefbc4f8b8f7406 +5902,a0c1cef4f31ff3ab +5903,7718bf828a7a0b00 +5904,cb991f424637eb35 +5905,a4451164d7c05dce +5906,dd289917193bb988 +5907,dd863564c31d1d25 +5908,4c86660a57952e0e +5909,175699bf74b3bac8 +5910,e16d8a62a6fdb0ba +5911,9f0df1f2c2dea6eb +5912,30d692687859d4e8 +5913,9f04bf9dbd4f1aea +5914,bed6166f3592e253 +5915,6c570820f0d9f584 +5916,b81eea4394021edc +5917,7aa4e3a2afd27ce6 +5918,0123082d5ab477b3 +5919,4f7ea2dfac6e12c4 +5920,74b44a388137f7dd +5921,2d9bda29d20088c8 +5922,1eeb0f046cf49c0a +5923,ff9d7dac98deeb20 +5924,0e15f0f5b37ad7eb +5925,e9126d995c4f4904 +5926,56b2e2b59b64ad7b +5927,848cf37fb24d5528 +5928,17b2de46fa090a84 +5929,021b4cf4de4a6a06 +5930,5550ae6b04bec3dd +5931,e50b85102d9bd6c9 +5932,5d34d94b55351e56 +5933,07ac82941da63fb0 +5934,a7165558421926ff +5935,c082d41613263058 +5936,280c1a75905dc2d7 +5937,2dd1a0f9f6852ec3 +5938,2aa89cbeef016888 +5939,537a21be0ae70fc9 +5940,2c3aa60176e412e2 +5941,f107644ede05c8e5 +5942,d9b76bb27d0d5a45 +5943,9080859433d8f4b9 +5944,88b2e4ec80042967 +5945,eb4ad8104f5096d2 +5946,ab9af70bb4511331 +5947,e516e55e36d6b377 +5948,d1b43a5250597ce8 +5949,2bce4bfd83727e73 +5950,c16f6c5aef8b25ac +5951,67cd351a49ae6fc2 +5952,b94038852c6c7aff +5953,3e3d17dc3376acf9 +5954,39bec63f78e6e209 +5955,2aeb79eb1ea29a64 +5956,965f18270efeba6b +5957,805ca8e244c9e4fb +5958,8211a3ee2bee0166 +5959,0357e11031ef8a3d +5960,1710303a21fcfc21 +5961,545ed309b49932ae +5962,5bf86b3a88002c5d +5963,4a7f676bdf944a93 +5964,80127beee99a18fa +5965,a6b11b8e6b978c46 +5966,5a5adc2c9b94d41f +5967,e94a59a2bc542ad8 +5968,4998e4b28913adb0 +5969,376660ce4a90f647 +5970,f1feafb3fe0afbd7 +5971,315a1534bcf4634e +5972,03f3a87ac82a8c27 +5973,7315714a6897c731 +5974,ef2e13ca8a3799ca +5975,0827aa866e96eabe +5976,3fe2fa9dc83050dd +5977,f342ef6a6ca0b43c +5978,b49447f7c1983ea8 +5979,1c729f732df98a36 +5980,254bb342b92f78b2 +5981,155d78fc1c6ea071 +5982,97a63c616940e2e5 +5983,d209b39174344cd2 +5984,becf750f13306f13 +5985,bc7f21c8f27b798f +5986,f8b4e7df7188b21a +5987,fb4ff07c61f90d04 +5988,76e7cc8d26724ffe +5989,f13cf60c83eed0c8 +5990,b63e29b83f48f25f +5991,191903a946a9419b +5992,1470b95d3830a442 +5993,a46c54c951adfd17 +5994,5d9f970a0bd2a770 +5995,036a47dd9e26bd98 +5996,2e1cc2cd96f949d5 +5997,b926b546b7b7e7de +5998,abd38afc638c9379 +5999,816a495ea783f718 +6000,6e7f5089c9a9a161 +6001,41cdbf8997036746 +6002,4e797d0c2065f4a1 +6003,dc618c2d22ce1c01 +6004,8e16ba05a5ecff22 +6005,4480c520f160cffc +6006,b105e9467f19d6e4 +6007,9694d81e764706bf +6008,5f9f94529ad3fc76 +6009,79eb55fa12a3c7bb +6010,108cbd5d9eb3cafa +6011,b0c1c95b07d9399a +6012,421dee6069723c15 +6013,7fdd3195ab694d7a +6014,9ff83d7796cca65e +6015,62588cf8c1e788c5 +6016,eaba89b76edd3d9e +6017,b3ad83a85eba5d2c +6018,fe75db5a06db102d +6019,76d23da47e464b9f +6020,68496fa08c2a26c7 +6021,d7db311cb80625be +6022,46ec7595d523b176 +6023,f0f24f623fbcbffd +6024,2577898dc38e4b5c +6025,be72d56ac9ec942a +6026,a9f980e2fc9d80a4 +6027,c4c763a219371a12 +6028,8733a026a495b2d1 +6029,7b39c5a118cc11e4 +6030,992aca56251c18b7 +6031,0e85f8ca8c842f44 +6032,5cd9c29517fba1ef +6033,25fd372373cecf62 +6034,8e05c37dcb3bd1f3 +6035,40c076b6035d53fb +6036,37859ecbbff84664 +6037,c812e702182a2700 +6038,c35d419ba0b36adc +6039,df88ab3b7945abf8 +6040,73f97c54eebfb252 +6041,c25b5102d7dd7802 +6042,3cb87e47ab689eed +6043,0141479ad157686f +6044,041f97013a1868fd +6045,3f958213c7c80021 +6046,3b293d9045e05cc7 +6047,8ecf52683c53bdf8 +6048,c93fc15a720be766 +6049,74abb7e5eb64ec6b +6050,11f9f9e56960b177 +6051,dffcec109320f2c4 +6052,14e1a092649d398c +6053,0bfd0d0dde88dec1 +6054,822c72d4d12c000c +6055,48b379909b8a5e3a +6056,39544eaefba6a523 +6057,da2874790d9357b2 +6058,26b61bb52ff8fad6 +6059,2ce193cbff509a4f +6060,b31e561e685931d4 +6061,c6a55e0538ec44b1 +6062,1aecdfe2d48aedc4 +6063,4542a295c8c8caba +6064,e9e22a2237a9ec75 +6065,7114144e3417fb34 +6066,812a16aec75760f3 +6067,e3274d110961ba19 +6068,673c6e482cf57122 +6069,7ffdc119387e9ccc +6070,7fa58f186ff0d90b +6071,369af449fbfb99d8 +6072,ee29998bb2cf3c1e +6073,048e42dcbc8f582e +6074,09eb468d8c800d43 +6075,7b02c9050069121c +6076,2fd13b301f4073bb +6077,c642a5b0cf71d535 +6078,f66be874e7994968 +6079,bb025ed9a2fb1f34 +6080,6a84c69e152bf6fe +6081,f154869bc3c9295e +6082,0614758357fc1618 +6083,e5a2919a1d780bb9 +6084,d1d91fd8e7fb967c +6085,bc6a17b804115211 +6086,4068d3649afc52e0 +6087,05c40832ce080793 +6088,fb11600a5b01f977 +6089,fc6b166b74a37e44 +6090,b970cd3810c1a09f +6091,ff8c03e2ef211a13 +6092,6f38518bdea83d5e +6093,e59b40e6cd239862 +6094,b5d69fec405d9da0 +6095,c891b09634f4790e +6096,ad24eb0028e214de +6097,ae22fd2ee8089f68 +6098,4e8954cff256d91c +6099,4f3c4e67b05a124c +6100,80adfaf73f4fa324 +6101,281e0cca9a4807e2 +6102,6b2880a368c2c5ba +6103,2e18b7a098d20f11 +6104,ec6413454ee19a9f +6105,bc113a792962a66b +6106,12693add4f326099 +6107,d91d300624017899 +6108,8a2a4f362f04f3c5 +6109,799e6e4bbc1c4ccd +6110,38e031d02987b531 +6111,4751e95daa62d843 +6112,39a59331361aac6a +6113,552b5a16cd455e5a +6114,2edb5ba8d7f7b8e3 +6115,35d676a2f0d87573 +6116,180b4bdc57e4bfe7 +6117,85a9f72dc30eb3bc +6118,0374b28ab81caaea +6119,a18c48399ec94586 +6120,355640cccba34151 +6121,523af49b98e452a1 +6122,b358bba8fafb052f +6123,d6070ed70130ad04 +6124,ac1f2a557ed8147f +6125,16d57c2fa68fc96d +6126,2d66cf556f94f7fb +6127,b48baedde7cfaf91 +6128,d2656d9be33c700d +6129,acaf04c44b70ef52 +6130,71d3f5c6d604520a +6131,94c8993953c2226d +6132,f920c8710851ed97 +6133,644e0b150291f6eb +6134,755860d92acaab5a +6135,0c80bda0eeed4bad +6136,04c9c64001ce5b5d +6137,8ad4f82d1828cf32 +6138,3254f2ff689e8574 +6139,d6580badbfc0b236 +6140,d8b024d5ab423782 +6141,b01c3712be8a5098 +6142,00ad4aeb6ca01730 +6143,5658927f8d599ffb +6144,42ba3856db4d5646 +6145,a215c42b1b4dd790 +6146,c57dcd80acd182b1 +6147,c3dd6ef1b7704626 +6148,60a968db6cbadd7f +6149,9cb213e386a23cc1 +6150,df5db7b8b375b47f +6151,a11c610fa705534a +6152,58b5f17da6064f90 +6153,8b72194d00e1b765 +6154,2758a36eb8da1504 +6155,93c86fb080ea8c3f +6156,3cefeae7e1d00c11 +6157,c4cebd99b03a42d5 +6158,d8ca988e6e6dea5f +6159,7013bcc66ac5044f +6160,79c771610d8302ab +6161,004f5e4136725137 +6162,91a048bda44d5231 +6163,ba4c9d73cab28d83 +6164,43fed4eb184330b9 +6165,8c06d4047d8055fb +6166,9a692a1d84d3fed4 +6167,1d688631a251a8d6 +6168,49454a60a01823b5 +6169,250d1ce64ad3a400 +6170,cbfa897136717f8b +6171,36d3c30cec2c8e65 +6172,5a05bd03bf76e2e2 +6173,f553cc1fe49d025e +6174,75ff700add170be3 +6175,6cc3b56323c84aa1 +6176,3450108f63eeea9c +6177,9977bf9c0a6e8fe1 +6178,dbdd999cdd0ed1d2 +6179,cb30f0a5a9dd9d13 +6180,75d013541466cfda +6181,213d6fcf374acbc6 +6182,84cedb6932b4db20 +6183,7f4535608a199a4f +6184,cfea065acc137c62 +6185,a119bae8131caa1c +6186,9a0cad8a3989bc37 +6187,1c75928c3ac3045d +6188,dc68e4ca8a7c9376 +6189,8c864c3e457985de +6190,b21ddfe17e0d2cc7 +6191,5648eb5c809a1003 +6192,20303fe5fea11c14 +6193,bf2e0882197a9fae +6194,2b60421508111cb1 +6195,4d768691ef2160bb +6196,b4eb4360c47beb2c +6197,a8c150b112213753 +6198,21bdf37fc1cfc1ce +6199,616b616aba4652b2 +6200,645b10c87990145b +6201,287571e5f4e56aac +6202,d4269fac57892395 +6203,8d8ca308280c0846 +6204,edb01ffcc163ad5a +6205,92421c34e02dc300 +6206,90ef95761d857c2e +6207,3129e209e650161e +6208,dc86dea621ce9e0f +6209,4421df4ea388364a +6210,8c7e794b0e019050 +6211,c9681c82c5f21bf6 +6212,5b3e9ff0f4a4109a +6213,08fb34280eb42a48 +6214,93cda441881b73f2 +6215,a7ab5b5ee672045f +6216,a5f9bfa8dd923384 +6217,aea547402bfb1005 +6218,a9951af996259f8f +6219,c570927b1470d569 +6220,a7cf4199c25646ef +6221,3c55cd7649770f09 +6222,df0369dd31162a1c +6223,d9f6cd5152cd4cd9 +6224,7324e5609a14232b +6225,54872273254bfb15 +6226,b6ce95510413c278 +6227,70b01473c272e077 +6228,36ce3bf03750c502 +6229,8b8163d06c5699d5 +6230,05941af84dbbc906 +6231,c32d1ecab529bd1d +6232,9e15bee0610b85f6 +6233,1fa351caadac1785 +6234,45b4488abcc973c9 +6235,cdb005464df8006f +6236,f3ebee4eb6d11142 +6237,47d22bbcd28a524c +6238,c1dd94bffc30af94 +6239,2af53e0c0741fed4 +6240,01eacf3dbe4e49cb +6241,8f43a1b464e026c2 +6242,80774fd0aed2894c +6243,71321c9e1b5224d8 +6244,5715277910a0c441 +6245,86ff3725e7564e6d +6246,593305df10c51803 +6247,359f1ec87b8057c3 +6248,0cb9a9598c56be15 +6249,f0aa31f82d46e6a3 +6250,fa181b045d084b8d +6251,07bee7299191add0 +6252,2bb90189be04b7e9 +6253,95d784ebf097295e +6254,a6b4bccb486fb8ee +6255,609143dab7db4f2d +6256,4245652252d752e3 +6257,91d53ab69ac174df +6258,7e13220717cdd18e +6259,6d83d78065668f0d +6260,c955f2d2124d768f +6261,74728920ac02fc1a +6262,ecc9de07ba30b64c +6263,ac7a6401ee04f027 +6264,522243c4c6b9db16 +6265,7051e89b95353b73 +6266,0b72d1654140bfe9 +6267,59d502ca55b4aca0 +6268,c1df2c22c32ef63d +6269,0446b10263617f1e +6270,17bdafdbc0a3fd40 +6271,ca55b3d6ccd9a797 +6272,ffb5c7945ba155ee +6273,97a4456767fb495c +6274,d4754005551b3234 +6275,d8310df38a8d5875 +6276,d5700f74ea9c97de +6277,fc7c10b2874ae6d6 +6278,d27ac8860069abef +6279,9e2c5d9c7887f4bd +6280,fa2c222176c48a6c +6281,84f53aca279a716f +6282,c8a9def8d1a85e10 +6283,b0ba4eb109da96b1 +6284,fe1a4a90c87e3fa6 +6285,32ff7619b9ba6da2 +6286,e7d630fe1618b09e +6287,9683f8eef2d59373 +6288,773953f99d5a54c3 +6289,31e04d7ddf823b52 +6290,80a0b23a69a1aa47 +6291,fa996e307ed69bb0 +6292,2627ef3c4979c7c4 +6293,34b8c6d140b397dc +6294,43a845b8752e02ba +6295,f728fd2b098534ef +6296,32e54f0a52f3c816 +6297,923d48807b78a3de +6298,f02348c65ff8fbbb +6299,7e1f658fd491cdcf +6300,642d0f9025cc511c +6301,5add061c392b9c2c +6302,abbb939bf3c0322b +6303,0b3288ca638b6f15 +6304,06ad01f8c967fa3e +6305,1d7471852fb795a1 +6306,18892dfd68cd3f8a +6307,e9c196a656629d5f +6308,f4aff460b896cd1b +6309,aac8edd9c9088fb8 +6310,a903c433c1bf3007 +6311,d8776f0209508167 +6312,85c54195532f421f +6313,6457183ff38b5976 +6314,b38d6b3cfe04489c +6315,51596a5f1bac3d78 +6316,58c9626454bc4079 +6317,dc229dae6bb70870 +6318,549e217eceb4eb16 +6319,4535293178c9fddd +6320,57a8d5c387ebc860 +6321,7dd6c3fde15820f9 +6322,aa91f57077d4792e +6323,1d47a10931a1a510 +6324,b69388976bd4112e +6325,e83f506b42201afc +6326,00fa83365fdf1fe0 +6327,60ed0f23d763421f +6328,ee55da0455447887 +6329,9e8da74ff3920370 +6330,83644fc5cfd13be3 +6331,ae243289ccb699cc +6332,de60e4d56ea883b7 +6333,7002db53fbec1528 +6334,a364f34a2b56ea8d +6335,8c2cb410c30d3879 +6336,e12aeeefe4c1744f +6337,bb7f826e22ef2aa2 +6338,d6b8fc9f709cddfc +6339,abf1887a9bfec0e0 +6340,bd1298f98a1ffcc6 +6341,d74b171209c83097 +6342,e48e7fc834108228 +6343,0aa1eb5bc0caa631 +6344,99499a5045f47ace +6345,9a49ef998d32d4a5 +6346,10e19be441dc3838 +6347,a8917b368367415b +6348,4ed2bec1db6762a4 +6349,a0ad41f8f5ce3cb4 +6350,919b676d37f6765c +6351,7e5c8c7b16586c41 +6352,13f796b875cb2d4d +6353,2e073d5c0c7eeaab +6354,e40cbbb8beed0b65 +6355,f70fcc4756614f66 +6356,8e65b1bdc06a767c +6357,e603ad191bb8056d +6358,122ca8c9b1da49fc +6359,5b7bbec5d37f35e7 +6360,7ec3399289d4c484 +6361,5159dda451055f3a +6362,b4b879ded5c7051a +6363,d2cf670f5b0a200a +6364,438b1c20c5a67c0f +6365,5a3a0554ab5df86c +6366,c9a9b9382f75c12f +6367,9afc1ad86be246ff +6368,2ad5be81c14f501f +6369,b64566ec2ceaf908 +6370,80e489b4ba7ad2c4 +6371,a01f697d0e53886f +6372,818567e27513c770 +6373,35dc6e478fc4d0a9 +6374,b0345f60f314be4b +6375,f26a6b5391e2258c +6376,5830ef0a6701c168 +6377,165706db612ac8f1 +6378,714db982c1252a5b +6379,d75cce8525a32db9 +6380,3ba8bec5a211a850 +6381,53713e3e9991aaea +6382,c25150c063aef5d0 +6383,8efcc5bf82332ae7 +6384,ffb537117c3e3a02 +6385,0446b2ca5431b7bf +6386,e904c6a5552ecedc +6387,1020a269b1f67406 +6388,0107cba20bcafe89 +6389,74da5e4e7237e415 +6390,134667527f663c6f +6391,a5b44870ce3d7ac1 +6392,18fcb7969637a430 +6393,424eeab7aa1b2910 +6394,79d18c31600fc346 +6395,64d71a4d3706d4b1 +6396,976a0f2e53e079c0 +6397,41c0d9c8de0cb3bc +6398,ed090ba43c654e7a +6399,3c469fff6e5feacc +6400,a2ca23502d8b8f93 +6401,999ea3b270e0c54e +6402,9b3d419e989dc836 +6403,56e5d698c41e17f3 +6404,23e873db6e94ca6d +6405,0bc372f3885d3938 +6406,1fd087be7e31743b +6407,0bcf09101c5a7b8f +6408,f10bee7254f83bf8 +6409,62378c818915724a +6410,eb5d2a9759da0b40 +6411,384ed68e3dd3fb66 +6412,6f3e73614a0277c1 +6413,bd4a22d71579b0ff +6414,5b134c5818246cde +6415,846b00428a24ac81 +6416,081738475ab21b15 +6417,2abcba889e415f05 +6418,fb2b1bf398b773b1 +6419,3ddfc6e656e97424 +6420,edc6fdf27e3b432e +6421,9384b2fccebacd0e +6422,dfbd14ed22d02e2d +6423,6293ddac708f3dfd +6424,41fa0b45572abe5d +6425,f74b5bd7809c045e +6426,18f72b9eec115db6 +6427,5f9214c44d211a07 +6428,f78c35fcf0a2ed01 +6429,525cd46f6db463c0 +6430,f8e3c03fd02ce77a +6431,0280e02dd18948d0 +6432,39e40cd83c5656fd +6433,cdf47624f680ee14 +6434,904e622192ff3b73 +6435,a12b98bc1fc0abbf +6436,aed035f3c5e5bf52 +6437,539efcee8d5debfd +6438,b65c78beb50f7ad2 +6439,cae5f8282427f43e +6440,12f584b0a26c5c22 +6441,fce21e632629292b +6442,ea00a1d0ded92971 +6443,2fd3fd9a639fad0d +6444,4f3322a5fa8c305c +6445,48d3b9e5dda1ec50 +6446,948b7072bfa8a220 +6447,8a1b7b04966a5c9c +6448,c7c5bb3ef779162e +6449,1b83c29811f2dca6 +6450,f082b16edca44ae6 +6451,46e3f88a4541f3a2 +6452,0d91a548991d0222 +6453,f1c8ed453d0baf3c +6454,d5a29e587c75e405 +6455,35d9d6b8ed3e9a2e +6456,7103e8c199477b46 +6457,9f7d8cdf602ae238 +6458,0385053e9d1eba13 +6459,1985098ee3857d78 +6460,644382c88309d213 +6461,e010d33a62537915 +6462,ee426b2edb40779c +6463,75ab7b8983970e92 +6464,15582ec058424a23 +6465,3e724e6899209cbd +6466,225e111f11559cdc +6467,cc53fb5b08d8a7ee +6468,aa578879d76f94d4 +6469,ade721a136398ca6 +6470,a7e5298c1bb95401 +6471,81991b00313f7cd2 +6472,2fa62a146b7dcdaa +6473,78970aedc95dc1df +6474,820d82adc22a5c67 +6475,166efd995786acd9 +6476,207eedf5221eb6ed +6477,1536a1fda62f2066 +6478,4679d4b6ab093a3c +6479,2ee92214bddbf7d4 +6480,545bd1e0a027ec9e +6481,89eed0f84614ae83 +6482,aef94f6cd3015538 +6483,18b7d2cae35de8ee +6484,7495a3b9f681a900 +6485,932e9875ca64e60c +6486,3553682f536285ac +6487,2379c13a542c6e4c +6488,7d01527da6fd3e29 +6489,073d26bb33eea22f +6490,497a018782646930 +6491,80a8077c1217fae8 +6492,4370d954aa3a6f14 +6493,9becbac4d07703ba +6494,8883b9cfe24c3894 +6495,6903580a5bae3d52 +6496,c42ef7dd712fbd52 +6497,f649d1476d5fa617 +6498,dae20202f2b12903 +6499,e77dfd821b79379d +6500,7d9d725ba69e7757 +6501,00bafe28b35c7367 +6502,9d9449c5ff43d9e9 +6503,e972086c587994a3 +6504,51790ab9bbc39156 +6505,456e6c059fabdb12 +6506,ca7cc5770c2fb495 +6507,bc51a4f6402977ec +6508,531ad56885fa11c0 +6509,f5d580d318c6d7bc +6510,67cefe2ac726dfd3 +6511,607beb331e4cee5d +6512,7bbc545f85b53b46 +6513,4f813276b21b06a8 +6514,3a395743970177d2 +6515,e2e6ce395101ad8e +6516,571b6018fd535794 +6517,c952a30c43584514 +6518,bd063e2ea74c9fde +6519,ddef18d0637bb542 +6520,70e45a62c8562090 +6521,cd8555ad06b74233 +6522,eb6b40a379b7bf18 +6523,a3da84e69cc72bc2 +6524,9dad67f2119939f4 +6525,ccfc61373c1f9b2e +6526,e712d23d380df356 +6527,6397c745583a0bb0 +6528,c7a5b9bbc6c0183c +6529,c92f6415a5c87c5a +6530,6161951a50c052c7 +6531,c8065df37cb943ac +6532,a725b15f846d7272 +6533,b215b0368ee85283 +6534,eaea1bc177b24125 +6535,54855584a8576e96 +6536,15ff11d6db9d5051 +6537,c3182c04d9d871c5 +6538,413f89fd44011e7f +6539,ec672cb8517cc02f +6540,310318954d7d9575 +6541,c38951f7c1bbbafa +6542,0c2f4f113193d99a +6543,50295f4e2298faa2 +6544,2a1f2dd078a5c7f2 +6545,ff8d1518f402249a +6546,8561a6f80ae97a0e +6547,9ed053c1091d12c2 +6548,ccc2dd9556938a49 +6549,d6593121ade486a3 +6550,984a55ff1ccf39de +6551,3881861f1cabec00 +6552,55c6f50b7ba0d821 +6553,1482fb964c3767a8 +6554,26113f1273fb4fea +6555,bf741365b5505c65 +6556,b4dd918501c09130 +6557,424e16cb3b698c7c +6558,73ca9846659ad0df +6559,dddcb4253ceada67 +6560,a97e376cf53504fe +6561,acf38e38b2433f9d +6562,0b4b9f3ec53fdd8d +6563,cfa9d1ca53feda5d +6564,2bfd4a81a14d807a +6565,2f7831a4ff8837b2 +6566,f826437692c8577f +6567,1a729c67b85ea2c6 +6568,83f54d465603500c +6569,16748f588472f051 +6570,f00cb71ced893d32 +6571,f543c3cd9cae3e81 +6572,9f2bc4a5159d80e0 +6573,b5f1f80850a579b8 +6574,4745fae8c5031c85 +6575,3a58d390349dc6dc +6576,46da9f10bb5023a2 +6577,5c25502c24238a8c +6578,1103d9ab9a46d937 +6579,87c46d0820b48690 +6580,cacaa529c248aac5 +6581,58bef15859128ec4 +6582,2f4c4d52e1773ace +6583,6d60ea1579eba607 +6584,09439e54031515e0 +6585,3e1f5f3bcda991b2 +6586,6d6146f4847f2ea3 +6587,0e73ffd2b2cbd948 +6588,7ecbe9a8178c5649 +6589,923b5cef520b6dd7 +6590,c735eafd6ee679df +6591,09c23476a46ea831 +6592,45538b3b6f8a56c7 +6593,56d7d571d8226a8b +6594,8c55af10cd966303 +6595,47c91095601bfbe5 +6596,20c976247cf51e86 +6597,31fe0f34a3ff7e28 +6598,c444b33aed0b4336 +6599,ddd72b43ba002723 +6600,b4a4e7a52126d3f1 +6601,0fc2e0453fc4dfe0 +6602,81086c90beddf2b6 +6603,fb01ae5a2591f338 +6604,edcf7204e6ce334f +6605,885c814a6b9b9ba7 +6606,4f171d1d11681e65 +6607,221a53422af96f12 +6608,34bacf75158ca8d3 +6609,499a1cc6e67bf4a1 +6610,4e41c38f0c6d5160 +6611,7bc62fcf8b7f5bd3 +6612,8c2071f91b5efdc9 +6613,c5520aca5cbb9274 +6614,9fd6c8a0f2274217 +6615,3749d017c0d8e68d +6616,f3796eceecad33ac +6617,e0a232192119842c +6618,0430ab179f6ca967 +6619,878ba64405bd3d24 +6620,41f890b65ea8a24b +6621,fc6372ebcc47886b +6622,8490e9a172c2d575 +6623,b583999de156a6ea +6624,53eeb61af0a52771 +6625,3c788ae581a00cb0 +6626,66dc5e21ad9c448f +6627,00a48d64f4583db8 +6628,b952316f28c2fa5b +6629,ee2163d94e31f910 +6630,c411f9f85952127d +6631,4bf70340a8aca522 +6632,4c01ff8099d2b270 +6633,9172f92c166ad063 +6634,6b1cf482933b5cde +6635,8df307b0e0f97ba3 +6636,3178649fb61f315c +6637,787f8b1a7e0eeb72 +6638,70277ff3ee83263e +6639,1fed05da8a61558b +6640,61568148e5530742 +6641,632f77051969dd63 +6642,c389ca4d246faede +6643,ab74003eaff5a4f5 +6644,7f5af5835d77c071 +6645,37ca43f6afafb98d +6646,be31d5a971851ad7 +6647,510a4dc2b81bbcda +6648,50735b5e3fa2df2b +6649,b87b732229433c68 +6650,42fb1b71bce6e971 +6651,49c174e94396e3c6 +6652,baa4a6bfeb8e064d +6653,0703cfdcfeba096a +6654,c8de6e71f95631f5 +6655,111395903e5bf616 +6656,e6d7ee61b8777c45 +6657,781e89eb5e86f2a2 +6658,8088a6c650bdd2b2 +6659,617a6eca2ed19a67 +6660,de76c43bbc1a7525 +6661,5c070327517f2fa8 +6662,cc1f60289ff056c3 +6663,3d827707c2bcaf08 +6664,c2f8d575138a7e83 +6665,b8957d8fa7362c49 +6666,5863f09fb75b1f9c +6667,e30b412e114705ab +6668,fa61d53cba5cfd0a +6669,81bc04d40cc6a0aa +6670,1bd34b9797b8aeec +6671,1838de6ec24218dd +6672,46820f61c64f9aad +6673,025c2e8862f18524 +6674,69faba644effd787 +6675,eb7185d0494713e8 +6676,8b11809a6f1a0f95 +6677,783d1301d0f15188 +6678,d9974896099f80ea +6679,1252a91ddfa84aa2 +6680,30095e8444f47e19 +6681,32d38800a801d371 +6682,5a454a095dd71e9a +6683,e32426e75f671d2b +6684,d541cbfef6fc2fa7 +6685,1ba0da5271040c19 +6686,6f88ffa8c77a5833 +6687,c7b443411f7ca4aa +6688,632a1a0d183d0506 +6689,93c4ce02c07eabac +6690,c67cd731c81351a0 +6691,8347b7b8b0fdf5e9 +6692,91856649ab691137 +6693,0cf5a4a7b06b6712 +6694,baa42fec708c7fd4 +6695,44516c1770913153 +6696,ba992943550703f5 +6697,1a72638643ecadf5 +6698,d6340bca31932b12 +6699,6d9931136d993690 +6700,e74b50793b995b01 +6701,69af6f27d068edc6 +6702,01f0e0863480ca0a +6703,b213d5eea60ad604 +6704,d2008c295f216765 +6705,ce65e9eb00611e49 +6706,f76f7cfca6a88277 +6707,1a950b4bd09311af +6708,0c3f37bdd63eb63a +6709,2e3412932443b0b8 +6710,e8f812a22cb04c87 +6711,644c130220ac7e4f +6712,b2e08bf03466e9cd +6713,3f02166e2861a157 +6714,f49f871735d0df66 +6715,1674aa303c10f8d5 +6716,68cb417b159668f8 +6717,69dad18a41dbfb66 +6718,9ed5792f46be65f0 +6719,62ed3bbdabd89301 +6720,394c24663c7916a4 +6721,7cd00598beb7c8ca +6722,6c294ee81bbbed7d +6723,b614db8cd5c395b1 +6724,48346785567ba749 +6725,f7132bb442fb93da +6726,42432a346903204b +6727,9db2d73f1a722d17 +6728,df5dbbb8129a37e0 +6729,6efced8209ba7e6a +6730,3e1cebb6719a8a03 +6731,ea25593f4f40be8d +6732,28edd7935c2f69ea +6733,f09748e08d3c2deb +6734,228d5d8ee358d788 +6735,46d4796f1fada240 +6736,9b19bfd054cbacd6 +6737,8131caf4fe8e4860 +6738,79f5335a01717ff5 +6739,671f87e8c7c3167c +6740,d4bf2ff9f8e84e94 +6741,1f91508c2d6bece8 +6742,11420fef192486e0 +6743,39b2dc2b94f8e97a +6744,0e201307b8ea355b +6745,56e15ea497a70767 +6746,7a24bdc5dd13487b +6747,3e6e9db77df59c39 +6748,41859d8e00d835c1 +6749,08da3cf6fa82b13b +6750,3c4905f6d93d365c +6751,90b71b88a0afc5ef +6752,b3661f789ce17c88 +6753,73c542d327123dcd +6754,59bc835c54b7f9cc +6755,7be621226bb57737 +6756,f59e169496eae00c +6757,9f7c3af35c18fd04 +6758,a44b4b97fdc9a23f +6759,c71f58838ce68f3c +6760,271f9ce3b4d93adc +6761,d66e746104133fde +6762,e2b92efa38d97d67 +6763,1dd6246cecdbdeda +6764,95048fba3e3e083f +6765,d0fde8c95d1a8efa +6766,878e34815591406c +6767,a6f43d9815571d23 +6768,8d09f708f9bf5c65 +6769,ac233332cfe0c934 +6770,6692e9f5d16db8dc +6771,250bd4f58311b656 +6772,a686982345117ad5 +6773,9bbee30a856f69f3 +6774,d269d741cc81b311 +6775,3d99deab2aac743a +6776,5a22c73273cae9b7 +6777,7f8b075d42212d8e +6778,c8b31be7fcc4e7e3 +6779,cd881d035d317c26 +6780,5d862c1e461b22bc +6781,4cf39f7168c07c2d +6782,80abef1a5228135c +6783,062b96fb95d74fcf +6784,5ce172f65c94a61b +6785,848a062be4168048 +6786,8b4e5fb3384192d4 +6787,98d62aa557da6b84 +6788,92f3f65a012d333d +6789,a64f80c006e6aaf4 +6790,0b2422a411d189c2 +6791,8802dcdda55081e6 +6792,8ed7255a18b1a95f +6793,cb23c661fff1ac99 +6794,5ccb230bad232ec4 +6795,7fd7c86523757922 +6796,8fea2ce3e85f7aa6 +6797,8633c9237a29dc10 +6798,b153016c1fbb1a05 +6799,f1f99d8ea2f5cbba +6800,128c9dac87195714 +6801,c7dd63d7d120e1d6 +6802,e231a9a96bd956ab +6803,334d5ff80e68a306 +6804,5c0f00c35dee8207 +6805,8d5f1ae279bba730 +6806,00074b64b4dae507 +6807,8c13ab425cb02b07 +6808,e662c27619156496 +6809,f82b73b65e0b61d7 +6810,7c7cc0c069de8510 +6811,602d11e08c369f21 +6812,204a50a21c107010 +6813,8e85195dbd9c4dc8 +6814,79d601f03d625986 +6815,1a8df468bcd717ec +6816,28dd7785cc7a70bc +6817,c1e1bf0f0d0387c5 +6818,82c4d13a31b941ff +6819,5b9a610f2b93fd36 +6820,109e846ab0c7041a +6821,dd408f3af5296ffe +6822,4153113b9086d64f +6823,5ffb5a735ed7ef5c +6824,ad3a92a3297f24aa +6825,2c26acb52d8e4eab +6826,19328f6e17fa98d8 +6827,5e10baffc656e2e2 +6828,f86a2bc52083243a +6829,22198027db19acb6 +6830,6e0911204c3001e6 +6831,6226487a1b6a9d5e +6832,10f1cd68421d86f0 +6833,8ccabbc73be77255 +6834,52f314c936ca86cc +6835,4c8244415e6449fc +6836,4fa894a0ddf3ecc9 +6837,8721c547c3a1afa6 +6838,005b7ea9d7642a02 +6839,8220d3ab50522ff7 +6840,7da5cbc8b63199e6 +6841,42349675eb68110c +6842,4fe591cd4db528d8 +6843,30111623896faa6a +6844,54cd0cd38ff77815 +6845,bb20448342220dc9 +6846,3ca33ab7436e247e +6847,5ad0b143986da1c9 +6848,858a1fc81a77e8ca +6849,37e3cbe93159fe41 +6850,172ec76f8b935b73 +6851,ac44f1821d82c1e3 +6852,026db2bfed136d57 +6853,f152c8bda6f73990 +6854,d88193ffd20394c6 +6855,3a28e2a2d4a1cca6 +6856,3d17375c27eb5beb +6857,47d6a94b4c3aa501 +6858,f9de73580266db8d +6859,0deb7277861fefa7 +6860,e4682835ec9504b7 +6861,75a29f2312ca5ffe +6862,48918bfd541eafe3 +6863,0ced60ca05b9838c +6864,1adb335f77f459cb +6865,5e4dc32550cce0ab +6866,d77fc7bd2162aa80 +6867,462bceb6abfb30d1 +6868,0bb247a5ca004036 +6869,a139ee63d108d1ad +6870,231d86b07019f455 +6871,f28da2881def7fa2 +6872,18305d6603e7a613 +6873,a84c05b7d7648d5d +6874,05dd8b1b3d6bacbd +6875,ce9c5398aadc930a +6876,7d2d7ed60b33271e +6877,223596eab258a58a +6878,5edb828f9f48c608 +6879,85757ae7121ed336 +6880,d11776b8f92fe6b3 +6881,9b5733002423dd36 +6882,aff3cc7b096eae7f +6883,b01ba78d0e284d30 +6884,a543df5155df48e6 +6885,4cd82bde6e32007b +6886,900d6d49cff2a4ad +6887,54b81cf8680d5ebf +6888,ca48438b83cbb8ae +6889,3aaceb20e837b7a4 +6890,29036690f80b13c3 +6891,3d38405e28fdcc27 +6892,0c0d5748f70f8688 +6893,30b03d8cb8f5f887 +6894,838ca1ed1f18af43 +6895,0d938bb36772009c +6896,34237b76b5a26e3a +6897,bdf873d0b2280a84 +6898,553a868aa36748c1 +6899,0638ba4089afc782 +6900,54d580fd90c29008 +6901,555d26638b625cfa +6902,b6b1eac91b14d56a +6903,31618a943f379e6e +6904,24aeefc3e4018a12 +6905,59242d3bf5a40125 +6906,7ecba71c219498a5 +6907,02004911de3760d1 +6908,b5036fe22c73e58d +6909,8411acd8e4ada406 +6910,435aec8a7a1d0c80 +6911,1fb5a41715308a85 +6912,a08277bae697e17c +6913,748d2780aa07293e +6914,d68df56912a75e48 +6915,2e75df838fe38ada +6916,161506db1723e3bd +6917,ad15d18a259aace5 +6918,a41266bc77ddb453 +6919,cc1fa5542e2b0eb9 +6920,3f5d08351c1d0407 +6921,293c4294ba500386 +6922,5d1045c676117a03 +6923,dfb38dcb130bcdfc +6924,cfab4c6478e66317 +6925,6c6d2b3b61fedc5d +6926,ebdce6720ad3f56e +6927,0183d0813a1cb059 +6928,628f72f0ef8ab991 +6929,7e2d338a9793aa7e +6930,f88fb950a9defe54 +6931,e9bcb79a497fa430 +6932,5601c8b76e1a41f0 +6933,f51a8cb4064bbfe9 +6934,f1d7d21a2895ea02 +6935,e2470018bd84dbc8 +6936,443a5caffc2db630 +6937,346a0a9893328efe +6938,161b71ee4a138fa2 +6939,7d8df294392c843b +6940,40e4b70decc347ea +6941,23d8bd9b5c866fa4 +6942,e7c4b4a516e2af5e +6943,e54fe2769dfeef20 +6944,d9633b0296e447d8 +6945,50e62acd89501c43 +6946,1ca413b4af7ae0e0 +6947,2a896ae27adb6a8a +6948,9da4dbf9d4ce548e +6949,557ca3159be45535 +6950,66ccbfb984e482d5 +6951,3ec511eb994544f6 +6952,3acf3f45affd288c +6953,e2ab2269578aaabf +6954,eb8ec0c1e8e51524 +6955,7d1d4cd658169f1e +6956,48b1584387051250 +6957,8f3845dd00f65977 +6958,479e487f96fb98d6 +6959,bd480ee6a57552fe +6960,2cfa96a21bd21828 +6961,97269beeec4ef1bf +6962,cde3e9bd8df1b2c7 +6963,c628a4b51716bf54 +6964,6df3620218b9ed13 +6965,9dfeb3e16a270028 +6966,490b94f84ae711fb +6967,b01374c55c8d6a80 +6968,d143d61e37e5674c +6969,95ba6e40b3041f27 +6970,b859ce1af9c7d25d +6971,3711d01cef4fbab8 +6972,899f30df9fc967bf +6973,82a12008bf80c5c4 +6974,ca9aa89f957dc530 +6975,0bfc0e810c48f264 +6976,d8dd400054c12352 +6977,ffbc8940c21fe4f4 +6978,193ac00075d70dba +6979,6a066f25df2244ae +6980,36012845cbf5f8ba +6981,5bc26e20762bbbf1 +6982,d01c93b26aa6aa44 +6983,53474a04d593a39d +6984,f817553b818b47f2 +6985,88f4dd68c95cb5a9 +6986,85b4da110a1d7395 +6987,20cc602f3ee8cca0 +6988,f06b3b6d8b079e73 +6989,a4f75cb68fef36e2 +6990,5e8e929e63df7581 +6991,f51c544d0ae2b0e6 +6992,a981a4feacfb0aa2 +6993,57678628d839594f +6994,035c2188711252dd +6995,a79b0b98a2d04904 +6996,00780111df4f88f0 +6997,8ed9a2c58dab1c67 +6998,6758a802c99bd076 +6999,5afe02b7d1180ff3 +7000,958ca6f28a09c4ae +7001,41924ae132cebfe2 +7002,94b6d1ad4f9cb288 +7003,a82d8c2e1ad08e86 +7004,a74a015ee075f959 +7005,6fdca27314d88649 +7006,6e8f8c78eb854a30 +7007,32acd5df4c0487a6 +7008,570c39dec6c21080 +7009,8cd4210258f10b3f +7010,db940f21c1ff321e +7011,b88a88178a90c541 +7012,37252d782267cccd +7013,8d1f57cc6de6c05c +7014,3c2fa1346018c078 +7015,bfaeb9e77439ba81 +7016,658403d6cee74009 +7017,06ff5146559304af +7018,4496514b5b4ad442 +7019,4ad49178ff0c998e +7020,dcb422c5cb9e703b +7021,78b71b6a58ae82cf +7022,afa28084abbf06cd +7023,8e9aa9d48082d2f2 +7024,4f1e5f47e24f0ad0 +7025,a3a98078eca21536 +7026,c3d8ae61bf77189e +7027,11905e7121088b95 +7028,5b423cf70c64b316 +7029,2f42081da9a8674f +7030,da4c7d2a0a32e5fa +7031,a46846128d99516b +7032,2fc9fddbfb02c335 +7033,f9430e8dc8601406 +7034,025d38159e1365ca +7035,4f2a3c60752b4c8c +7036,857966f6b1dd630f +7037,0bda18de62119adf +7038,93ba9e2ef0727fd7 +7039,d13734c82e7039a1 +7040,6dd7728cc497e6ee +7041,971a37087add8c47 +7042,900005bf5757fbdf +7043,c7006253fb8d334f +7044,8e153bf61c621e2e +7045,8d5315197af8a66f +7046,e81a47a2271d371c +7047,093eb2132881699c +7048,c50a0128c9ff388c +7049,b08ef61ddda19131 +7050,1f6a5412c8d42e1c +7051,b8f9ff86ff1e73b5 +7052,54ffd8ac1cfec0a2 +7053,62a27c5431150b1d +7054,eae7873616f411d1 +7055,b2b0faaba9f6e4f8 +7056,c3b5679f2373796f +7057,d92a7705061f5e3a +7058,18d2160d407a128f +7059,f0292f956bbfe3b2 +7060,d524bde301a5782b +7061,1e1d4fe9a54cd2c3 +7062,a56a323198536fd8 +7063,65d249969621c565 +7064,f91b9c0cdd87d889 +7065,ab419abb77c7bcc7 +7066,8729a123dae75bea +7067,f2e75ef75e1cf632 +7068,c57eea7615edc403 +7069,991fc1f18ffcd9f3 +7070,5a34b8bae9719290 +7071,5f03699a2fe8d39a +7072,b29ad97fb5a4bcc6 +7073,ea3ae59cae3d8a32 +7074,0538f2c98f875b8f +7075,8dab04efdc0ee8b8 +7076,bea1ea2fec31f7ec +7077,4fb00ff770b8d7c5 +7078,93e3c45806263791 +7079,b1fcb2a3db87cf4b +7080,d324608947235090 +7081,23a666aad2963240 +7082,826c1fdae2af59d2 +7083,3d200fb08aed226e +7084,beb86e739de3c771 +7085,8c45809b7dbf72d2 +7086,5913e31962d4646f +7087,673b26977dba6397 +7088,21ca05c54ea75263 +7089,8bb1afe1543a2252 +7090,679662c591f83bb9 +7091,4f35c74c49b089e3 +7092,27396d8f254055d9 +7093,25eef2d1ab13b2d3 +7094,295c46b81e661107 +7095,a6b99d5f3a1e4094 +7096,22fd6c06d11853df +7097,1f2753d44a1848f5 +7098,28506e0363d3130b +7099,be97e1c2c2bebca9 +7100,7f83ac6e67914299 +7101,0a62fee3d1cfe327 +7102,6a15f905f507e3f4 +7103,19da2da1ee196269 +7104,4ba7cd415e409f09 +7105,60e096e015a342ac +7106,4c8ece4ae57b54ba +7107,336c3fa47e851292 +7108,effaf64cad8ef9d3 +7109,39d9b6850f9fad6e +7110,2e847b3fa533d534 +7111,def5bf7a1424a749 +7112,d6513332258ef64f +7113,91123be1e546e32b +7114,f08472bf3c4193d4 +7115,d84a4f6c04ece24a +7116,225842e2b3a5bff7 +7117,d4237bd823384916 +7118,fccf11bd29396044 +7119,18ff7ac12f194a37 +7120,1970db3426d0b398 +7121,217a34c010508573 +7122,06c69fd42dc7b2f2 +7123,4d4a11c66594a085 +7124,1f82415ef416f6af +7125,a89a342900c5bbfa +7126,dfe11bcfc307a382 +7127,587fb867700c59d7 +7128,d09e6f6aabd0b01b +7129,46a197936967b6a0 +7130,f8296b755060851d +7131,d27c0c8e3c5ccf44 +7132,8a8716d8b96d53b5 +7133,0d689ba0d6fde2c5 +7134,374927525b9d6548 +7135,c25b9a36875a3aa2 +7136,745ce3ab52156136 +7137,403b9ff720528038 +7138,f3100ef39c108db0 +7139,d781ac693389c08d +7140,2c6e0a61acd1999f +7141,a4f89d301d058d09 +7142,8e4c942e80683681 +7143,b7f38806fc6f171d +7144,cf5c3410644ff026 +7145,d90892ef5444a7be +7146,30f69f1f9de61732 +7147,cbe8ebff84b922bd +7148,99f07fcd19f16714 +7149,a4c8f07cc702d044 +7150,2f53af92baf96eb5 +7151,02a88dad793d68d8 +7152,286675c011e00ea5 +7153,86864d9f0b1d7b42 +7154,ab395b4b709b63b9 +7155,40f40963869b1c82 +7156,b8dcfc79290a9633 +7157,33c9d2f6d9ed0479 +7158,8ee0cdca837d2bb5 +7159,e4bf72b27c64c7d2 +7160,6cefc6686b5e8ca9 +7161,9763ea162537d3f0 +7162,cfb5f8a18caa9acd +7163,34ba2aa2fa1a629e +7164,4784d0853ebb0eca +7165,2c9c417985f337e7 +7166,b8392583fc84624d +7167,f5e64f216b4bb59f +7168,1603daf1a215a814 +7169,58e2c90688dc1a47 +7170,35965fd8a11c4176 +7171,ebc271a76bcd8b13 +7172,030567765ef14bc1 +7173,a4f1d6cdab700014 +7174,d9c4da3a19976944 +7175,055c45e1d8cafb2c +7176,d5b78d6c99eb7f36 +7177,a7d25584331fdad8 +7178,e5420a3e723db0d7 +7179,fd949df3137cdea8 +7180,f863c51f02322288 +7181,7d85f929bd849105 +7182,bbd79cf96af7d437 +7183,1236000286a98562 +7184,3d82d0e02ead460b +7185,ede46e6e3d560797 +7186,b6fd97a973133f2d +7187,7a03a0e22989f0d4 +7188,b12dd173f0c3d622 +7189,5933abc84756b10f +7190,4cbdf7fc2a7ac16d +7191,43a8121dd0faeb57 +7192,4e0f3a8c955183e0 +7193,aebae0d4dd1822fd +7194,ef0f0ab7e7955a1d +7195,7884cab1d3a99b82 +7196,4e6a16ee20bf1044 +7197,cec37dbf368301ed +7198,a8c26c19763bb51b +7199,c75274c49bac4195 +7200,eec0635dbb0e7baa +7201,a043bc914839db2d +7202,ad59761fe73ce81c +7203,2c7e124ceaeaa486 +7204,10c5f0190aa3a453 +7205,1a4091157086bea6 +7206,b5cc48f48954dcf4 +7207,c7209e04f2f2c0a4 +7208,efb2379fc8720368 +7209,5adeefe76b08f022 +7210,5f83209594725e7e +7211,48027ed85c742aac +7212,145ef43d5ddf98d2 +7213,535130bdf6ff3988 +7214,a0169512bfc76874 +7215,c112585fa28944dc +7216,d79e67b9ca57a977 +7217,d522e4184bd772ce +7218,817f0c46c68e7736 +7219,465fb35650d471a1 +7220,d1ba49ccce062c90 +7221,2972ae730c3aa877 +7222,898e698b30934049 +7223,4606dcd55acbbdb1 +7224,2cdec35f8872dbd1 +7225,f0a0f9217e972ce7 +7226,912446d3ced532d3 +7227,50722b50818575f3 +7228,0590636b6651bcf7 +7229,f93a564c1e9f9e7e +7230,d3c5f9f167d4d7fc +7231,afd0873a82535f00 +7232,1d43718c38b5b0d6 +7233,9e4454cf129cb3f6 +7234,7c6341cc04efe471 +7235,d73b4ccb7e680e70 +7236,7a70e556324c66c6 +7237,26af4fb8f95a6ef8 +7238,d249af5d3b123d94 +7239,08f6d0ef990282f6 +7240,96a323d28c8997c3 +7241,194bb940f57adddc +7242,a152e5866ef56a1a +7243,65e758ac2ec9af51 +7244,631000c004339322 +7245,bd08601b1f9a5a7d +7246,4c6f3e09343b7133 +7247,26a3075fa84ecf3c +7248,a0ccb6c1348bf8d1 +7249,083b1c9ed41a9e57 +7250,a6bc08d5c5dfca08 +7251,a45b18760c10ef34 +7252,a846cc6d6ff09bfb +7253,2aaabd0a5490e490 +7254,dc2b0072bd75620c +7255,c1ce089e3fee09da +7256,40d0f1566502b103 +7257,f3ed2992a19ddbec +7258,9fef0d93025b060d +7259,1774423929ac43bd +7260,8932a7f9ac84102f +7261,ae9d2bd66beb5015 +7262,a64898d895e03ea2 +7263,0523c9107b03ae91 +7264,2b86088962197204 +7265,398fe9b26153f778 +7266,65f66a7c5966397e +7267,bc691ab9abadd504 +7268,2c58228d02e27428 +7269,67104be7f4dba44b +7270,dd440ccbfdca5784 +7271,70b32a388033bf1c +7272,014f3210668dcb6e +7273,ede7fbc6adf25dce +7274,003bbe25e0c9baeb +7275,e448f50831399984 +7276,e2b7717ba6152e77 +7277,d39e2e7ffa32fb8b +7278,9f5bc48058f4745d +7279,74d75f884b03f67c +7280,87b4724657aee6b9 +7281,69c495d76351247a +7282,3094a4e617f4c5a8 +7283,c40423e8d9d5243e +7284,229df9157f36e490 +7285,fd16689c74bbc19c +7286,3230f732201da8f0 +7287,2630f267fd2bd0cd +7288,e4c186fea824d1fa +7289,2b39b3a0f70f933b +7290,24322165b936fbb2 +7291,c3fc627037f939c4 +7292,f0f7319dcfcdbdb0 +7293,0466747c9094b641 +7294,ae34b5fa63b97a9d +7295,d11911b754eb91d3 +7296,6ed9f84fe86ce927 +7297,561712e4812b4db9 +7298,50091b758ee734ac +7299,a233e15c585555f3 +7300,96bb3c29f7c8273b +7301,e6b04e0fafd2db68 +7302,84410e69f8b11a93 +7303,43bf04fd71f86348 +7304,d55b4e6d1b85c6ce +7305,31db1f121a7c645a +7306,4a7f8a2a4525b7ae +7307,8538e0fa4a672b1d +7308,0be4786f7369663b +7309,a92d63e612e805de +7310,42aeeccaf2723976 +7311,c88cea638341e0c8 +7312,9e5e2fd97f641837 +7313,d44694fea5b332fe +7314,baeb6ee78bdb2fe9 +7315,363ea504d35f83b2 +7316,1db2132775dcb6ec +7317,f000dbb39c22765d +7318,1842a8f4dcfc44cb +7319,894b5d55f167a80d +7320,220ce1d98389121b +7321,d839e9f438473c0c +7322,e878c100e3b05e1a +7323,d11aab1928f00b83 +7324,37d8d12ab8e2f353 +7325,a9c97e314f4a8c76 +7326,9a46e707abcbb907 +7327,7c5a4b6404cc0310 +7328,8c2bc562174ef19f +7329,e53a7155a2504f6d +7330,86e6813adb7a906a +7331,97b691bffd619b08 +7332,e8fe89bd237e9c86 +7333,ebd4822bec51ec14 +7334,b8dce062b0ec3ecc +7335,71f396b7cb7b9f96 +7336,26bfd4cbf5a54613 +7337,984970f200eb9118 +7338,9f89f627e93a55f8 +7339,756daee0288af96f +7340,52aab01ff8952487 +7341,3d0c8fd20425802c +7342,e9b2b01048d95354 +7343,b603e6a9618d876e +7344,108dde59ba4d928d +7345,8bf2ff09dd762542 +7346,9338ce882f1655da +7347,a6344d06aa28d758 +7348,9d6e6159c84f4277 +7349,512bfed21a48db0f +7350,9f92b472b2153786 +7351,31d92ba1e328801c +7352,d173841a3c479da7 +7353,4ca831f2dc008f5b +7354,ecaa0b315a26c63a +7355,be157bd192212abd +7356,ca664e0c93684297 +7357,81184a52060eaf62 +7358,4c849e09fce84fc8 +7359,1dbc1b1d93f99769 +7360,495a2c6d29ab5880 +7361,5255c43324b6c222 +7362,72f20179945a298d +7363,4c729351694a59f8 +7364,019aa32662b0ed3f +7365,40f969c6a5fbe6dc +7366,faab8149bdf7c582 +7367,66fa53e806d7d8ed +7368,5066b6c7858a4364 +7369,053ffa1c531d0ddb +7370,79ccb09974059ff2 +7371,f16c4e336e9355f3 +7372,84e2cd86674a2bdf +7373,5c1098cb7766dd7e +7374,6c05338b62b407c5 +7375,6450d8f53e9207bf +7376,69265d8d03587559 +7377,8b9893777fa4e304 +7378,70a06a0690a1183c +7379,19a4014cc9d6d7ce +7380,8369d7f16344740d +7381,b6007689217750e6 +7382,9d4a60c2203736f0 +7383,e4dce36c81cc8ba7 +7384,dbf1dc7ec567910a +7385,a59a0484ab7d43a8 +7386,e96615024fee130d +7387,2a9be34e08719e20 +7388,89e22d1fd44234dc +7389,48a16e61044aba56 +7390,51ff8734f8e31a9e +7391,3ebc906d2ac9e549 +7392,2c5b1029571002e6 +7393,a89f3acd263939c5 +7394,44e1e94f789c206f +7395,f887228c4ac55d4c +7396,8e5e82be428ad246 +7397,31ec9be908c86592 +7398,88f8ac6212cf60ec +7399,bb25d00ac1aae1c0 +7400,031862808537dba3 +7401,a99990180dbf2f0e +7402,09434ec24a222c27 +7403,0b4919a59aa363be +7404,933b608d98d17b62 +7405,a382fd28bd1081fd +7406,050943e74eda7f00 +7407,226ec9d2418639d8 +7408,85788e27c2d7dc48 +7409,cbc1f86cd9b0f4a0 +7410,f04576d365cb4768 +7411,029e514f9e5bf7ae +7412,ea1442ed1bf24a75 +7413,c8bf13ba06edbb5a +7414,12749e6246a38ea5 +7415,ede3db853ed9051b +7416,53f3e90c7ee068b3 +7417,5ac1375df97d0e01 +7418,6cd3941efc44f449 +7419,85c7a7343b32dbc5 +7420,ec65fadc2cefd2d4 +7421,55cc183812898ada +7422,3e955b273987f0ac +7423,f982a46fc4a18738 +7424,95306446cb4f79d0 +7425,095f8ff27b64c451 +7426,15eb6688d8ed744b +7427,fb33e77aa2e88279 +7428,5012ffd87f035df6 +7429,bcb10d9161c12690 +7430,bf00b58abdcd4be8 +7431,ee8dfe9c7df62aa0 +7432,3c8ae894d60cecdd +7433,a733b76cb24ef361 +7434,5f11337557511206 +7435,4f0ce0c230c5057a +7436,6b229c6c1de6b8fc +7437,035a12ab37759727 +7438,b1977226d51fe621 +7439,a9e34a2226aa2b61 +7440,0dab0c1652f1a222 +7441,422ade0c9fb31e7e +7442,26db18ddccc8d238 +7443,dec0f462be1ef246 +7444,3ff34b931ef0871b +7445,4044827eafe6b489 +7446,e4e332b0b7a0d045 +7447,1c7fa10aeb12f11e +7448,8c467bee60cf4a4f +7449,db7e0ae6e1e3f0c0 +7450,f3b3a6ff8873afb5 +7451,1d1c3ac17c960f2d +7452,908612c152f19632 +7453,bcf3988eb67ef7fb +7454,904d784118e15561 +7455,1f7d8d1c178e2161 +7456,535199c4bd990ba3 +7457,6396d916c366b22f +7458,a07ddf640c1a559b +7459,a869c0e27cc3897f +7460,075ad21bb87506a0 +7461,b151921ba6399250 +7462,82f2551ef56355d4 +7463,a235b271a3f5df6b +7464,fdc173e47b4f6d87 +7465,9419324873e27f70 +7466,b18a5cf4a732986e +7467,11f3ba9718eea7fd +7468,66990dd46bdc80f5 +7469,733435e090f29215 +7470,f31095d8a060a8c5 +7471,67dbac0cafb75ad4 +7472,6e8767cf7ace9924 +7473,1bbb645967214e11 +7474,62173fda12239440 +7475,aeb08ba0f641db44 +7476,4d52f94ec9c65237 +7477,d9012a8a469c4991 +7478,c0c599bd1d57e219 +7479,3c1b47672198f68f +7480,8677df9a8c0be92c +7481,cd9a5c738a1b7b52 +7482,af404342382a2d72 +7483,4ac5ed3e6dd4aed3 +7484,7167c0e0501ef35f +7485,27f7dabca8d75eb4 +7486,48b792ee5d0f01eb +7487,caf41229a38d4583 +7488,304a30cc5822cfe5 +7489,1bb29a9321d35e97 +7490,34be8a9de7b1ce72 +7491,3367f420a1f26554 +7492,90ae93d5685e8b29 +7493,4c8458808ce39b77 +7494,6dd0b91468a3b5f3 +7495,7ea9d964e831f101 +7496,683088171f93bfbe +7497,99563ce20707573b +7498,2993a649baacca38 +7499,6238ac3c45fa118f +7500,b7dd55cce48d5164 +7501,5e3ef7f5cff6f547 +7502,f4e83cc02073a774 +7503,b58842c4f24e8c8f +7504,4abe75a665abdf8d +7505,4b65ca14a1975d7b +7506,ce65fb420f45e2f5 +7507,81c70b25c5bb620e +7508,7d297ba75b18c318 +7509,754c844f60247d17 +7510,4067a2aea41bf1e8 +7511,e6494992de65d3cd +7512,73b87768623ed20b +7513,03c8b9889e2bb6e5 +7514,e5f419cade5d8f21 +7515,67e084f628dfd94d +7516,4c08c215e995e530 +7517,f1b3125b119a2b4b +7518,e06b812be8e87679 +7519,e6da0c8f1f1bf343 +7520,4072acca0fec6122 +7521,951a9dfd99210869 +7522,48f41f7adcf8ac88 +7523,2157d4665fc5ab49 +7524,944dcb71b8dee0d5 +7525,84423f7488f67698 +7526,40997f96f951c94b +7527,e6380e7a2557bace +7528,ef82493ce7f47765 +7529,93537fd371ed6594 +7530,bc7634df1dd82b9c +7531,91c4d6dbbd5346ff +7532,4a3041baa323a50f +7533,0fb1b8f5ac97182a +7534,6d6057865a4dbca2 +7535,83d930b004a23d9d +7536,94d6312177619d09 +7537,d3a8fc316f36f1fd +7538,daf93892a854cb6a +7539,718994342ee5e321 +7540,ca35dd781ba03c5b +7541,2325c517f3cdaad3 +7542,335ad0f50d0bc4e7 +7543,ae24bd76969f2544 +7544,622635dac3bb7552 +7545,6b13edf491989d71 +7546,6fab3569baf3d022 +7547,cd432378bcb1bc7e +7548,bf68e53407d4b31b +7549,c9572d1a9a92383b +7550,b9e34e453b1181b3 +7551,0ecc1134a60b7fa1 +7552,987a21447e41803c +7553,d88283e0b1a7bd3e +7554,2cd945306340cae1 +7555,058a735e2669a1fd +7556,10a08b83404ed776 +7557,b183b97c403e2dd4 +7558,dc40a62ecbd6898b +7559,7b7eaad1716642fa +7560,4d4fca2a26d05906 +7561,8bc16fe2cc588254 +7562,c5e6102e28932d93 +7563,b86599fa4f82db65 +7564,025d6c2367c568ad +7565,d6d237093ba8b095 +7566,02f5db7a28561eed +7567,da1b0843b9c9d397 +7568,71fc101d02d798c1 +7569,35687de9aa1dd605 +7570,2b55203886ede379 +7571,0b9112d248819a17 +7572,a58b2a034c455884 +7573,5abc7311f740a30c +7574,67537a4387cd83e3 +7575,c21215e31647e2e1 +7576,8e182404ed8e331e +7577,366fe8d75df9e6b0 +7578,abc193f879e43c79 +7579,157f1b1e0e32a1fa +7580,2a781ca9efeacdb8 +7581,d8ce9d98f16dd415 +7582,9de117ff406b9c05 +7583,81f42ae2268aa292 +7584,7661769ff8b7504a +7585,be61f8ef2997b7b5 +7586,cb027494cfb226b2 +7587,2e1840aae701dac2 +7588,73cc69a78d3e5b66 +7589,2094c265e0f31e52 +7590,a1eb50e8f8bc93dd +7591,d39f5aebd0949e2d +7592,4fb4b1aec76b0f8b +7593,a6acc4bd1edb68bc +7594,4e185b262a51c717 +7595,a908797c3d6be308 +7596,eda1418c2ca620d7 +7597,a2b9b9419d4d543c +7598,45e92a1c34affea6 +7599,623beff9172bc0d3 +7600,2109426385b061b8 +7601,58b9d035e0c02918 +7602,42510654af662271 +7603,444225288d6ca79f +7604,79946a614e5b4f68 +7605,b5e6dd00594193dc +7606,3a2122a1f8d6502c +7607,806e3bc231c326a0 +7608,3ab5c5178f2639a0 +7609,a495400f85a09467 +7610,d7f58170ef49ca38 +7611,f6c6f3764a61e01c +7612,78ffe2d9a9039365 +7613,a39da1ecc87d4c3b +7614,de207c1c651b2411 +7615,c1be3631a44300db +7616,de5c4906850e01a1 +7617,1a69235c0926cd10 +7618,b33764cbeee09f63 +7619,04154d454ac98724 +7620,4ff2d55daf9e5a0e +7621,9171e756452f746e +7622,19eb1d95897b4cd3 +7623,d1a68794a0841805 +7624,553c04bb56c2fb9b +7625,532ed3f16d2d46dc +7626,e5d4c75481e9094b +7627,af3500c16fb8b5ff +7628,a5f437ab9ce7dd7c +7629,5836c4598acc1481 +7630,eeafc9d171ba8766 +7631,3596ba1507b5f1a9 +7632,04f40def08e05912 +7633,20fbcaab5bc12974 +7634,04c604ca6ea2d981 +7635,cb3de7b8cba2c435 +7636,e067ee2878864a9a +7637,bc8d8d518fad4861 +7638,dfaa3a9e40da3134 +7639,795b0a6f2657158e +7640,19fbd6b009d24ce3 +7641,3ffc5fbff519dbe6 +7642,639ec15c06f051e5 +7643,6bff963f846c7fc1 +7644,e6ffa0aad75749e9 +7645,07fa39f76c4f8024 +7646,0e8359d37df584cc +7647,2ce2c4f31272971c +7648,f5f77a4d48d9294a +7649,0d4f0bb5d494b226 +7650,f71a9a24b68cb008 +7651,6f1d552e7bc3ddf5 +7652,6916407482c159f7 +7653,988ae08ef989eb49 +7654,ff202afbe0f3ed10 +7655,d0b221e00e3fde9c +7656,b0d8db271d35b685 +7657,13611b674790131f +7658,f0b775d829a0f4a5 +7659,f363fd1b0733de5b +7660,7c6513354ed1a521 +7661,4d79a37d92b59d1f +7662,2a4f06cc8883e716 +7663,471daaa937dc4d5a +7664,f9efcdb53b29497b +7665,006a2aecec981e4b +7666,ab722e4e3dfeff16 +7667,1eae238a4e2efe9b +7668,7748c196c44715c8 +7669,5558e66cc55e886b +7670,81dd1e14be9d88bf +7671,b1f4869ffacf37f0 +7672,12462f4627561721 +7673,821d90e94270c682 +7674,b0649a3ba5cb1ee8 +7675,2941fb09d84b71fc +7676,05c1bc13d8d12123 +7677,4cf0f3054d247665 +7678,99040593c2f7e8da +7679,3370fbb579735e24 +7680,adfccf6de6274f7c +7681,ea3c393f9309c772 +7682,c0e71988c38b582d +7683,e8ef254dab54255c +7684,c25bb1160f767945 +7685,accf2274ba6ff860 +7686,e4d0a85fd76fbc52 +7687,c813fc5e126d0a17 +7688,feba92dbe8990555 +7689,d14557dc3d11246b +7690,49569ba7bc3a63ea +7691,cd489e8ce1e98e75 +7692,8385320d6f9f561c +7693,b640d02466b3a587 +7694,dad06f57f650e837 +7695,df90fbd7194c666d +7696,f21e19c992c2750c +7697,f7227d6b60767583 +7698,542a8b1068bbd8d4 +7699,0f74f44dca276f13 +7700,231007ef79d22c97 +7701,92382d2a32c301a8 +7702,ad376b2338950045 +7703,814ddee1a9645bc1 +7704,1f6a086f1ce6e780 +7705,1628c3ff1d4b05b3 +7706,6eff6028f944c239 +7707,47ecac553034359a +7708,31ce6eec79f320dc +7709,8d009577802da069 +7710,0e1e03dc24a166bf +7711,078a5fd374085f68 +7712,21c29f2f2cca01fc +7713,744305e785937f6d +7714,46d05f850ab66b25 +7715,6c46ae36eafeeb05 +7716,900687d70da63bf8 +7717,5b6b480050448002 +7718,43989c087a73c062 +7719,f4b3fb60773d7f7e +7720,b819b37e4067400b +7721,7c8a91a68b2fda64 +7722,22d803de655cfc7a +7723,503bf73fb284a4dc +7724,ebe264e8a63a7553 +7725,f988e54f211cd811 +7726,84b00d830dd2880e +7727,0de1656df292426c +7728,d2ba39d57134c3d4 +7729,59675496dbb6a5cf +7730,58f2768dc46876c0 +7731,9e8a02938789f780 +7732,b0f8d6c1f44548ec +7733,99dab1b468a3516a +7734,41b759a6eeac0d6e +7735,2a0c3d6522a805e8 +7736,8b12d94a874b64c6 +7737,740741d122ff4380 +7738,3f8ddb214d90300b +7739,ea67557774b5e7b5 +7740,a084bffa098163d0 +7741,d0bda71e27477435 +7742,82ff4d643653c13b +7743,b1d3ef9d4f3b8a13 +7744,72974cb45205391b +7745,1401f18886fc6d95 +7746,11052448604969fa +7747,4ee8712e4ce6ad9a +7748,8bc0b2345496347c +7749,0dd27fbbd1abc25a +7750,6cd60978b179fbd8 +7751,42c1fcc71b47a530 +7752,f06687499d47f4ac +7753,01a354c4427c4f4a +7754,b7d7e1bc068e1382 +7755,ca950a912ea60ca5 +7756,6c6cbaff120d0829 +7757,abd9091c0c10833c +7758,5c1207fb87e3863c +7759,b7de055187ac2d57 +7760,af9bc6c7d6d1cb0f +7761,2a9b968ae677cf95 +7762,0a6948099a2a36be +7763,3451af38ca32b4a1 +7764,b361469e9d0b28cf +7765,1d0713e1ba778c88 +7766,ddde88a55417a966 +7767,e5cb1360df9729ce +7768,12a9c1e96b32eb80 +7769,c6a46cc1825411c5 +7770,c63fdbbc94f32cd0 +7771,6b976b90745614cf +7772,bb3c315b0f3dda17 +7773,f69bfbe2f57d3811 +7774,9a546ceac4f48737 +7775,43883bab5558edaa +7776,460758da8669344f +7777,8352d16357e9456c +7778,4d9a0ee471537b5d +7779,864d6902b8b97b75 +7780,00ba8788a1ee4e67 +7781,7a8826a9926fa1ba +7782,837d952305d38c77 +7783,e9a34b17c15dd029 +7784,940bc1b76692eb5d +7785,4f55f28682e55bcc +7786,b47250cb55254dbc +7787,60c6ed2453db33e3 +7788,7d2d0ba11a309745 +7789,73e76553d2d888cf +7790,e966f089395acf30 +7791,28f6891a12c6b272 +7792,dbeb845e2da7b6bb +7793,f4492e7b06e0382b +7794,cf37900db65a2305 +7795,7b5819a5b6ff2d00 +7796,45cabe122560323b +7797,bbffc46a270d455f +7798,23389261d72b05a6 +7799,358cfd5ef38ed536 +7800,1d014aa3cc87d06f +7801,b7b08aa4155f4a8a +7802,d14d1eea5b6fafd4 +7803,81086d6c6b21fd4c +7804,0a6819b65487d0d7 +7805,d9658feb31d39b3f +7806,6688766460043ad3 +7807,b3362f446ef70fde +7808,ac01835a8be2a37c +7809,5ca476f6adb800a5 +7810,b6598fe238e4d68d +7811,d6eff7b09ce2b5a1 +7812,b8e68d0456af154a +7813,b71e67c5159b6d77 +7814,80394739c9652831 +7815,a423ccee23b2c544 +7816,b8562b48e5f9ae48 +7817,87a885db44ad6a5b +7818,5cd5d3ade6bd4644 +7819,8e64e4d43d831b63 +7820,b29a4165454be091 +7821,39ea5ac942b3267f +7822,0baa97d15107d072 +7823,f5d1b1fe9547e282 +7824,37b4bc5763a0b77b +7825,15e74379a0eadbf8 +7826,3360aec50c411ead +7827,ff375b6c860c7bed +7828,2ae50644dc3e0ec4 +7829,da0b4c4e8dd1e006 +7830,445fcbea38c14143 +7831,635b2ad72c99b3c6 +7832,0550d0665635f178 +7833,c01cb5993405eec8 +7834,9b86978a9a4dc8f0 +7835,e5eeb9ec6899b67e +7836,a478bd63c99d9a1e +7837,0f515d65dc6d4ebd +7838,a6cfc322fa44c27f +7839,f87db2e55262f5b8 +7840,28ed8acdc28d8491 +7841,3b2ee1aaa798c0b7 +7842,631fd31f654ad586 +7843,16d06009d93b40c2 +7844,8d49bf8eaf061d2a +7845,657a998f63b37ef8 +7846,feb4b5fbdc6a6794 +7847,185aa607b1100247 +7848,944ca73cff121443 +7849,49531d6159f69ea8 +7850,32b669dffcd96251 +7851,66cf74f28099a453 +7852,60368a7c40554893 +7853,540d6a4eeefec419 +7854,c5948d1b257df6bc +7855,1ad85032196e8588 +7856,90ba28c521a27015 +7857,efd421ff87fa1a3c +7858,f99f26208946f21e +7859,516e8007423e9ec8 +7860,c7ace6fcc38089e8 +7861,5d65fe028a82c68c +7862,b4c88accdf1da4b8 +7863,8aac22c045799445 +7864,597db70d5d809e17 +7865,6d52b75c4cc1a326 +7866,1666e390cc922068 +7867,5bf2b1539ce8e7b9 +7868,c6485311ceb4eaec +7869,b5c5c2ddb71df152 +7870,597a20f566f4afdc +7871,7f5dd780b7b0c744 +7872,87f8714f6c6cf888 +7873,a3daf5296ed7fa62 +7874,857db4193337f8f3 +7875,128cf95477436244 +7876,7b2e5a8ed3d19b5d +7877,b56487471385fb2f +7878,594611eef1ffa486 +7879,4297f756ced8d316 +7880,b154baf29dfa6bea +7881,49a43d0d1b6069dd +7882,9ca9647927fd55fd +7883,54efcb2ce8bcfb51 +7884,3abc41e7b1048a50 +7885,aaac68a2197dff9a +7886,e8a5b3b4a6ba7fcc +7887,e167f5fdd25da402 +7888,87817b5e2347e845 +7889,7a6460bd4fd28d58 +7890,28e4227cdffe9e46 +7891,0aa628996a09e34c +7892,f45a1f6d1be053f1 +7893,4dd984100828953e +7894,4ef854545e877e82 +7895,291438d985c55a18 +7896,072b8ab3a6e86686 +7897,de660d9cc916b49c +7898,98e2de4a71ef2fa5 +7899,3f176ab7cb78623c +7900,aaa5381f649d685f +7901,2041692d6b22cda8 +7902,1fbc962fe19c85f7 +7903,5cad9b1082f6baaa +7904,311e1616366b2a73 +7905,a20615317456f548 +7906,c903c2d6c17309ca +7907,d80612c317febfa6 +7908,86fbe8ceb8cfdf16 +7909,a4bbba4b3d4b8e83 +7910,e40f1c924a4785df +7911,b723dafaec76d830 +7912,5509dce64e65a7ad +7913,bd893748eecc6bcd +7914,9f3eb0193ac2130d +7915,0c619095f106172f +7916,b8a2177248e56a9b +7917,b2630fe4cdc6d5af +7918,59119ed514cac763 +7919,b396fc357026093d +7920,8671e69043f6c527 +7921,2b7664b3d0a9f2fd +7922,946a81293c540215 +7923,2d88361cf3878085 +7924,a41dd359fe54e4ac +7925,ffe8a67170d23f46 +7926,c8a0d84376653b62 +7927,03b6953e2ff7ac07 +7928,ceea3a4cb7927425 +7929,77609dfc457eea1c +7930,5770d197592a1228 +7931,dc3cbc8672133bde +7932,0576f1e78f709d04 +7933,0a1387f670a562c0 +7934,312e6f0f2086687f +7935,d5410fa714500dbb +7936,ff48703a5c794ed3 +7937,884997785f70e59d +7938,d4c9912cbd0a5c3a +7939,79cf7792e938fa78 +7940,cf44b8015a89833a +7941,a47a0fc060c6f4c4 +7942,8f8c219924fc53f9 +7943,a010abc5756e8f36 +7944,06ee903539bf79e0 +7945,3c5c64673b7a1e32 +7946,df523d8f5af7cced +7947,a78c8a0db04ad46e +7948,a4874e7d929dd75e +7949,d26156dbe3b667e2 +7950,897e9b90a3ae03d4 +7951,0f826c025ec36607 +7952,c7c24805d76ccbe0 +7953,6f6de71fa0969c8f +7954,49e343c3c93bedba +7955,8c0948bfb2a337ad +7956,48f1d86d86bbc6b8 +7957,913badea454f5e6e +7958,5f6a1412165403db +7959,2e890980920d0341 +7960,83fec04bf8ea00eb +7961,73f27e358bbe52af +7962,2dac5c06939a9e25 +7963,71b876b23868d919 +7964,505fd1c1fab8ea2d +7965,2f4827c172c9bff1 +7966,baa673cc860bfa08 +7967,b2ad4a81924a5bd1 +7968,b69e96fb40b88c26 +7969,cd12e82cc614683a +7970,383a5f71a6d44bc2 +7971,9b4f91e030223661 +7972,dddb3d104ab4cb96 +7973,91bba3194b00492b +7974,5ceb48336c8466bf +7975,1b5c86c1038c009a +7976,d0ee01a47285536b +7977,63fd624ec159d4db +7978,288104a505ab67b0 +7979,59fbc98de6d27a87 +7980,2b6067edfcb258e3 +7981,4f1bf09b7218c6ae +7982,8904a1df2d904664 +7983,681024cd2768c3fe +7984,a0020099ad3ae254 +7985,895e56ce10bb84a7 +7986,3fa3f446163eaf84 +7987,13d6467c6e4d46fc +7988,ae53f10a077d76e9 +7989,9f40ac5efdcf9b27 +7990,e6583fecb7deb37b +7991,6b3906fac7808376 +7992,06c856bd425d5947 +7993,185a26df4708ccff +7994,1a3591171f0b8e53 +7995,1f9e6bc0a6507c91 +7996,0bbd2bfce2232ac1 +7997,21ceeb4636328705 +7998,add7b0c3dfd7ada4 +7999,cdd1ff8e02ad004a +8000,d34c5353625f1e88 +8001,b8074051bc0c9f03 +8002,b20d1f8e91279b38 +8003,656a57075fa44836 +8004,17f7d5eba4920d9a +8005,70af02be381a02a5 +8006,c978b4d4d499a3f3 +8007,06038e6f6e4ceed8 +8008,c2c9faca0548b6c5 +8009,95d55289a5270f08 +8010,44b17ed956674282 +8011,614c32e692ea924a +8012,c75ef7e12ee2b01e +8013,ee36f7d70f41e50d +8014,2984bd8905782597 +8015,0f2b4a10927e8a10 +8016,a53e7e4b69219def +8017,1cd2b92034a613fa +8018,92df7bd0134c7ae9 +8019,9c604a440ef57f60 +8020,701019b13d3b1a5e +8021,e8598c3d97ec45ff +8022,e251cbc600d36610 +8023,2390c98095c56f0c +8024,075c8664ef1d1bb4 +8025,4ca8086b03e59fe5 +8026,13f913cf89ce4202 +8027,311c81a8c4d3d011 +8028,2a9aa8672b9e94bb +8029,72c8dbc8f345457f +8030,a97a8f3330853154 +8031,7fe8d5aa62b72bb9 +8032,57267a48eacf8942 +8033,51897937925bdaee +8034,ecbe2e1483e14cf9 +8035,c611d783d21a5308 +8036,241c70043151ac59 +8037,29f00c14daf2de62 +8038,26646632ef53472b +8039,18e72e59108f6f2d +8040,1ae298e1150319b3 +8041,5c1a2b61bd216177 +8042,c3832311077a207c +8043,840a0b4fdcebd8c3 +8044,0883ad1b63db8733 +8045,14d0cb4f7bfd0e76 +8046,af94cd75f38aef4b +8047,201aaab70e6407ed +8048,1b41a2d8409a47c6 +8049,53bfca7be1bb8321 +8050,71443942bdf0b61e +8051,67345d6fa4f78796 +8052,552cb039975da6ad +8053,1d4b93d766ccc869 +8054,b6b6779bcb9d9315 +8055,9b0c0f05ce3c8ec9 +8056,8faf9a7c92f20b3e +8057,f26669418e4eecc8 +8058,c7194a2ba2f197f0 +8059,8ff983b64c95f962 +8060,960c68fc670fc365 +8061,78bee2f92b4fa15d +8062,e02ccc3c94532c12 +8063,d77b083e23f39b72 +8064,2f73d1c1b2f63d4b +8065,d0cb7cf0520ceaa3 +8066,9f110480c3428dd0 +8067,fb1fc59c17063507 +8068,8e2067f4291b268b +8069,2114dd7a16878d73 +8070,5ae3992e5b140d9d +8071,7ca25c421f360f08 +8072,efa42b4fbf4074fe +8073,ed84ba885d032bd8 +8074,0a0fd010e06bc1c9 +8075,31a8b9b17861a34f +8076,400b85a8dc260236 +8077,11c975395e3cee90 +8078,43ae881c07c450ac +8079,0de845110299e2eb +8080,f7311424a38f0ddc +8081,095f8c439fabe2a3 +8082,98eab5f16668a9b4 +8083,8466405c0a4ed93b +8084,08117d3dd01d72b6 +8085,9e5629fbb2b9cbbe +8086,2bde51a9ce9e49a3 +8087,94ff7d3531bd9747 +8088,4207c4c5b121f3e5 +8089,bec346b0248649b6 +8090,6996006833c2981e +8091,f88fd5b2ff61da1f +8092,71f5a0d54c08440e +8093,b356ddf868077d2e +8094,f9059ec23a4e742b +8095,ef9db52c081bccb0 +8096,83d843cd14fbbfe6 +8097,84f353d9b42e7e95 +8098,df0a29c5fc23b05e +8099,bb57e9308b1b3cd1 +8100,d04cf559e266425a +8101,2b0c55588b13aad7 +8102,9fdbd6c392b82a7a +8103,df8b5e8c7f9f1e31 +8104,8edad53a840d80ce +8105,2170d3871db6a359 +8106,8d837eab41fdddb0 +8107,5b1e465eb640d6b7 +8108,919fc75dda8198fe +8109,90d555401121aa0d +8110,0b971977b9894fb1 +8111,99a22f0d69f08303 +8112,60d4127f3d9e41d9 +8113,e593eb003175cebc +8114,ab0cf9b8e23ce712 +8115,b631ad3867ff27ac +8116,ff86fdb418e39f08 +8117,ebfc419333b8926a +8118,c71e27613d2bd0d2 +8119,1a3d68de4da122a7 +8120,a5be4bae4ab0d195 +8121,8875e81c90fd1dcd +8122,775c6b81738bf5a8 +8123,90982f22fb7a6dba +8124,6d9ed38137c20a9a +8125,42de090b404b232d +8126,357cb4ae03f4519e +8127,6ec17eb1e990c04c +8128,2405ad50730c3c07 +8129,bd2e98407e683bee +8130,88d3979c7f678bb0 +8131,b89f8aa7a60ae36b +8132,a6cd32605c258664 +8133,1aa2c9f345846f7b +8134,f01424a13fe48e88 +8135,46dec5d99ec9e438 +8136,40d3764335745fcb +8137,3ecc0ef17af454b1 +8138,7847fdb2cf04d5e9 +8139,1eac314294389205 +8140,0418de512a8b292a +8141,6b206ad2493949ed +8142,2e51b4459c0c67bb +8143,f7e9a42bc59354e3 +8144,e0323474b6931fea +8145,177a6092b22108b6 +8146,90db31cf094f1ddb +8147,3f3b075b99fee453 +8148,90a2cd25eecb4bcf +8149,45855bd61c7ea50b +8150,651b29f96c5a114d +8151,a0e12016dde09724 +8152,ab9808a213a1926c +8153,819b94e80a1e9789 +8154,10b78baf13323c2d +8155,ad4523043083ffeb +8156,55c9491270dbc2bb +8157,33678922e8de4f74 +8158,f6aa796e9a6313a0 +8159,f3a93434743c0bd5 +8160,95c1997d1dc631a3 +8161,e2b1936c429e72f2 +8162,3f9c9962394137a1 +8163,b01773fc79698a64 +8164,88c67939bce5ad25 +8165,1c2c060a462076fa +8166,e6f53d0c7003023c +8167,e1f167cd24449291 +8168,7bcde78591e51439 +8169,e2f46d390814a696 +8170,460da8ac2501ecf2 +8171,6b137c9241e78814 +8172,4e7dabf3c5adeb83 +8173,de4f3abd8edb232c +8174,50d79d1a2fa6f63c +8175,2e59452e5450bbea +8176,174aa9826e69c85b +8177,4c3d06204f33999b +8178,d89619181b0e0176 +8179,555495d9121a55f9 +8180,64995e33c0656e49 +8181,690467b2d3039701 +8182,849dc8c4e1b1ced3 +8183,782c3ecd9d5343e7 +8184,a08ef549d1b93b77 +8185,39773be9f414c518 +8186,dcf680fd21b25f41 +8187,3bab6ec3cc4909a7 +8188,3195d90fbd2ca3eb +8189,e285ce312b84d14a +8190,bd63da22ebdfcd59 +8191,dcae3acf062105bd +8192,6706d8180ada3f13 +8193,b39988ce509bc60e +8194,2c9cb23ffd3d4f60 +8195,95f4252c7fc76ecb +8196,d5696d5d5bb650b4 +8197,6bea20d3792ebdd2 +8198,97298ca05f0a274c +8199,b947d9946d6433c5 +8200,dc28ddd0d247a448 +8201,f1d6dc76e4d8ab7d +8202,bb4e094579028c43 +8203,5e3271351802474c +8204,783e01a12c505a95 +8205,db3a93369a92e40b +8206,b9ae8da868d04c08 +8207,873abb7330efb0eb +8208,c5f0c4e336e081e6 +8209,86c3964b5dbf985f +8210,d9ba2fb3b236ce85 +8211,31362ef032931495 +8212,767c61881bc7ade5 +8213,cbee02be48001692 +8214,84994a1a7d30e9fd +8215,b02c510f646d019a +8216,c9350f324c93a29c +8217,09e3484b4d64ea19 +8218,bcd1698806b3428a +8219,fe2d515c155c5e18 +8220,e5700e8b07ad1633 +8221,7644d9074a66bc69 +8222,fc1c33c3457cdc68 +8223,e9a72b3e02218b97 +8224,ef366b60ef953bc4 +8225,dd38b49d4b716f35 +8226,1d6ab718d5e37ba2 +8227,dc6778e2e122ac1d +8228,cf7c04e4fef96785 +8229,8e94312f9993fb42 +8230,11dde670bcfd39ec +8231,48847a610cba5f26 +8232,7e20c71d0858ef43 +8233,5a71248db07d8bc4 +8234,598754be7723ccff +8235,4bbc971609921ea0 +8236,df6bcd1781ac595f +8237,b0cc7d60087dc826 +8238,f61bf2da26220f04 +8239,f86dab9b5736fa46 +8240,e22f6fab1d76734d +8241,f6f1bbff103686a1 +8242,5e7f8ce877bae9e7 +8243,41081f5eedf726e8 +8244,c95c48c7896c6130 +8245,863abd4225140e7e +8246,051ea17de941373f +8247,af2a1e418741ac95 +8248,50c48c7fadc3c814 +8249,3e1d75f4f1d88172 +8250,fa120fb5ccc19c35 +8251,3dca04e6909b85d2 +8252,bd70845853220935 +8253,11e00b7e5cb6f16d +8254,1305b2993a4868e8 +8255,5baddb5d2013757f +8256,1425bc4b70872706 +8257,abe1bb50dfd5fc1a +8258,b09cefa9572f0909 +8259,ad3217f48efe646e +8260,0c02d76a2c2efffc +8261,5b6b71cb2a6ce9ae +8262,f2a9543b78946f4b +8263,e99dbe0e4396d2f7 +8264,0f7f9ef3535fe7b5 +8265,6068881b4201ea1e +8266,504bf2c3d4f42fbb +8267,39951c4019875555 +8268,e86a43c1d17187e5 +8269,09cbd04349a4a4e7 +8270,36e74750ab2c371e +8271,b19a272d3adb3a4e +8272,d598ec0ba659eb0b +8273,4987675945271528 +8274,797a0e8d21b9a08a +8275,ce089fba4260654c +8276,2db990cf22a0105b +8277,811e0711d439c3d7 +8278,fd5025fe0724d46b +8279,cb7c0d0d00b7d828 +8280,9c5786234316345e +8281,c268a5fa1b525176 +8282,834e8cfa02a4aac7 +8283,f9383c10946e5219 +8284,f216bde60a2908ce +8285,e76a596b9254ef03 +8286,9b99822bcf51a6c7 +8287,384dfeec8001a3f6 +8288,fc1382876d081631 +8289,b32e081ce91c25ee +8290,6c197d620c1ad10e +8291,de949eb49f6e30db +8292,4ca9f0d175556196 +8293,977e0ffcc3ddd825 +8294,4fe5762b1bd4688d +8295,9f802d93fef12b61 +8296,cbbb1fe58421f7e1 +8297,22a651c15a24d13a +8298,1e19796488899640 +8299,9b56a188fba7aa31 +8300,9de5fd5862f6b08d +8301,6ca4fc46c69839a2 +8302,0d28f9c30d300364 +8303,222f9347fb4b799d +8304,dfee4bc6f43cf6e9 +8305,d01efc813b55d27c +8306,054c6e0262fe57ff +8307,0e3fe21b9660b197 +8308,0e7d26c78e6ba128 +8309,e9ef28c7f74e1978 +8310,01add285e9de1c36 +8311,e7c972228d0ffe78 +8312,926394f82cfc3633 +8313,b8f8c749ea3e07cd +8314,3e701b3d5c1044b8 +8315,a51d1a96021a76bb +8316,4b1f9e06b833dabb +8317,403f9bb86ecf8f1a +8318,920cf8c353aed42c +8319,b6e62b8f9ffcc5e4 +8320,3ab191649fb259eb +8321,9f53f914420c3ab2 +8322,5f48753b734f54ea +8323,245989292d2b9317 +8324,208422ce11032ff5 +8325,c999cc40930cd881 +8326,4dc4ee8051acc8cb +8327,ca09ebbb935f36fc +8328,22cd3bd078e000ec +8329,c629176cc93cb487 +8330,b227a2502f1a9361 +8331,c6147bb26070178e +8332,92218770588bf416 +8333,c77e4edd37eb2a34 +8334,614b024662b5434d +8335,fc26f50f18305e6b +8336,b352e6c458d2650d +8337,7d595f567fe2a573 +8338,d6d520cae09032e2 +8339,c4f5c6e5aebad6f5 +8340,75a73b544c60c736 +8341,6569d6f7033c9510 +8342,e4e14ca480459ec7 +8343,55f7dd40deef2dc7 +8344,89579f04e0707cd6 +8345,33517b296efa0060 +8346,ecd3fee1c35674ad +8347,c243e2184d6345bc +8348,5d4dd53ac58b9afe +8349,c740b7e239a7d539 +8350,d0518dfa604e7d58 +8351,b599370058b3a2f0 +8352,0dc53b567d23e210 +8353,49dbbfb5f6637f8e +8354,9c29f71819eae421 +8355,f0481c110dafcdf8 +8356,30ebd83fd6a9d228 +8357,21af6220dc48af98 +8358,af6259fb8b58dda5 +8359,01a1810a8536d8cc +8360,42df8ac14a69da7a +8361,03f8e9751ab41715 +8362,56d211fb6e8b7d3d +8363,26a53cfa757deb2f +8364,60f1f7ea163acd9a +8365,48b916abfb6d2fdf +8366,1a6f23e6431e0174 +8367,562a2d5ce6b91adc +8368,5a2256fc7f8676ca +8369,41ea9a44c6afedf9 +8370,40e4d50d5a0f2fd0 +8371,2e9a9b4e7e867378 +8372,651639aa6a6fe1c1 +8373,794ece5fc7597322 +8374,7cd3f2885f9536e8 +8375,605c214045ceaa78 +8376,16fd11e9320d0211 +8377,eb5ca509d1239d81 +8378,c232cc8b71571c23 +8379,7cc0246cf40ccc0d +8380,62203cfa5192b73a +8381,feccddc5d8ba09cd +8382,1e54c4f1c6312961 +8383,0ba63a64604e98b8 +8384,3b6889af41657d50 +8385,b94f44a1a551b009 +8386,5e15e5cfa5f5d941 +8387,d889cd65ac2f07d8 +8388,db83ef77c1158eae +8389,76109c1771ffdffe +8390,6d94b0ffb0bf42b3 +8391,48db450e001f2b2a +8392,2a5816180685ecd6 +8393,1d50e0d5d9a6f215 +8394,e7ab965a2a6ee150 +8395,5fe4038b32552371 +8396,86f216d9c296f02b +8397,d8703e8c0820b88e +8398,4fd8b448152fbe53 +8399,6ac67730e084e5f9 +8400,04204e3be740eabc +8401,e5e89ab1927645ed +8402,3ac012a5b5d21d37 +8403,a3916992854e9293 +8404,5bcf659edba33971 +8405,101bf6b061199903 +8406,847d15c643ad0489 +8407,216e6c8d964413e3 +8408,b80c895caf710a7a +8409,58589858c72d756d +8410,5613b55f0abf5e68 +8411,f5d1a6a2dc909f3c +8412,62d5230d81da9b7b +8413,596ab84b99edf83e +8414,bd26617996567e23 +8415,454ac163d79b6465 +8416,211a192db14cb233 +8417,d86630339b838f7a +8418,3c2d383375d929ee +8419,fbfd93e50b645c8c +8420,fe188b0c308db379 +8421,685c7c6703d2db0c +8422,32389c31d01344f7 +8423,b9530ca99761df8e +8424,e58c891cba2fdf4e +8425,f40bdf2f7df0091f +8426,0ff0d2acbe2714e7 +8427,74c64801466dcd8e +8428,b6ef9f3e96852bf9 +8429,9c9f569dcae670fc +8430,fffcd0edda8eee5c +8431,72dbb70cc5a17442 +8432,3f34c06f63063106 +8433,03d2205c39fc320e +8434,505f52b985f9f4c7 +8435,a3432a471f41eb6c +8436,f55b178582c95aaa +8437,0325b32419757aa2 +8438,8e47198e58a454f2 +8439,0cb7ff693354ee0f +8440,8864374ae0180260 +8441,4e9b3ef89be6ee03 +8442,b58d8cc6ca650341 +8443,0e5414701e026bba +8444,9910ccac4cbf4006 +8445,9f20707022ec53c9 +8446,bb18f76ff3ba72a9 +8447,4a62f3b7db8479ed +8448,beff7655cf35b306 +8449,06085d25008ee556 +8450,6d415f5a469fff8a +8451,2298255a111f9ab0 +8452,19f2bbf2d46cd1ef +8453,114f6c0f3ef9ede7 +8454,44d6ce1f49b495aa +8455,bc53f3550372811f +8456,6144248fd3ac25e1 +8457,8c17d307d275fa82 +8458,3b35dfbf80572794 +8459,f7845434e37c1f1a +8460,2be1d72dfe8e8aaa +8461,65ddc64d17b7df50 +8462,59fac499a8299850 +8463,aecae333bfaaa782 +8464,07945eb5a6c0d1f0 +8465,0f82de9796fdc9d4 +8466,435a1b9812a95362 +8467,08ed77bf749aa2b4 +8468,6cedd923441dbdb8 +8469,ad446c438eab56f2 +8470,e445c69ef6df7ed4 +8471,1b8a680da80c32e6 +8472,dca81b39e7b0fabe +8473,896fa7f2d2f77bb9 +8474,ddb45a37ae9e6f1a +8475,7d9fc749ce47ab50 +8476,481a97b754c6dc9e +8477,43aa5eca735c48d8 +8478,9cda701f0dc65890 +8479,e87ebccfde350fd9 +8480,851312bc2101eb03 +8481,9c9321de89f91d68 +8482,50ecd40144027b3f +8483,881500264744e3ba +8484,1dd4bffbadbd502d +8485,ce85ac39dc1e3e38 +8486,fdc23212377b353c +8487,f46f5abccdd0c64f +8488,2ab7da5f37a6283e +8489,e6a51cb3980be36d +8490,fea17660959ee732 +8491,76318583ea944ab2 +8492,b6e769faa3520c14 +8493,1b2aaa74142033a5 +8494,3966d08e2060fdfe +8495,dc58c4d7b39ffd22 +8496,5223a97636e2c8c3 +8497,4b3c9b9c67b244e7 +8498,3e81e0f863f84ba9 +8499,63b1e6a15d121104 +8500,a7d13073ab69fd34 +8501,e33d12da4401eadc +8502,be5cdc3d75d3b143 +8503,d3edb4a4595f80fc +8504,cefa0a374a723ab9 +8505,18feec171fefa3ec +8506,674249e339f4661b +8507,7bc8737fb34db145 +8508,aab8721bf10ed818 +8509,51bee26640c6768a +8510,96fe8640f5015d60 +8511,81ff4e531442f1e3 +8512,e60264e87c2fa6cc +8513,8e10440590eac915 +8514,95bd2146ff27d216 +8515,e331e38b0db1e765 +8516,04718af20043d972 +8517,3530c71fe10f92e4 +8518,1f8155a1e802d511 +8519,2b7f6a310310933d +8520,8746b799f84c5631 +8521,fb446da7e9cf0a4a +8522,3b8b2a7e0ac2691e +8523,204fd6e880308b12 +8524,ea44533ce40e9e97 +8525,7b1916c9b32711e4 +8526,c36e526fc6b692d1 +8527,88b9520146ca2253 +8528,8c7d4f7f40f1ba72 +8529,06a125619251dc38 +8530,bd133ca222363d22 +8531,68bcced5d52e8d64 +8532,487b58c4f3174743 +8533,4438f06716cde824 +8534,8d92cbab6005fc23 +8535,66bd98636d26253f +8536,484c809def45605a +8537,d793313c2c54a2af +8538,252cddd8ecd868a8 +8539,4f06172099581968 +8540,83df5b10e26683be +8541,952105335de826e9 +8542,631343be8d772fc7 +8543,b9e653b9cf3abd9f +8544,77e61a7711646e02 +8545,1e510111091ee855 +8546,865b7acac72319ac +8547,c521e332cb9ea8db +8548,3c27fab126b3b8e9 +8549,44995dcd8095dd87 +8550,6dd4cbea814bd48d +8551,f063ef496bcea925 +8552,2f3e3516f90e13c3 +8553,fc5b69a94792557e +8554,6b287ed998d3a584 +8555,635a426c200c2532 +8556,4915b3bfe85fda0b +8557,60f63c9eeb69f6c6 +8558,671ab37a3b0e6d3b +8559,9e3c031676c1089e +8560,c026deb2a66d786f +8561,d1bfd59a2715fdb7 +8562,7607d2641cbe20e0 +8563,d73ab774214ef634 +8564,e6a3a23675fcc779 +8565,1cc00548862504b4 +8566,c354e8014273547b +8567,e682e9d57e1036b5 +8568,1b958ce7d5ed5eaf +8569,d4b7a876072a6e81 +8570,e7fab5140a387390 +8571,2b0cea12406e862c +8572,1119b338ed39de63 +8573,91a6b33bd7a18413 +8574,9fb8a341270c89b3 +8575,bd22e535c6fd86cd +8576,be8383fea07a557f +8577,4bf5f3d17dd99d1e +8578,b7d4f75d3401c67c +8579,15e1221392168edc +8580,eb9f80ff9c061661 +8581,c91043d1c15251e8 +8582,b60693fbb194f333 +8583,3c1ebbd46d0ccca5 +8584,f3595882cf8e9551 +8585,38326c16a731e311 +8586,16109fe7b22678af +8587,100c8ea290bd3591 +8588,dfdf586c213d277d +8589,23f053f36072fb5c +8590,a4a2ec3aa5a3bd70 +8591,66b4b93f77c8ee2d +8592,a21303de4b0b32f9 +8593,a781877504122a33 +8594,3d5902287e81f70e +8595,6f0e2210542d3524 +8596,c3821fa659c2db16 +8597,497cc60f4c704afd +8598,11ea0e6e201ca96a +8599,94a264741381be7f +8600,b69f903db401def7 +8601,48bc719ed8a4ac2d +8602,57132446a708fe7c +8603,4c1f90ca4305eb9f +8604,665b248736cd1a96 +8605,1cd05b186523b057 +8606,d8abf62fd2566d13 +8607,4687250c050eec25 +8608,04a8ffa6972bf431 +8609,a006cb9c01650f18 +8610,95e6ddbb68e203ff +8611,97533daf8463787b +8612,a7439aed391c5ae9 +8613,60bd3310d506de82 +8614,790c3f643259abe5 +8615,9e935ec0196d78ea +8616,22413e2837481a75 +8617,8d1b0d4857b3a799 +8618,d4835a05f4514d16 +8619,12acd8e6bc6e5319 +8620,d1a19f37e1b4a231 +8621,11f127000a5c34fe +8622,bbb137b2807f5a1e +8623,7dd0f9e1012f3ac8 +8624,dc70fc571c91a437 +8625,a74b54310db87b33 +8626,fbf9d5bb55c812d3 +8627,a6d9b6f45cb2828b +8628,093981a2297effa2 +8629,f4bdbc1188921f6b +8630,09a66954207f8b6d +8631,5a8133b22ee2f320 +8632,feced0121b247301 +8633,56279f0f582f5a97 +8634,0d13d360405718d8 +8635,8c703e0f34da3c7a +8636,1e2697e6b04cf0c0 +8637,7303c623a2c8d35e +8638,35377bd301f0dbfc +8639,110343b4b1f5c84b +8640,501d73d3aad746e8 +8641,6970623936ffef23 +8642,bd3c137a8b96ceda +8643,b46caa3c680681f7 +8644,37dca9d2cfcebe76 +8645,e2ea9eb1445286b3 +8646,d40fa7e07926818a +8647,198288a84683080d +8648,0e6fee22ad29bf45 +8649,dfb6ee112310ac66 +8650,53e85034eeff42df +8651,10d2ce8a7f6389bc +8652,b0f930c549c8f9fb +8653,d95c9d24521841e4 +8654,97aa2320cabd1b1d +8655,1984950d99a656ae +8656,67341887e8cc7ce4 +8657,519a8c1b9925a368 +8658,a53d51dae9bf177b +8659,9d4bf47b3aab7bd0 +8660,058af4c6e32e0a3b +8661,19f6cea31dfdbdd1 +8662,3191cbd55c713e16 +8663,688db09d9f124272 +8664,f016d075398c56af +8665,165e3ae53a91bc24 +8666,f50aafe628dc7d74 +8667,a0dd03687e7a7072 +8668,2d04c402f4c0ef1f +8669,8e011c31ea13a477 +8670,c07acb86b80c46e9 +8671,71b1406bdbbb9bde +8672,2e49fd20d3186abd +8673,b04d65786be54ceb +8674,d2b0f9181dba9ac7 +8675,4d81c9a15e020b04 +8676,73e0102930b45e4e +8677,6f134a233c8ecb48 +8678,caab505d87eea5ae +8679,3fa29660a35c6f54 +8680,33ecc05791709cc4 +8681,8ca86fd4860dde26 +8682,4ffe8ba7569bb4bf +8683,d6f32439878addd0 +8684,c6e80916eb0bca40 +8685,23c1b1e98933874c +8686,940b2606a4ff74d0 +8687,763b6cc70b199712 +8688,294f2e0b5e2e5589 +8689,591ffeb25613f61d +8690,b6bcb27b388daafa +8691,077e3df6fa1983c5 +8692,be6a6157fda0e8c9 +8693,2072d414ab865c7b +8694,b2b5c5bc1e8a5384 +8695,e71dd6c4e96be6c1 +8696,26e7a8e924316795 +8697,057d2206daa133fa +8698,8fdf368bedbe3411 +8699,89bfc9213f8edf8a +8700,9051d0dce499b856 +8701,9a021f23c8e41d5b +8702,82a0762656cc9e20 +8703,9d9aa5d04c0356c1 +8704,cebb3b15c87ef003 +8705,c8868a7a4087aae1 +8706,e297dce7898da364 +8707,ba2931f88beaca81 +8708,c4b62e11cfcadd3b +8709,97cab754a9c594db +8710,0f5c867c5b620264 +8711,2f42121a8f8f1919 +8712,43c408c2645144e0 +8713,a0ee0db59f64e396 +8714,9b28e57fffc1d647 +8715,ba85a8d0a6515f86 +8716,2780d934db63f41d +8717,ccd4e586deb8885f +8718,77924a682c710bf8 +8719,16bd72433f28f4d2 +8720,6c64dc2e749a65c0 +8721,578c3e83571afac7 +8722,ae927c94c01a59fa +8723,8d02ea6f474c2036 +8724,2aa862952347cb25 +8725,144f8e9eaf603918 +8726,b59928aeb64a834a +8727,0c1196a8a1ca7b4c +8728,c046e7b8dd23ffc4 +8729,8038e73311c613c2 +8730,c6787e571c166a53 +8731,a66b39e52e2e9e8d +8732,be18bdd38d199a5e +8733,e7fac3c6959bf7d0 +8734,4d92c65f0403716d +8735,4af9da8bab4053df +8736,ff8787203937b474 +8737,d33b529d80224174 +8738,6397a7d30df0083b +8739,028333c009cb9190 +8740,0b2594a1ed8999fe +8741,d9354fd9d0d64257 +8742,0e3257812d27a95f +8743,8b8c89f4ac5f4664 +8744,5a476926a0c9a6a4 +8745,81b2a68198df288c +8746,75c3055d30e6fa3f +8747,13634571b227df8d +8748,0c882877bcbc31da +8749,0497c2b6605ab8e3 +8750,feec1a7e84dd2c3c +8751,24ba0ac536fbc909 +8752,1b60f54cd7f8421a +8753,39efb376447bb259 +8754,2ad92dcad8672927 +8755,a27cbdd0409250a9 +8756,16db8df6ee214b48 +8757,fbd14bba286dd196 +8758,1515f6126c4f978b +8759,6060db6d67bd614a +8760,6810f10b7269fed2 +8761,376e8dd5a7152684 +8762,a5458a55d07e54af +8763,974b8ff7cceb496b +8764,90b303aa80c1566f +8765,e52900d7c01a7652 +8766,25dfe3b3a5d18fed +8767,c4ad31bda6562433 +8768,ba9287a989e9c844 +8769,a3774e473b12b49a +8770,b446a581d4e78e20 +8771,f80bc4488c906e18 +8772,7c0eefdba489660c +8773,c4b9a6f68cbd5efa +8774,e60caf951fcabf62 +8775,a292a15e66106e70 +8776,e622ce46087627f6 +8777,69b9a47fc82b7ed6 +8778,ffca4541bc9ee000 +8779,49424c7aa2ab7b2d +8780,353c7b7dfb600766 +8781,ec92bdccfffa54f7 +8782,90aa8bcfe0b659f2 +8783,59f6652773c9b1e6 +8784,d522b008fd69707a +8785,b45ba5e35820f2be +8786,91e4a4510b168b9e +8787,dc89a67973b19503 +8788,14588f91a3ad6bf2 +8789,4dffd19c15c281a8 +8790,840f9056d286a88f +8791,df0282ceea6b3a19 +8792,e2b7194599de4b73 +8793,5b1b4fc35e02dac4 +8794,1af80a6275ce7a10 +8795,eb7454f86582b11b +8796,67f8d1286650879f +8797,ba130a2dd659c091 +8798,29a8bf5c7faa60e8 +8799,bb244999afc5bc4d +8800,1a9a99d96fc6d4de +8801,b65588425e5e9b40 +8802,90be7df734912a8a +8803,89112742943176da +8804,759396728718d410 +8805,641cdb806ec2c5eb +8806,8032de939cd4d8d7 +8807,1366a1a2b5a8454d +8808,19f831a3c62662de +8809,5fdbd4e8dd368afd +8810,5531b0ace3521297 +8811,0adc5834ee396706 +8812,1b0ef3c8caa21f6c +8813,2f8d595bb5df4146 +8814,39001b88e7da808f +8815,207be5174aa1fe36 +8816,175458924a88983e +8817,62517d777dda9d4f +8818,4e5cfcbd78345b40 +8819,9f53f46364f83717 +8820,4bd4a5e4864a3a6b +8821,74bffa6f54e3a9c8 +8822,4153c0337976b574 +8823,3692c3039bd1464e +8824,eeef0e6063a5261f +8825,2653a7770e0793aa +8826,3c2d94a52e82e715 +8827,e249ae89e3288e52 +8828,6c68eb067b1d775d +8829,1f56e55331269dc7 +8830,585829944e2e301e +8831,1d0bbca7917153cd +8832,e4dd557efa30217f +8833,00387235bea63293 +8834,71fcef4094ab9715 +8835,8d5380f2880d901f +8836,0f458515ca2c56e3 +8837,075239544aa38c5b +8838,acb451a905d25260 +8839,3726359d7aa2f7c8 +8840,952b87cd42ae214c +8841,c95ab8ffe49f1d75 +8842,96f043ea22e67fc4 +8843,fc3287f316eed45a +8844,328dc4caa89274b1 +8845,e5684e12a9509b83 +8846,f73c2ba423d566a5 +8847,000199a035184bed +8848,84dc6c638c735ed7 +8849,e08071307d3c06b3 +8850,895677cef966a3f8 +8851,684b53e142aac343 +8852,9b5bf8e1485176c7 +8853,bdc8c7338a6b47bc +8854,51f0448263191f4f +8855,28fc158bbad4360e +8856,66900be01cf6b530 +8857,9afc5bbe1539b595 +8858,c026633c46ad1691 +8859,81405325b67b8239 +8860,06cff080d53ec993 +8861,73f80f3574ea9a59 +8862,7254f625fa40116b +8863,c402c887c7f9e252 +8864,4b69ebe7ffcda887 +8865,78a850e243568e49 +8866,115219a20a00d46f +8867,30653a63eb61b7b6 +8868,8b202efb698847e4 +8869,45e5f61af9f9d57c +8870,25da070fe2419cfb +8871,713b6f8c913ab055 +8872,53973d6601eadf51 +8873,2a0f5d9d3f4803eb +8874,ec6799e21cfecbf1 +8875,98caf02a0ccffd8e +8876,98eeb84f8487bf92 +8877,d901d13c88a9a6fa +8878,047f2a053ec5a957 +8879,fae4b8fd600ad517 +8880,fc9e8e659c857430 +8881,e0ae4cb00adb3e1b +8882,47499beba59562cb +8883,24171ec51e1522ba +8884,64191c31cb9da243 +8885,f3d75dc6df45dcbd +8886,93349034688afa5e +8887,82d796a236fcc4bc +8888,d340d97894726165 +8889,41fbd9cb3c7401dd +8890,946da027f20006c4 +8891,019c3e6a481a75de +8892,f1c94ae1b1a94343 +8893,b626764243ed0899 +8894,2aa9e0059940fcb0 +8895,dc291402d6ffb6f2 +8896,a513425edf29543b +8897,b2c2aa41f41800f3 +8898,e8c1a6ea28251c3e +8899,71b3e30caac1a1c3 +8900,7354f2004b48f472 +8901,b10d49fd47b0cf35 +8902,49da82e27c7522cd +8903,b5950dd1ec889064 +8904,1facf374a034b870 +8905,3744df9602a81757 +8906,bcd0474c6db2a9e4 +8907,4515019e94efaf5e +8908,332554b15161fa96 +8909,48fddbc703f68cae +8910,c424ab27fc6dd73f +8911,5c9b34d8d4678425 +8912,799e54185dc7b823 +8913,af3376828975c94f +8914,318b051e9e4ebeb3 +8915,f945df3442353d87 +8916,6a0432e1aab35b59 +8917,0460c5de60215e5b +8918,e366f5763c5819d0 +8919,e0b5cf442d2273c1 +8920,cd344919804a7042 +8921,6163e88866b91e4d +8922,ec061161b457e0bd +8923,d884757cc522f201 +8924,d847befa36bb67f2 +8925,0fcf77b731ba68c2 +8926,6202dd7acf5c98d7 +8927,a71cb447fce1bd18 +8928,b81597e9f1c57985 +8929,0d97be7b1e0e6241 +8930,bd735967db0e69b4 +8931,0c7c2ba1aa14bbf5 +8932,7d78654d3745cfa9 +8933,d9d0c0384232465a +8934,d36fa7cb11f998bd +8935,950bc6a3e88ff73e +8936,ea9950415ed8dd1b +8937,b53997bf2755ce3a +8938,a7a63f47b7839a02 +8939,84aef74318ae02b8 +8940,37796eb83f84521b +8941,fcb9d4176007b88e +8942,c5f77e7f7d701f2a +8943,80282d7898c3eff2 +8944,bde1c3bfb4fdb65d +8945,bbb1f6292cb6e2b8 +8946,bf884e5d6710c881 +8947,72ac029b6c8297a6 +8948,29b0b81a58af3cf8 +8949,171dab91bf4107c0 +8950,c05ab9c8526ab2e4 +8951,b522abb67d0bd1d9 +8952,61f3f7bbb6ba768e +8953,06dfbd9c827d214f +8954,337f19e859ecf576 +8955,036a1c88319ba29d +8956,35e509b5ba70ac90 +8957,ecd43960fb1b65ee +8958,04cb0a747b7f1ef4 +8959,781bde69f9de84d6 +8960,55666dad90a74085 +8961,c00437451e27da4b +8962,2cde26a5c397f32e +8963,401cf33837597660 +8964,5f10025c9090dd21 +8965,df037ddaaac49fe9 +8966,a2858ce2f176d108 +8967,9afed6f1b2da855c +8968,6001034a416a3f99 +8969,2b5bc6263a2d8c55 +8970,b6dbfbdec1835b7c +8971,0bb91c2eaf41605e +8972,91165666475536bd +8973,ef5b84e40ea8340f +8974,bf90c71e6fcd9690 +8975,5ae7d6b5bc35604d +8976,59546917e9f500b5 +8977,022d1b6a776697cd +8978,fbe52fbe7d1745ee +8979,9f3c6e37bf0e1c29 +8980,2f8806f1415467fd +8981,16e3f8620c4e2099 +8982,b9791add5aa43ce3 +8983,4eed8436c49aa96e +8984,40f2e97243926342 +8985,baf46fa2b0719321 +8986,7e9d87ea8c4994d8 +8987,cf690294da591a65 +8988,8a135b49b6c3a2d4 +8989,95d1d318c18d3237 +8990,b0477d890f358ea2 +8991,5c6b71629ab15040 +8992,effa72d4ee225243 +8993,f7345af480590f1f +8994,de84637c8847ae85 +8995,bef3872b55c22fe4 +8996,7c76f32286bd5077 +8997,3264cf8630780988 +8998,e4e5103f1525149d +8999,5fa98d0b20f13b66 +9000,396a66704ce89fb8 +9001,b491851ca82daabe +9002,db97bfa1666a97b0 +9003,6a6d5ad73eb6017a +9004,350c35859ea6e079 +9005,36c1c080866a0207 +9006,4423d7f2f9d7588a +9007,5d8eb3e6729293a6 +9008,3b93dc2d5af483f9 +9009,f6c3d013da0c3b65 +9010,c8011e90fc7a8e48 +9011,2713f92197f07cf7 +9012,64005278075acca5 +9013,8d6070e335d18884 +9014,e463ebfecad39c77 +9015,713bbe664f86ebd5 +9016,267d1a76e8aa7d67 +9017,fef30ed51ee76626 +9018,13bb9c6f1f0d46a3 +9019,2187775d4f54f659 +9020,a4a64b01b80505d6 +9021,d255ca8254ef4c60 +9022,e775f1b1f814665f +9023,2229384c6d850fd8 +9024,60044e320ce9cfa7 +9025,8a6abb7aac1c2386 +9026,ec5470909cd38527 +9027,f5ea5125a6caed4d +9028,3b9a9f999e900249 +9029,5571e063a43551d3 +9030,ebba26c12063ac43 +9031,9e0f6a5124459889 +9032,1c4425486f93af4a +9033,69aafb360087cb85 +9034,e1002f757672df6a +9035,4aad82d5bfd61b71 +9036,f008233a57dd8923 +9037,ae5ce3c102dc1861 +9038,7e9ce70c774cbab9 +9039,1c302aaf1622d1cf +9040,f47e9dfc2fd4f786 +9041,79d722b523e962c0 +9042,26b5b7f5670795e9 +9043,87bf1c2e3ce67c6e +9044,f6283ac89f9fa864 +9045,a454724e6688be5f +9046,e75725d8360cc8cf +9047,6b20dacccad6768a +9048,02a8c8325b79a934 +9049,bd5890cf31728fe5 +9050,8af0e78a1796a41a +9051,3327fc1a3c29fb74 +9052,ee444712a9fffb91 +9053,e74efbe928242ffe +9054,dea4adecd4d298e1 +9055,c0c7571564bff457 +9056,fa7c631542ab1d23 +9057,f0d7b4dac5b5423a +9058,689dcb6a5ab87f3c +9059,abbbf64f5161f745 +9060,4980fc518efcde99 +9061,90173375a3e22465 +9062,6fc6b83e5d9f9f5d +9063,897fbf81d41f1c4d +9064,fcc73396969c003d +9065,53e2b5cec6733a49 +9066,5d1567adb5535224 +9067,0292f06125d05b71 +9068,7e81b640c0b381ae +9069,c8e925b2a24177e6 +9070,a665ffa7410e55a2 +9071,57f1e65bfd90b7c6 +9072,5104934402b43bb0 +9073,69f059914499b9be +9074,8bce49f5c0963e5f +9075,41af36e3a5f02861 +9076,f589392c79719c48 +9077,834728d58057005f +9078,e5dd8b2d29ae4e93 +9079,d111907c81b7daab +9080,553ce693f2e6827b +9081,08243919e750744d +9082,2e6e02e70b87a708 +9083,295e736e72633329 +9084,066cfd3a5e91418c +9085,9f573c25a8599a64 +9086,a6b4b6f437adaf20 +9087,25740baf1ddd957d +9088,b97e986524393f01 +9089,d192eee331dc5a10 +9090,6945bf0fcd138eab +9091,0cb090b6471d123a +9092,70db500706780d4f +9093,76c3a5bf331d913c +9094,9ad3a4f7aa0b14d9 +9095,98419e1b0d2f3225 +9096,bac600b8abd29534 +9097,96518ef526c0e369 +9098,8190134f989503d3 +9099,4f00014aa5bb1967 +9100,a26ac0f6de6893a4 +9101,e015ce6048b12ff2 +9102,e9cbf3ef357282c9 +9103,b3ef2c42d37161b7 +9104,b881bebc09249306 +9105,4291a6227e7b9218 +9106,3b82b4ab909f0968 +9107,23700c2b0de49b92 +9108,cc201b50c7df56ad +9109,0c08d443b4ffe9e9 +9110,23ec8e7e22ea6eb2 +9111,07d26421abf74d69 +9112,dc92d882ea2c1f5d +9113,cca7328c58d2aa24 +9114,cb09665b2c3bdf04 +9115,a9922079b56b9501 +9116,be5f5c451b80664d +9117,d5fbb94e28965202 +9118,a955f1edbdcfda7c +9119,c4eb621caa72618c +9120,f5eff8a7283c8c9b +9121,103d08d9527be489 +9122,78a1e0135a11d19c +9123,a8f9c2a43d84300b +9124,68e60d0acc2e5327 +9125,05aeb20f7715abfd +9126,c084dcd46bc67ad9 +9127,e46f79b3b49454a3 +9128,db8eb32e472cb79e +9129,06f0d65c545e1f13 +9130,35238280a7156ae9 +9131,2a875f85f1ae5a03 +9132,a8de669795ef3fcd +9133,2c31d078741fc4a2 +9134,ceb7a2a7e1249469 +9135,98b77ae6b853828e +9136,377778ac8b2da202 +9137,887a044ee88f9479 +9138,6e927e90d039a435 +9139,826a7f6589d25135 +9140,c82e552c69a1c900 +9141,462daa7bc7353bde +9142,32c628911778ec60 +9143,670c5691164f0134 +9144,a58c3578242942e7 +9145,b5031194bd89c13d +9146,c2a1247bfe35bc7d +9147,f1f61a7f26ba0fbc +9148,1b7d7659ad53f445 +9149,c29b6526fdedac7b +9150,80fc579304e3514d +9151,428a986291794318 +9152,cc506188cddda1e5 +9153,44a09b73ca87ff6e +9154,350e88a4fbdba72d +9155,263bd0a5c0671405 +9156,d0ee9e88caf642f2 +9157,96a1ff7a88d36c9a +9158,5311e3872b88fed6 +9159,25813cccbf97bc23 +9160,121e350028ea3122 +9161,54152232922897a3 +9162,797970dab939e5ff +9163,6b41e8eac0dfa2a3 +9164,96f9e4fa560dfcab +9165,af79fb0d3610b952 +9166,9b3e78a8cbf3a591 +9167,a506263a7deb4565 +9168,6aaa815ef6f19076 +9169,52fa31285b15649b +9170,1c3c910b3232fa02 +9171,59eed1fcb81f645b +9172,65a262e87a915240 +9173,854fa42c2621b09c +9174,b3a3639fb2e10778 +9175,85eb514fcaab9141 +9176,643e7c0cd3be865f +9177,dde0d87c4b6954ff +9178,8358e602ae77baac +9179,70c2de7770f34745 +9180,97195f2a7f611e1a +9181,2df60872be511bd3 +9182,7755a4c530276767 +9183,23351f12aa183eb3 +9184,930d7e1f0631151a +9185,2cfa267da90dffc7 +9186,bd9ef332409be99b +9187,f78c26217a5fd423 +9188,032555f9c83379da +9189,b7cf9b9c26344103 +9190,d45fb8be136e0fb3 +9191,5b10c060c6640848 +9192,42ffae83e5d85019 +9193,5799d329054988d7 +9194,2f0563d324050985 +9195,10a24710d1861789 +9196,4311c4c95fe14e1f +9197,79fa47bbeefa6f7c +9198,5e073ac7859ed19a +9199,60139162854e6c2b +9200,3d5fd19382947b35 +9201,5c9cfabc61b99b33 +9202,361cde8db10d01a3 +9203,bc9252c4b1a38cbb +9204,4365bdf94098a355 +9205,0fcb72892ad8c99a +9206,4848e2a762ffb50d +9207,75a061a213e153a7 +9208,656c92574d0a6c58 +9209,075a29a288067e84 +9210,a337c8c388c2b365 +9211,e2ad57b02b6535a8 +9212,5bcdfc01051f640b +9213,8b3a2dcb9396966b +9214,d3fc7888c1eaefde +9215,263eb2da3e2392b8 +9216,b659f408c065a742 +9217,9c568a9069fe4189 +9218,c0909b6ee6e4cc3e +9219,ce2c938c048a8933 +9220,70440148698cdc35 +9221,29867f4374257636 +9222,47e771d671558ca3 +9223,d3beadef6ae29439 +9224,8755b62d82064afd +9225,d8daa8fc9b463bc3 +9226,2de06908c25f7e22 +9227,284ae58b2f56ec07 +9228,c695590dcc8fd701 +9229,9ac331e854d2c225 +9230,739f67782e116927 +9231,816e8d2eb56264d5 +9232,423205686fc9bbc3 +9233,d250fd0feb300fb2 +9234,12870cd5fab31066 +9235,a99dfb9c5b4981a0 +9236,8c05d2f239bc8c64 +9237,ec3b78eb8c2ba723 +9238,bfd7af62191c6ada +9239,4a44f448dcccd110 +9240,c2fc25096b0c02d5 +9241,bd78db7e95bb3d58 +9242,7a5bb029ff8801b8 +9243,560de72b9e475078 +9244,4cbd120058ea780f +9245,38112cf53a777e82 +9246,01d520732b4ec091 +9247,ec5069dbd0c88766 +9248,5d86c412f0648c8b +9249,9f5df715bc0a84ec +9250,7c3ba0441f8adf5f +9251,64d31f3ea89ece4a +9252,50a909d4fc00005b +9253,78eab1ba663a6e22 +9254,433a39c4acb9d0aa +9255,9574615b2bd0bc5a +9256,ef86b85f9288d3b9 +9257,43ffedd613b7faeb +9258,feeed6bc2bc63e19 +9259,49b8f00c2e749fa6 +9260,dcac210fdb17931c +9261,88fa2e9c0018f0a3 +9262,de7e459ca02beb2d +9263,7801c3a89c2a3396 +9264,0cc45b771d0dec32 +9265,02fa935a2d534741 +9266,1b5730713b3cf40b +9267,9cb34970e2d1b467 +9268,016ff426dc8882c6 +9269,dab3e87aa5bb2e57 +9270,cd0b536dc2503fee +9271,554881f5f43857d1 +9272,dc02e77a44277e2c +9273,5389f014f4bdd8ed +9274,f321959094cc3817 +9275,67fcd6aedf0a72af +9276,794d6f96ff583012 +9277,5f4e042ed622e272 +9278,e57fc5d36c4dbd25 +9279,63109b1027672662 +9280,c148f66b561aa41b +9281,5ccb95225ad9ea7f +9282,132bae3e3b6c4a48 +9283,2bd9240f14a0c7eb +9284,0bd8b3f6fb248fdd +9285,17b4f00bb7f54146 +9286,57ba4edf8b87caf7 +9287,ff5e674ee4f1e3d4 +9288,e6791536c36878d5 +9289,496c51131d82d77b +9290,0276cb129397f191 +9291,b6c0d5b9df0b064c +9292,00592f74df8a4bd6 +9293,4aaf596a18cbd3de +9294,0a294716f7d31a1c +9295,416ce21b5ae7761d +9296,8fa7dc7215543077 +9297,57bb3cbf6f798c18 +9298,ad895646c9ab845c +9299,3d95270c2875a8f0 +9300,d20a0ddef33bae5d +9301,4659aae5ff56ed02 +9302,fc9d3e6cdba180cc +9303,5b33bf446b974cdc +9304,690a4df67ea90823 +9305,ecf8056cfa0c7420 +9306,5bfb9c06e7045188 +9307,9376e62ea41dd8f8 +9308,ad11d1a7238cffb5 +9309,a2f9f413f0eaca7d +9310,37dac8e9f7cf492f +9311,f893d167bd058fbe +9312,fe86d16062bf131d +9313,c41a12eeeb8d3228 +9314,69cd7c3aec932ee4 +9315,53b2adac4ce6893f +9316,0dc87ac1c64c08ef +9317,badb62ffb500c5dd +9318,b64ffe1c864f6826 +9319,89b6e6e505bd3260 +9320,ff257a6aba1ece16 +9321,bb094f5a8906a070 +9322,96c5275fcb33522f +9323,c4909feb1ac874ce +9324,6637103799e995b6 +9325,e985585e82ae0eb7 +9326,5895ef20de143133 +9327,d13ee2403338dd4d +9328,16b95fd0f46d06d3 +9329,8bf5b9383d4d428f +9330,75a87168e14d1821 +9331,5414db781e8fbaf3 +9332,320545011bc49f55 +9333,b8e75fed148d8849 +9334,fae7ec47b36ef1b0 +9335,7ed72110558d94fb +9336,2d64f5b0eeb531a6 +9337,6d4a50d2204e06b6 +9338,77f1b4c065f5b36a +9339,238a80feb622ac60 +9340,ae0420c14704f942 +9341,d0cec432c4bd424b +9342,3ebfee1b3e8ccc73 +9343,b7f267e21c4ca738 +9344,c179767f4b8a01d4 +9345,61c9da5dee0ff120 +9346,623e99ef3374c9b4 +9347,00de01627c8ca9c6 +9348,e670d28de71c8a45 +9349,857e4d29edc8ff59 +9350,f4fe621eff3851c4 +9351,b20775ef7e904362 +9352,219e4cd730fb4110 +9353,240f4d55c76ab7fb +9354,42557f6cb7d3a1b7 +9355,d486b1c2be75434e +9356,4c86d49d717bfe3d +9357,5fe59366cc72b96a +9358,a7fbd478fa782ef3 +9359,ba5ccd19c2a6cda1 +9360,f18ae6dccd194320 +9361,58380e6728a65749 +9362,50deaad7dced3174 +9363,4280e89b11a63440 +9364,448008e8448e074c +9365,e5f8b9635c2a14ff +9366,1fb2f9728470d05e +9367,1b5ff58d7555a57d +9368,857faf714cdf224a +9369,b11883a78ae7e57d +9370,39674d47d7a8e42c +9371,8c1728456290829d +9372,b7044d6a24f0e787 +9373,1511af81f9193bc0 +9374,4904fbcebe6cc59e +9375,4392408e4d8b1006 +9376,8dbdafe0c8ecb0bd +9377,f6540b02dcf9a28c +9378,8665e3ca847b642a +9379,470789efd5fd454d +9380,9a77779519dc65d8 +9381,2b009eedc709b543 +9382,c36cfd276a7c5781 +9383,6dfcf2e33824fb71 +9384,0d084d9e702e7fa4 +9385,ba1b3899901303fa +9386,3f86168d22ab11fe +9387,735c5e76ca134f50 +9388,73d1a25f4fde385c +9389,9ee7e248b2e4af65 +9390,05ce3443b3a4ea75 +9391,d1bed24427454d8c +9392,12af7ad7cbaec07d +9393,84f1b6579b4f5349 +9394,0dea80850890c1c9 +9395,3f9e42adab5a6b5a +9396,6b9b65239bbc16ba +9397,fae988a94c35eb93 +9398,849dd9b74c38d7aa +9399,332c01df2f3c0e08 +9400,d402838883d3cad9 +9401,c44a0a5e5e6f3b89 +9402,db8400f7ab5ec673 +9403,f9015b6fe44a94e8 +9404,f9ddb2d0a08b5acf +9405,ad3f3a6f59f8d7a9 +9406,49f39fa348b5da30 +9407,f0c8e9d0537bc047 +9408,3801a8c958efe3bb +9409,dca5aced670e0f02 +9410,d1301cb74ba89897 +9411,a83f606ba01263ad +9412,82aa1ff23afce69a +9413,aaeec0347feff746 +9414,13666f6138b68f4a +9415,6e76cb89c48c4423 +9416,8363ff028e82e6e0 +9417,31b7f3f129a9ee13 +9418,4479dc0673a40505 +9419,4b76745e904c01d9 +9420,49cb633d570d829f +9421,f86e50ff18a6bd5b +9422,13240f307cabc9dc +9423,849d73c10fcee737 +9424,5182d63dfa4a0156 +9425,e3092b2a16ba98f3 +9426,58af33b90ab51256 +9427,6caec1bf8ebe05c8 +9428,1c662c1cfa74cb15 +9429,8f74da9bb316f35f +9430,08631f8ae1fceed1 +9431,05643448d3deeb2b +9432,a54712659d5738a6 +9433,57c3ad275c5ba16e +9434,747cd863a026ee03 +9435,6a3b6c87f1c928e4 +9436,f34b23041f30380f +9437,bcbe5502d9b45cc0 +9438,c13ee97d30261ab8 +9439,a446927f7d71ea24 +9440,dcbd1a75ddcf3cf2 +9441,fa77a3adf7f38c13 +9442,dfe2f30bba3f2625 +9443,203216981a129766 +9444,e7718277e1654f07 +9445,0290b28f9b417210 +9446,330f3b7fae16dbf7 +9447,d24afaf84c123d81 +9448,c102404f69019a2b +9449,b6e3f3267f916f49 +9450,9bdb5cf228275f54 +9451,a6c89031b90b3665 +9452,7292bc2ab6cd55d0 +9453,0367764fde55b45f +9454,49ffa227db32d800 +9455,b88af07143511338 +9456,3632f7af899829f3 +9457,a7cf5d977b9a9d81 +9458,3c008f0ed9fb7874 +9459,e75b34df3d30b565 +9460,deb7f823bedc8c33 +9461,09f0fc19636737ec +9462,2ee41a5295c0157b +9463,cd6da5026a1de944 +9464,ab408e107e7f057e +9465,b7ba181897ae26df +9466,92247a0958a1f14d +9467,6b94c0678aef507a +9468,7809a31821a1f68c +9469,29de34cbf082d5bf +9470,ce4f773d0d2d3829 +9471,198c5ae247340c6f +9472,706be029321994e0 +9473,52e065b9a709ea0b +9474,9b44afd0e0ef028a +9475,b36e3735192aa610 +9476,4701c6ae9f60691e +9477,07af1c64dbba1422 +9478,f647a1192511c9d9 +9479,bffbd3ef0d88d85d +9480,9fb257844b4d2772 +9481,10aca731c4d16e5d +9482,edd395b2417cd60a +9483,7b5ce182290ecdd4 +9484,e4327f63dca912e5 +9485,52ef85bb9d5de6d6 +9486,2da91ba9f648234d +9487,f692071a353e6279 +9488,9d206124acea6b1b +9489,1ef0b921f9f9306a +9490,06e07b37f3c1f522 +9491,749616b74ab45e74 +9492,e229e22ebc11ee3f +9493,1ba9afe6175c4602 +9494,fa792ad4170b81bc +9495,767f72c1bd640f9a +9496,871f9bb4579622db +9497,ba46cb248e0f3c24 +9498,ad9c8ce02d18d773 +9499,0f1b993280f057ed +9500,0b786910cd91a49e +9501,dee780cb6a1af714 +9502,c25307496a2029df +9503,45e2518f0d2a6032 +9504,4d4d5682d144647f +9505,6532412f3fcd9396 +9506,8fe774dd5ccdf2fa +9507,53b3e43231e6fc17 +9508,44a37a7e6b5d00b1 +9509,3a1301ca342da0d7 +9510,6d5873bc64275fcf +9511,b7896407663312de +9512,a8641a15dba48ff3 +9513,d4d29ddc9379621a +9514,9d4f9a67bf4c5108 +9515,ffb78c77861e51b7 +9516,98fda3961ff67d1c +9517,4334efc280cdf911 +9518,bdb9c9197f1022dd +9519,50d0b0f5ceda6e5d +9520,a2c00f64d9526a72 +9521,85478820fc4793f3 +9522,885f4174608a7be1 +9523,feff182abdd92d9f +9524,bb107353fd6a15d1 +9525,700968ce666937cd +9526,5ba8c24e76ce8068 +9527,da3019cad54eba67 +9528,0a2feed594e0918d +9529,fdefc2507d953519 +9530,f3ae0ce8778ec549 +9531,027c553a78c97568 +9532,436401a2502ec3e8 +9533,75f6df5223bd736b +9534,31fd1c8e6cacea44 +9535,7ef170ab834116ba +9536,a5512cee2ad4f12b +9537,68b0de42f759b6ba +9538,6629fa5154b144b0 +9539,bc968fe55c3ed25f +9540,580133ac9a11c54f +9541,ffd53858f4e6e447 +9542,7dad5720c766af25 +9543,a75c17b87aa727d4 +9544,52be71e59461368f +9545,c492c414afac2427 +9546,b414c31eac9872a5 +9547,91aad2f9d6f70fc9 +9548,82ba1bb2df17c7d4 +9549,cb30fb8f25143d10 +9550,de59f9bcaacd9ced +9551,a1afb99895b6893f +9552,fc3baed5495aaef9 +9553,4085c4f6c85b342d +9554,4bf4ff7cf7c50852 +9555,7a7b0dd6ca802f34 +9556,1e6b09ee652c3ac9 +9557,610386094abae795 +9558,2f28dc2dcfcb87eb +9559,525decb27c9bb7b1 +9560,f6ba18254a84270e +9561,8030bea601f1e513 +9562,35d8d3b2416921b5 +9563,b4adfbfc958e961a +9564,5fc8bd077a126d1b +9565,87c461ea003f337b +9566,2712c3ad5ee94cdc +9567,10242dbd55b35d89 +9568,0345ffb3a270d1d8 +9569,092dc73bf8e4b06b +9570,ccc87326b87d654c +9571,5b9d16a6c29f7f80 +9572,f462f9757df551f5 +9573,83a1d042f5c80220 +9574,63a535ae19c2f5ad +9575,7dc8b59bf93138a2 +9576,3c956ed98a54d6cc +9577,feeff214a90a8e9b +9578,a861ad7fb8b44a62 +9579,b8236952b398b22b +9580,4562780890bed8ed +9581,74a6342c7d2ca3a7 +9582,b5e83d3535dbf7c4 +9583,c0805158da110784 +9584,ef6a1d3a7ae8d3cb +9585,3bc42f5dffc4be51 +9586,f19bdc83eaca034e +9587,0a3e5c8e94718f59 +9588,1fd38434529fec0c +9589,064e93913b5cf80b +9590,241e77a0a351c675 +9591,77770c02af8282fb +9592,8d577bf351779197 +9593,7322d786914914cc +9594,f3bfd49ae6c853aa +9595,3cec88a57ea00b7d +9596,6a7829852ded9ff9 +9597,839ad024b85ff03b +9598,29a66acbedf89cb5 +9599,779c5b83cdfcc113 +9600,9f8697fa0d92ce1b +9601,706c9da9e5a6e308 +9602,10f61b5db8117e67 +9603,79fdf9bc13c7b4f6 +9604,1223b4bde6488267 +9605,b887033fd119ebc3 +9606,ffd2bad2cb67bc76 +9607,e87ec3ea11359e94 +9608,a70f2292a7cac4ae +9609,c17aa6cb1a4bfad4 +9610,bb92e754be624803 +9611,a4687ef86d3dd179 +9612,0e2027a0f292e5b4 +9613,f495eba74a8f2a2e +9614,71a493f84608e74a +9615,2293518c118b6940 +9616,a43365fcfa4ba482 +9617,ce23f7857f1b7062 +9618,a8b55cd47ef6793b +9619,782d6dcfcb300537 +9620,95dba7d4da27d8c0 +9621,10efdfbbd5a06221 +9622,d6a72487a3a5ac3b +9623,efcff55b671e5030 +9624,be7ca86d78ecc2eb +9625,35df28b55dfe8545 +9626,11c19d77e66d0a0b +9627,3d2d973e189a4342 +9628,c53ef6ef112d5476 +9629,0dbaeaff65b0d7e1 +9630,496e991a9e9d3252 +9631,5b7a8be1970af6ff +9632,3dadf30929b2dea3 +9633,0e1098fdde02e5bd +9634,39b55135690f506f +9635,f0225c0acd336b84 +9636,cba216fd7c055641 +9637,eecfb24f8501aa0a +9638,952c91f25111f6cc +9639,fff0788cee784739 +9640,b02cd9b6bd8cc9b7 +9641,068f11c0893590ff +9642,4cead936c729ba43 +9643,fcd33dca03925b5b +9644,f54adf9d0dfda1be +9645,b49d89d600c28367 +9646,beb49af0090c626d +9647,cfc1f739ad2c2142 +9648,bcd358c84020777e +9649,07a69d31b9b4df8b +9650,92a461f53a3aafe8 +9651,83fd26be30215bf0 +9652,b7b18b44794991d4 +9653,e048063d86acbe6e +9654,c654dd8ed9cbd1f2 +9655,b45c4b50615501d5 +9656,0b8f83aab44041bc +9657,01bee9cabf4c461a +9658,71cc18453734bb14 +9659,984b69b4bfdebf9b +9660,2dcfc04fe131c88a +9661,1dddec5b85744e6a +9662,9d95549c26dc5352 +9663,c7f8d97348feb160 +9664,01e75ef488920f34 +9665,f0190af7d545157f +9666,bc533f331410ca67 +9667,39e9dd4dc17f9f10 +9668,61ab9c2c8f0edc28 +9669,0b6f563fdc8493d4 +9670,9d1a0ea4398e6e9b +9671,e319a55bd40091d8 +9672,d7d7c735cfb1ecbd +9673,207857b3913ae1dc +9674,a5be8139efe2570b +9675,0999ea465d1898f7 +9676,7f3db2f39ff52935 +9677,0704d74f2a0e8079 +9678,366364e66cc6029d +9679,77029783be17e89f +9680,65c81c8e18b5d155 +9681,03ed7059ce29c8e0 +9682,b033747f9c6df2f6 +9683,1db4a4ca1c8b6626 +9684,54ff4900179c9218 +9685,d847821977d94671 +9686,4eac81fb33df6714 +9687,9ae0b0ffa9f71d3a +9688,1730eb29ac251552 +9689,26dae150e1df1c42 +9690,916c5a618b5f6464 +9691,216deb7019d11dda +9692,68c6c7f0837d48fd +9693,75864ad85874dfd0 +9694,32e56915839ab3c2 +9695,ffeb1a6bc80910c7 +9696,e99497ab93e3f0ab +9697,45d8ce13ccaab383 +9698,2e9073ccea1c849f +9699,a0676e78e32008ae +9700,d6ddea96eb0c0bf8 +9701,dce6357b0213e82f +9702,ead8885b9cfb8834 +9703,4300f89636002e5f +9704,af463648605572c8 +9705,aec0d33d2a5c4de8 +9706,f32576b7559650b0 +9707,6e2dd97e87392db8 +9708,17c930234061be25 +9709,a65b654b2198198f +9710,c8fff3b26b4e9f89 +9711,b752d4be1ab6849b +9712,31f567fbb981a536 +9713,b5aa3ee6a3e6aae8 +9714,5207128a27acd3d9 +9715,ab79fa96f0efd3ab +9716,fa3313b512ff2e4d +9717,7685a87ee7586309 +9718,c61d25e39dd4acef +9719,c6b3cf304f89aa23 +9720,cda331e5833a72a8 +9721,e321e8bc9a87b3d5 +9722,7bd10444b8f4952f +9723,01644eb9249a813d +9724,b585d8dd7bcf622d +9725,29fdb1560d4ab392 +9726,e0014214b003370e +9727,3f75c189921da731 +9728,53b95448e67e2696 +9729,a9cbfb60108d8757 +9730,90504a9363761e10 +9731,4c53926ec6d5dc7d +9732,b6272d121b137e90 +9733,0e797cf6639eadfc +9734,df1ce7bcf141e1f1 +9735,2adc49d3067a668f +9736,8e281c4ad1c68f0c +9737,80928296759faa1a +9738,eb83c3c66b482f04 +9739,d4161f74d76764ae +9740,235f855ea3f11695 +9741,bc95aa56d4f9e1c9 +9742,0cfc9ab640085727 +9743,980687211373ad4a +9744,7ef08946a829be74 +9745,3813411fa5b888f8 +9746,7877a4f7f3f4de7e +9747,49669f724e820aeb +9748,5dafb59fadaec7af +9749,690446142285baed +9750,217541e1c22083d8 +9751,0fc99b00c1bfee09 +9752,ae8e4c6a5b7b4ba7 +9753,08458864beb0360c +9754,d4ccf136f0f89c6b +9755,f75c23551057ef22 +9756,23cc69df40d0ebb1 +9757,03ddf67ea8ff59a2 +9758,e93fd3ecd6ddb38c +9759,54bf06a1739b9815 +9760,817949d458edb4ac +9761,e377fae1f6e0e287 +9762,981b038d120eaeef +9763,89e63bdcf4356bc5 +9764,c0e3af6cb3651f70 +9765,6b4e9426577c4124 +9766,342e80f6eae94aaa +9767,9bf39e9fd94856c0 +9768,dabe9a23e99ace63 +9769,09748c92e7dadf66 +9770,2afd5af047854e22 +9771,636c488e8b4d2006 +9772,ef95b57c868aa8e6 +9773,b9bd6d8baecb5d2e +9774,029357014339bf86 +9775,96f247e2472196a8 +9776,ce22b271dd7e0ff6 +9777,c30eaf4bcf9c8d40 +9778,fcb0d68f372b6799 +9779,86ea93bbef592e98 +9780,f11d9c083291a773 +9781,5976e794ea1300f5 +9782,0312b6cfc15c1464 +9783,097ac4607747fd61 +9784,beb7eb20f29f1d0e +9785,05c145f4270d5ee6 +9786,da38abdea7ae6068 +9787,08c4fb1cff95e4f1 +9788,1d2e669bf5603f96 +9789,d7d313c0086ac01f +9790,0c8efabb29cbe7a6 +9791,38641d67eb783c5e +9792,f91ab2fdaf123692 +9793,df92d8f25fea932a +9794,0a94f9e772d102dd +9795,ccf615bce1478298 +9796,12ae6c5e7f6b179c +9797,a87d7c37ec2d1f03 +9798,227a1ec1a71d4ada +9799,b6422f9ac2214ec9 +9800,0fa2d3a562b40cfc +9801,436dc0cf396cef17 +9802,b87f49cbb2522c60 +9803,4f1022cbddcf3b6f +9804,5e49965f9919ada1 +9805,f72f0f9529411745 +9806,2f0326954fe0101d +9807,596cbcfb53461f4d +9808,9401b249f8c62501 +9809,ca81f56a24fed7fb +9810,acff5bce093431cb +9811,c755b6bf1e246273 +9812,3c2f17eda39579c1 +9813,cf74f25543226c0e +9814,04f1271a20d6365f +9815,617a00b9ebdefd1d +9816,a4fbd35c5ce913f2 +9817,6d16138e11762735 +9818,b024a6c88e1dc12b +9819,577ddfb8599dbf36 +9820,1e9beed0b42f7b67 +9821,1f0f642fada471e8 +9822,5eb0ba084804d57c +9823,be641f4861531b09 +9824,e9a65d2cf743aa04 +9825,7ae985f3a36f35eb +9826,5c3054a05cf07670 +9827,fdb8085f40f65bb7 +9828,feb74324d570f50d +9829,3d17fa04aa570cbd +9830,476b59a6c2ef9387 +9831,7d9cd815fe1290de +9832,c3da02291d1135fb +9833,cd933dc032600788 +9834,386183a9d4364ddb +9835,b30f83ca2630e74b +9836,41913db74210e91b +9837,2f9648f2b424dddb +9838,11680251eda1b016 +9839,469c918732a1382e +9840,0aa889b15add9ae7 +9841,380a618526ce1d19 +9842,980b73f725a43898 +9843,afe3f8a543a37718 +9844,f5e1b4a1f19109ee +9845,b8626710830ceb9c +9846,e204915d69d33acf +9847,174ce50cbe1b086a +9848,3f73de7ab4776b52 +9849,7c7ba0bb82d172d2 +9850,777aabc0d2508fcb +9851,63897f07c0561b50 +9852,a2fcfb332c44091d +9853,6bd696c98a8d362f +9854,52cd17effd39f0ba +9855,c4a7a9e2ac97ff8b +9856,da8b65e247cdb75a +9857,bb92a1f3610caaa8 +9858,3114e54fcfad8b0d +9859,596b3f8299d413b1 +9860,bab6dfa2984380b7 +9861,16530143ce8275d4 +9862,250ac10dd9b3ead5 +9863,febe56f30883ebf5 +9864,b9ff472d10448618 +9865,7667b6bd7d85de80 +9866,c92708c5b70bda28 +9867,ef8fd3e6e0aaa442 +9868,bc9dd0697498ee9f +9869,e0a8fbd449ad11ba +9870,c5e9cf38a21dd71e +9871,960f1003096a1896 +9872,a0ddb84012deabf6 +9873,42e11bf83a2f359a +9874,5cf2ed29cf57c63c +9875,1aa3f43b48df7c8b +9876,0836713e1decfb46 +9877,f86328cdc6272d9a +9878,8a3c684f312c3c51 +9879,60cd017779502fb9 +9880,e99a74a4510d3363 +9881,2607c1a900ecb8f9 +9882,b38eb8181882559d +9883,61acebf20b872fd3 +9884,8f15d6c43e3af61d +9885,6ae8570f7c048473 +9886,b1ac312876a930d3 +9887,272457ed5939bd92 +9888,0c626d977ea59750 +9889,700351ea4b23bc04 +9890,520062046675271f +9891,fd0f7b95195c7a70 +9892,20e326e59674fa71 +9893,386f3f1192a4422e +9894,07f8a4c933946d9f +9895,a1ad8172ddc23444 +9896,2160c099438ed5d8 +9897,a45b88d5e0dd934e +9898,1c3c5e33076d7b42 +9899,002067253f2b52a8 +9900,f1de011c5cb164f4 +9901,c5743673a676204f +9902,734ce9486fa6fd83 +9903,2d40e3ae7abb976a +9904,1150237f96fdbc8f +9905,fc036fcebd633a63 +9906,738c162c2275af9d +9907,0b86e842efb02338 +9908,77b2f325eb292ae1 +9909,214838f6f7fd018c +9910,de4428b41d2bfd2b +9911,13cf4b62263d1eff +9912,8b032e5889926e87 +9913,5d8d3e4142cb3d87 +9914,d984c9b02b903982 +9915,7e0075a5ab3de891 +9916,b556fc00a950a721 +9917,60624274d82dc456 +9918,f3fe880a4b61b0d5 +9919,9c1695b597a4e9b4 +9920,7da306d7f399eed9 +9921,d539b301f5f64d26 +9922,e93f8e44a4ee0f3b +9923,cf2aaa1691afd45c +9924,eaa215d58b8864b1 +9925,b6d564196f5e11d9 +9926,ac3931990c9bb907 +9927,9bfadead6385d017 +9928,8447904e76500fe6 +9929,5d97637c970f2fd7 +9930,2302259a3fd83f41 +9931,03e476c388d6a933 +9932,3dd78b577d4d62f7 +9933,579e02f4cd5cede7 +9934,2d13892c2e5d7527 +9935,a986457025c2ff99 +9936,38532dfd3c3fceca +9937,2f7698fa7cce68cf +9938,30bf8819c0a87322 +9939,cb7358feec46d737 +9940,0390b92bb1905300 +9941,9fa5d1ce63e7905b +9942,ef0e6e7f5d21ce33 +9943,02aff78ec5493707 +9944,30e23774cd8626ee +9945,5f3b30bae47461a9 +9946,fad278dabf3eee18 +9947,f74384631aeb9558 +9948,3e007320aaf22239 +9949,63c8e782756f4478 +9950,ebf3057d39110f2a +9951,978ff84e3417e18b +9952,f65d086fe3c8025d +9953,76bc5595b8e26283 +9954,6d22af96447c5a0d +9955,959b1d53b1a5149a +9956,f9de6760b430a961 +9957,ca32259a8a426dbd +9958,1e8d895611ea0783 +9959,d42f8b8cf1ed5cf5 +9960,cff945e52393f393 +9961,1fce2b06d203a909 +9962,b0c5ee2247747511 +9963,bb5d11d79ef36b17 +9964,bcfa4162bb032ac6 +9965,1c353f2a1ccea9c3 +9966,6405e5a58fddb952 +9967,1c9815ff42ebb533 +9968,b8190d8ae2b9bbff +9969,bb26475e97506d10 +9970,314f919ff7c5b727 +9971,7289322ead732744 +9972,d1baeba48204ce1d +9973,e0424e887fb879a1 +9974,48287c741600d078 +9975,2f81c447bab1efc9 +9976,ccdccc00f9a07dfe +9977,659c01156047d276 +9978,c4bfed26022c8f3b +9979,5e421e795ee42e6d +9980,c044d18bdb31b932 +9981,1636f8ad25b649c4 +9982,903500123b659543 +9983,243cc49e7cde271e +9984,ffc3ad6ebb175f81 +9985,6cd92a32804685b9 +9986,a0e28bc69085fc31 +9987,84937a2b018d82e7 +9988,3d850c14b3a31161 +9989,4be24600b500b606 +9990,a06af1073aa7eb14 +9991,4363dbda56ed5298 +9992,acca547d90989f0e +9993,08b5273ca7fa5c05 +9994,ae4a69c7a5a9041c +9995,223c44c0c6319e53 +9996,f48ec2e4d3cb8f48 +9997,d3e1645482c945af +9998,6ee00eb6a6790ee0 +9999,07dec66810def4cc +10000,77c59f09385c77ba +10001,a9a20159fd68c636 +10002,7936f84ff703f316 +10003,852e60a07a927633 +10004,924d9d27697b3070 +10005,67a5cdfdd0f309ae +10006,03a9152c2cc29416 +10007,8f26123044e60afe +10008,2965bc15e61c1aae +10009,8032ff423e9580e3 +10010,cafe75f79cd526d6 +10011,782201e9ed992ff6 +10012,3062b09657e10d51 +10013,97e80dc0f6801481 +10014,358c7577c23d10bd +10015,8a523fdf42d657cd +10016,594bf6cdba5216ac +10017,a93ca4e3e92c7735 +10018,1725384fbfd10aae +10019,8783ed68db02f4cd +10020,40d94d1401c372a0 +10021,b98d2f09bfe55284 +10022,8c577e99158889f7 +10023,a1d260c56894a1fa +10024,fe097f876514dbd2 +10025,eb2aa367c08e61ba +10026,30f7653b9e67f418 +10027,829f80ac1cee158b +10028,7b10e74f174a4bdd +10029,f331ef17bfc72966 +10030,eeed8272ec8c7d4e +10031,cd68e693396856c3 +10032,b6b0eca2fb332260 +10033,77d09813c471e44b +10034,60921b4c2849debd +10035,9ebabb31388a7792 +10036,fdb2c0266405f9dc +10037,e56f9751b547a418 +10038,0db1257c2e8f729e +10039,38a706d33097a3ea +10040,1d4e9665a097ec4a +10041,737909a64197fb46 +10042,7e49b50bad9b46ec +10043,1917d7a16bf45245 +10044,95bd4aa9a65a3709 +10045,83c57fb85d4f53a7 +10046,ff922609583d1774 +10047,140d70d2aa1ddc39 +10048,85aeaecd79a195fc +10049,bb680c1b4ebafc41 +10050,493edf6df134a5e4 +10051,b0d561e435aeab35 +10052,b6b262156162baec +10053,b74cdf3516da6192 +10054,1c905048fb961d02 +10055,3cacd6c58a67b8b2 +10056,e12d4fae81b8324e +10057,de8fe7082920dff9 +10058,3af32642b1788378 +10059,2320e2ffe3621ae0 +10060,362ce2681b0e0cc3 +10061,0cc3df3c6c92252a +10062,d7ff1166ad4d93de +10063,fef74d0966bd2d59 +10064,2f6144901c3fc3fc +10065,00f4c653511f746d +10066,a814135893e57903 +10067,af46df5f1bfca71b +10068,6d46f446b9995f35 +10069,f9bb0fb994d0a284 +10070,591153ff10b3ba95 +10071,9e010cfab8099470 +10072,a77752c4fcb463cd +10073,0db28d21b647546c +10074,831405af928dcf29 +10075,564389cc5dd8b8b0 +10076,b11f56e75b6478c1 +10077,ef6dec89c3f1909c +10078,52e22ed6bde67303 +10079,71d999a56e486233 +10080,08069df4931517da +10081,f0f1f45d6bca3f6e +10082,9e0ffe242865d0c8 +10083,61b2f7ed5369ee6f +10084,f24eea17fd2c589d +10085,64b75615eb56c4e4 +10086,4aaa1787f93a5a0f +10087,5100b0c2b62a3822 +10088,599d12b7b1d4b18f +10089,9d59569ecd390a0c +10090,eec058b85452f766 +10091,c1b390f23d635f2c +10092,96ba7166d1ca55da +10093,853b0545a6de8e35 +10094,9dc4fdd15c958bd7 +10095,7ba06fcd66261aff +10096,e2948cce1a051aab +10097,c503b7e71e3e5fe6 +10098,430314836b8c48f5 +10099,04e78588e71e00f7 +10100,3e0d3463d4c53b12 +10101,834014c0c85557bf +10102,1f7dcb93e77d7568 +10103,c0f3f604ea8a91ae +10104,0bb7be947f8efba3 +10105,d46afa7edb17c007 +10106,4304392959aaac2e +10107,dde9c8bcdce07f89 +10108,aa92c781626c44d1 +10109,86c06c2ecfae273e +10110,f4b6b3cffab62391 +10111,f6fb2a894486526d +10112,6827e518644cc4b3 +10113,27001200dba953f5 +10114,cbbe38f40ce74082 +10115,098b420f75a88a61 +10116,7edde2f33eb9ac1a +10117,4f28a7148e428a60 +10118,3d574366eb051766 +10119,807fb557b0ae3aab +10120,f1c5b2d736b834d9 +10121,64d196cf71c1c484 +10122,d8a01fac383f4784 +10123,6cd6b401ade97915 +10124,ce4ae11e174d066b +10125,644cda7c7b3c5c24 +10126,6d5b04e812733eb6 +10127,7d8aacebc60cfcb1 +10128,e4727c7056251a78 +10129,5a00e14b59821fc9 +10130,dca783e08cc9e72f +10131,29e67baad7a8833b +10132,8d0ddf52940bd7eb +10133,eb7a0049c47c5cf8 +10134,f63fd85428f84fe5 +10135,fa3863a4d2960785 +10136,8e0cbf3469c8c8ad +10137,eabc72cf23b40bbc +10138,8227ed363a594fe2 +10139,920d3393cd19c1f8 +10140,08516edc4e535649 +10141,566c4cb538fe2df4 +10142,3f5594bf13f702a7 +10143,d945bad1118aca40 +10144,26f65961e060ba24 +10145,d694ba5e71ea60c7 +10146,0a642ca96bf7a434 +10147,3a9877b3f7194aa0 +10148,bf5fe6afb10d6a55 +10149,2e35876f108ad0df +10150,94222afef6e8477d +10151,294be3e461ac66da +10152,168eb9c616f95c5c +10153,abb61e3e1de6201f +10154,c5dc07609293a8dd +10155,6e9169dc671a5f6f +10156,aa51484a17b0f797 +10157,dcbaa4333dd2c56c +10158,9aaf3717bb9507c1 +10159,e47c0eb46ebc603e +10160,67dab81f9150e350 +10161,9dc59b5b7bfcd3bf +10162,557363c77f0dc34c +10163,af44df9a4b31497d +10164,0852c813a9a60861 +10165,d6123a9d31a9e28d +10166,d21452fe1d37ee92 +10167,ed1e1e5c4e0934c8 +10168,46386d3727230b32 +10169,1ec8bc58d541a598 +10170,4bcbe4405440b9dc +10171,cdf0fa9d9cf0e350 +10172,ac6e5b8afaf49e98 +10173,cccaed50ac4bf402 +10174,7c60120e3bc5f0df +10175,8104384316de63ca +10176,7cb6135de6fbcd43 +10177,184539ea7995f953 +10178,5bec485153dd4d0e +10179,57f4c48e78231e00 +10180,15d9afd72307c66c +10181,9b583b449d52a7de +10182,7ff009c425646204 +10183,721e5ce78e1b85ce +10184,526c916bb80c4ea1 +10185,6c608eb4e10f698c +10186,bb70e73018bc019b +10187,c8f481e5fc2db145 +10188,32721b87746c5350 +10189,c9a40d3ecc5f6bca +10190,1a209543446bb924 +10191,607ed9b6858ad7c6 +10192,653d275c4fd2c09d +10193,28ccd5e6d6f4c479 +10194,45c889fd9d6540fe +10195,fbcf1af0b53378d6 +10196,e6cfbac746509101 +10197,f209cfc38af5ca01 +10198,f118d9bbddb5bb09 +10199,b466548b81a5e2e5 +10200,2e1befd6088eec16 +10201,3715114de774752d +10202,6f0c6747b8979a3b +10203,5dfc6a804c489065 +10204,f0166a0fed3a3c3a +10205,b9f9fd793387b134 +10206,f08879b9abde758a +10207,cecdc10412c34604 +10208,e5876ca699261bc0 +10209,4a0419e33e08feca +10210,bb0f164fbfc68eaa +10211,5b164e4de0ddb86a +10212,5b858ee55c3f41cb +10213,327eee9e78e1c5a1 +10214,979bd5185d2b5a3f +10215,bc3059d52ca8c520 +10216,a22a490a2bfa2c3d +10217,609d724b0d55aeab +10218,4d2a7dbb8d7365ac +10219,2940026ade832be6 +10220,99e3fa7ba3b90f55 +10221,ff30c814f6bd784d +10222,428c614ac39e2f9e +10223,416a520542b50411 +10224,980200710e929169 +10225,fdfe24645a0b751a +10226,5fb04207dbf94802 +10227,0a86368583d078f6 +10228,bfdbd5a11c5e5e0d +10229,e425967e330cc790 +10230,ddd469aa8dc73b3e +10231,1ae19891242ee0cc +10232,ea47e41b4b49142d +10233,d85bafe6819a0e64 +10234,430e297691e6d7f6 +10235,889e338f28dcaaa0 +10236,d3801ec33eec9367 +10237,a26b9b6483012af6 +10238,97b705853c869852 +10239,3be29ef7c5dddef9 diff --git a/hashlib/test/fixures/xxh64.csv b/hashlib/test/fixures/xxh64.csv new file mode 100644 index 0000000..73fcafd --- /dev/null +++ b/hashlib/test/fixures/xxh64.csv @@ -0,0 +1,10240 @@ +0,ef46db3751d8e999 +1,928a358b25c275ad +2,26e83dc718588b17 +3,0c771dbbd5145121 +4,103460bb4a599cab +5,eaacab0428e1ad18 +6,66d1d7acae1c8af8 +7,42a95dc071e0e028 +8,430fc95c201839aa +9,d27386e042b7ac84 +10,800ebdde07280aaf +11,b8ff62fbe94ca143 +12,2a2dd28398456bdd +13,5729b68a733fd5e4 +14,4a6b2de5c1db7a2a +15,7719b4b1a55dd577 +16,cb2c6554aa9f44e4 +17,65bbbf822a1eb5f1 +18,6f4f91f80704368f +19,36c69061760d141e +20,e037cd6b61852ae6 +21,b54164f4075fb6d2 +22,05677bc225a35367 +23,98f132aaa3341334 +24,8f1fc2d8bcd7f4de +25,279a7d5e4e4b61ba +26,b0c069f2e1b6ac57 +27,e122dac943f6f90c +28,6bea3a21e79a478c +29,ad12c6a0584fc65b +30,497b2af41c98777e +31,6658cf35e1e7aca3 +32,40576ef99382d145 +33,2ef68659cda2f865 +34,518d02afe799b1c3 +35,31523a60eb1c2268 +36,6528a2780a481f30 +37,d86c34573fa0a770 +38,d7a11deeccc1b993 +39,4b66a24a7a22fc4e +40,d72d6861fff17c3d +41,08a7fbcfcb059ce4 +42,eb6e43be7cc42ebe +43,3ea7486ed93101e3 +44,28e5ff0199b4790e +45,cd8cbd8040c4f4d8 +46,bb6fe76eb20b233d +47,74f691c6e2962868 +48,e947f01fea21a375 +49,e78f8521af46e626 +50,5c126bd3ff818363 +51,5a81e34ea311fbfb +52,2e81b61abab3b472 +53,9c638a73d92d061b +54,649fd6df014b9c86 +55,fa732e3c8263f77b +56,be3bc1cbf8b537ab +57,787cc6f65a042966 +58,46bec461e3e686b3 +59,d8022ad4226be087 +60,4db99050868fb7d0 +61,ee5ac8c321c21510 +62,eab92df62e5e9a3a +63,7104fe47d5873922 +64,f73dd16820dae557 +65,4e7615640254796f +66,8187bc41e4ef681b +67,f98364b0f844653f +68,39c23fffc7978c62 +69,83dc3f0ed2903200 +70,cef79fa63e1b3abe +71,a993730c93122c9a +72,701f7b2daab32b48 +73,84ea4fa08a48c23d +74,2e9110b111b9d95f +75,f73e713f5ddf47b2 +76,f6573842b63a7eba +77,02dd0afd12947b35 +78,9e01baf4c2ecdb21 +79,c394caff2916c230 +80,257f3b2ec5a25fc5 +81,8dc27a24a440db6e +82,29fa8454694e6f86 +83,f1b1cc67d546bf0a +84,0bc278878552e23e +85,8da8b1455ec673fa +86,cc146befc333c50e +87,c41dd18e79fa4c0e +88,86e1072412fb445c +89,5fadc2ea4bf93ea8 +90,5d49c951411c8d80 +91,1ce7a67bec2bd292 +92,e1ff187b13e296b6 +93,50bb94a7a957a6c0 +94,497d0e2ba5f85ee9 +95,977ee3c20a042883 +96,c06f66c6c90408cf +97,5b2eb9f3889a424c +98,87304b7dca4dd098 +99,63873a6b0987f5f6 +100,b056d3562afa52c9 +101,8f8f8beedb6abe90 +102,808c155f0229f0bb +103,748ec1871d0dff14 +104,57c8cf0554efcd7c +105,b2c77962b8c6181f +106,6e7ae14dd04c90e6 +107,f1ec572b017167e9 +108,3e26e622d8c79bf3 +109,da9a491e582a04b8 +110,452c553c2a4c4d4c +111,e3014a118bf31eff +112,19e3cbdc4dd407b4 +113,9aefa13d15a22a5b +114,bd981de06b12b05b +115,5e48199cd22e8fc8 +116,a5673139bb2f29b7 +117,2a3a8321e6817c8b +118,d53007f03813884e +119,f00142f97c43e30e +120,aff48ab699435dca +121,1849a705a680a485 +122,acab75e3fa56ba4e +123,c097d2d2f06f31f3 +124,18530ad02a4ddeeb +125,31dcf1d598041bfa +126,6222179e86ce5fe9 +127,d742fe38018b6746 +128,cce57945b0ecbf63 +129,99896e4e25b42658 +130,43d18686b3fd778c +131,f7d80f8b4dcd4ef0 +132,f27a1a0758fcde46 +133,f5a81030e42785e5 +134,ea4d5f2fc0331df8 +135,afc330f400039127 +136,2aa6652f1b70d4c2 +137,9ce89623c3c7a87f +138,1a68f9e85a5cd929 +139,e9f91c8e1a16d59b +140,86e48ca7f5d0fd1c +141,822128ee1f45605a +142,86a5b7f183c7a677 +143,2a8bf0968f02cef8 +144,3b7496e1ec976c0e +145,5025c766e9bf9193 +146,114d36068807d087 +147,5a8facb7a83d6de4 +148,ab02018e6c0aa60d +149,80648c90b02dc0e2 +150,161a13a26a229887 +151,5efce62399d1b168 +152,a26d9bb2e6f491e4 +153,9ef5c1dcd9e9dbbd +154,3375467fea8b4948 +155,ff562e4a17a89b6a +156,b8295814a96a73e2 +157,4952504c03950369 +158,1429441dfda74e56 +159,a7b2e09780126428 +160,d8ad309371b2a978 +161,5af16853516f4e3d +162,08419d5404101272 +163,ffa33c37e17b0111 +164,75a99b1242f2d9d7 +165,dbe629368dd701a8 +166,2ae7637d4a75e459 +167,bce94a622c89809f +168,3b07413b68c0890d +169,9474076bbf2fca59 +170,69f1060f79f54d51 +171,6d9f36b9b3530ccc +172,3266c2ea1ace0cee +173,ba3da59d8feb2207 +174,b493645c97b5ff9f +175,e053b49b49cf7410 +176,8bca807a31ec2b71 +177,5c7ae437035e75a9 +178,7d22502faad7dbd0 +179,2f1c7f1a8229a15b +180,66fb8f91ad19b1dd +181,a7f3be298a78c4e9 +182,abe805d3e5a28cbc +183,cfca55a75c33f9bb +184,ba01e5c07c3ef090 +185,2ff7834b3eb3f65f +186,25cf0c6a2f660ba3 +187,44e5e7c1da0a195b +188,1c4437c0d13871c2 +189,a55c12a1a36b4e6c +190,71138ac5cb193d14 +191,76a092970a8397a2 +192,bd001fcc02cfb1c8 +193,a60ff3132f015a61 +194,e4b9911ad296bc4b +195,b3e70b53c97490f4 +196,53c886b2612f43a6 +197,d1b4f647dbedd353 +198,10d67c9e4ce2de53 +199,e1712b6c28a6a58d +200,b7aa1e3df6ddb308 +201,19d0edd9ab7c0725 +202,59c89195fdc8d8d4 +203,583dfd4a6c5fa66e +204,ba9d86f544e5d538 +205,38dadfb07d52d688 +206,9e98f527e9542c6f +207,f67d5ec13841809b +208,e6773aa51f54ab84 +209,748932404e6a4c2a +210,71c3d7988af6832c +211,de5bf0c7d4a94dda +212,383cd05021bedb82 +213,bab7483b9522d8f4 +214,66e32f77924a6a0f +215,907752a380485497 +216,9896a6b800145868 +217,3a11bcd569c695fa +218,fc2f23a92811ed50 +219,867d9033f8a0cfc3 +220,5a945aba3f712019 +221,646ced632e0c4560 +222,f52b78dc5eaec930 +223,2d95036b2b80d8e7 +224,228b0b7d33aeba2e +225,2dcf423a1c90e5ed +226,98604fc0f9a5bcb2 +227,4fd4cf6e8e3ae97c +228,29583a00a8f29396 +229,460eff94998f5643 +230,ab6422870146d383 +231,16b2f7f27b7f552c +232,b5100a3cb353a651 +233,c5ff79e4f32be092 +234,65175f4f2770adc3 +235,899edd97e1ab38d6 +236,65ebd8907bf39490 +237,8a08c07ff66c5f4a +238,059c940688347d20 +239,bb532ff3fc56a43e +240,10599315bada5b9b +241,4aa358f682d808f3 +242,99c752a0d2d1dad8 +243,60a0c8252aaaa8cd +244,2a110201aaf11cf6 +245,a6b5f7a7755cb459 +246,71f39a3afe4c705d +247,aeddfd120ef4428e +248,a72602f4b077faaf +249,102a5233a09523f2 +250,4229372dd2c1005c +251,363d1dda84482432 +252,52ade9574680a8b9 +253,e1034c678e628f09 +254,98dbfde76fe1784f +255,53a76382b9e584e1 +256,9e2d159d990d167a +257,86511bbdf3928b3a +258,742c57d0ce2153b4 +259,fea840ebd85166cc +260,55ed842c5f48db52 +261,9467d9862ef86835 +262,d0c0c5c7b54ae1db +263,46a2b566a6b6e695 +264,0b671d20a68a6861 +265,05ab82c22fbe1e6b +266,eb5d61db2cba2f0f +267,9c88a6851f17d51a +268,89685f478ca443ad +269,424e7b8728fad93d +270,3c5eddff65e8da47 +271,65e5fcb034ad055d +272,3f5928e838dbad16 +273,64ee877fe9d362e8 +274,11f3e57397d1e385 +275,c25daadbb5ef81eb +276,ab1f93a9f9917260 +277,fcf44ea2d83c29cb +278,031744e1a88480c8 +279,d3a08e6ea4affc29 +280,d2ba4cf4c0db6666 +281,8692c9da32ac2024 +282,5edbabe3696d3a48 +283,c22295187734c86c +284,e15e34c62538f2af +285,4c2565064b1ba1f8 +286,7a14f4f5e8869087 +287,40aa079af078eb98 +288,33a84584fca0c470 +289,b17892853d9f27e9 +290,8d000a69b9c60a93 +291,eab9d9bde6ce8f25 +292,e1af7c6713bfee2b +293,9928c0b375f2b895 +294,370cb5a232b64979 +295,f20d6abac898ccc9 +296,eb56b1d4dfe60e10 +297,d2deb1370275de0e +298,38b3b35e81ed9226 +299,8278c6f78c6ea8e1 +300,0aff60c3bb98f32f +301,aa2da71cb6e0bf91 +302,7d9ac13930be5623 +303,823d0aab7be799a2 +304,9c3dc71b3e0242e9 +305,b363c2dee1ce72df +306,4c6c019dd2a357ab +307,4782f125e6c5ba5e +308,121a22d9cb96f5de +309,1e58beebdbe8d0b1 +310,4309fe9d569d4e5a +311,380c72cc30318317 +312,a11291cde4f6a5d2 +313,fda1b57935521e41 +314,15755312ea2d5aaf +315,24e96078b1e1bd0f +316,6c56ca436175b4b8 +317,adbb82cf98e5d1e2 +318,61efa1f590be74e7 +319,348791bebaa6e2fa +320,730bda7594397c61 +321,20435efe2207f1eb +322,5485ebed1b1546a5 +323,f0837fb1f966c20e +324,e64b7e1bca04d7de +325,977a9740a81d6824 +326,83c5d0189449127a +327,90b2a5ce5734b2a9 +328,3ae1d1d673caa4eb +329,6e64020f6a8e8568 +330,0c36494fbf75d839 +331,b6d20d916eb178bd +332,a8ba2048de2c185a +333,101bf35b2ab51d9c +334,5b1ab40062ef8f9a +335,d3c97dc8093d5acc +336,e705299d0e760874 +337,c688fa410a6c2a78 +338,63a6c6069392234b +339,8c7ca4762d7e6f6b +340,d63bad8f14fb7cad +341,123a285962b9bfaa +342,72e7e0d1e9c25e28 +343,c38f226b34a2c56b +344,0f0bfc32c49f5e35 +345,3150f4460f198aa8 +346,4af7075acf27f79f +347,3deb30efe5287940 +348,4be03be03fbf4ac1 +349,329a5b3d345779e9 +350,916c7b0e226b9030 +351,c9b6fc2bc9ab818c +352,b7827afda02d84b9 +353,2507fc16bb3fa073 +354,833d3abe4688d027 +355,6c4d487f317d9209 +356,b17ddd6e927d0329 +357,5fd79026a5e40915 +358,d6446d138efb4659 +359,4edf0ef2050e5164 +360,5b62e7bf7ab6a21e +361,5694ed243fe699bf +362,64a1d0b285708183 +363,c0f5179dbd5b3665 +364,1d966b27da0a3434 +365,aa05f005bf9ec945 +366,e12b65cbe9ea6136 +367,dc125be89252fe7f +368,2710033a49dec83b +369,af60334667f945f6 +370,f5839dcb7affff68 +371,d5e79e4ca2be7f77 +372,8574a9cda518a29b +373,acf190748a41474d +374,17cb45200b3210a4 +375,6cb9e51062fe5bbe +376,ec6b9803f1b55820 +377,24496642597f1a33 +378,370e83d00fbac7bf +379,6b5e40588811f420 +380,7ecd1b1c9f2e75b0 +381,648dc2c1bd4bb217 +382,6aed3e1a312a4861 +383,92e88bf4fc264930 +384,52e1ec6084535519 +385,e623a0664fba644d +386,9230385813390879 +387,c43ce76ef54e9607 +388,71d3f53ae27ea4ac +389,1dcfbafc12d5e096 +390,c1a1ba0c5bbd9df6 +391,0ee5393d056915f1 +392,65916b07f73dc9f5 +393,8aa36e628762716c +394,6f97cf76c3ad4f6f +395,d138864cfc7b2958 +396,eaa668f7d4392b07 +397,879763a223fdccd3 +398,9a8b3144f38ef190 +399,3d82093688277cfc +400,034359fc845e11b4 +401,ff7a2a784d71bb23 +402,55c4e69a98969eac +403,f3761ded3438cc5b +404,dd71cf9a52cbd1bd +405,637ace324f107acb +406,60ba3875c81dcf72 +407,00e7343e9f1ef06c +408,03ec67810470af86 +409,1ba53fbf001042c8 +410,451ba23d58016ad8 +411,fe261a3aac15ee2c +412,7170af823eaf3566 +413,f63d76a710d31268 +414,cf78e7cd339deffb +415,28a41193f4dd3b59 +416,902dfc2622d65e09 +417,4001a203695a03e7 +418,41751f5394e99256 +419,1c466b006ae62d7f +420,c637eb9776e8c7ce +421,eeb0dad5af94fa78 +422,749e282e0261d9ba +423,5fdbec79ae640986 +424,ac4d879774e90e07 +425,e1302ac991547c04 +426,e8d506aa00ae6e51 +427,dd7ac441bc346535 +428,64ed54940679de5d +429,e6d6bbbde13bac38 +430,454432fdbdd24027 +431,e39d916bcc6b5126 +432,3a100c2737c18a11 +433,e7b281aa0a1ec7a5 +434,7c2b84489ead9eba +435,6f530f4b7f5455fe +436,64be8c66e72c03e3 +437,a678e82e1a3a134c +438,ba2c0186f3d1245b +439,573d66f2b5efedc0 +440,5b4ba654301e76f1 +441,cab7bf1ccaa55382 +442,e1fae910c88be495 +443,37ca8f188ed5d11b +444,e19fdb0e966de013 +445,b9246c8f6e9fc97d +446,084d099fd90a65f3 +447,57066d80ea5ac05c +448,2d6c00bbef2e6957 +449,146083421c90d084 +450,5ffef70738443151 +451,0793cdcaa7570cb6 +452,c0c0dacb9f60bd28 +453,4c2eee39eaae9a47 +454,691f00fb4b2dca8a +455,9526ef4e620c2fd5 +456,9e8fa6dfeda479e2 +457,71b667e12bbd1dbb +458,2fa953769febd45b +459,b148459954d1bd3c +460,32ba4c65c275503b +461,8fb77e6ce54fab72 +462,fe45396c81b4a9f7 +463,24b445e3e723166f +464,5010e523a9e58673 +465,0719ead04a044b9f +466,fd381bccb983719a +467,24b09a881009fe67 +468,2b612f52773bf707 +469,6b34d5a77d059655 +470,63ea014073306b84 +471,e4a504f18a86b5c9 +472,0807911ea7a04da1 +473,6411672548dda219 +474,def6421e39d9966c +475,3a337f9ffad328ea +476,ce6a25203227fb1a +477,f9f7053dd35786df +478,a6aa28e8754f518a +479,046842fd812ec7c1 +480,4885000f3583f1c9 +481,b6a8ce95fd65c4fe +482,a5b6866465a55bc7 +483,71c920daa1ab7d88 +484,87226961dddd09a0 +485,50c437882c322603 +486,e7fbf8b0c67493d8 +487,a9385abcbbe5d0a0 +488,096ac2c90789ddd1 +489,a910da4e48f0f403 +490,da7bb24ef29bf9c4 +491,2f5cbe17dd5f4b98 +492,e5ee294fb55c2be3 +493,e52c9505c132b6df +494,d6daf430e4d67ef5 +495,efe2ce91a96ea468 +496,0e58d0c8edbb4698 +497,62015efb292c66ca +498,6dc2769ec2715b80 +499,e961918cec58f1c1 +500,1a7ed2c8a64b79a0 +501,845dc95c0747b206 +502,b429a3bbd11a7904 +503,8f1e81e5cfd60dff +504,cc90cbb7b3bf730b +505,a7f0923c7a9310a3 +506,852db5f9fa6aba91 +507,f30dbd31b15235a9 +508,fd955bd889fe3b3d +509,75d47440eef35613 +510,96dc2d0fba317b29 +511,40adb0fa34b1a5d4 +512,b13bcb85d7c9951c +513,ca639c12d802d852 +514,a2832b92c23d40fc +515,79943457edf705e0 +516,efbe159ba3e62c5f +517,633d01a4b52725c5 +518,c3f07fa4f57404ce +519,3e297130cb3c13db +520,4260c2b227577fb3 +521,7ae976c0637eebcb +522,52ff92c308a394e2 +523,fadedc6356e9e7aa +524,99b828f1392987fe +525,d4c1ec0335fbd9f8 +526,9b3fccd3a2c60f60 +527,4654b81c2b8f59e8 +528,9339bd71f5e3cb06 +529,4c30d48d9433be4b +530,608eb75e40f245c3 +531,254692882f492235 +532,c533715f4f2e71d7 +533,11f11539e8bc6855 +534,6db2a122d4ca04e2 +535,9aa3fe41835616f2 +536,36f90f09d501cb30 +537,1c572c783ab6a1b7 +538,2341daa149f9c83a +539,860bb958542fb38c +540,d833293da27a129e +541,176bc96008581f37 +542,79f6260af45cfa9a +543,a1478a930b9ea09b +544,375acb09a67f5f88 +545,112ea3036cbea62a +546,ae9cecd071d81512 +547,219c3122e94e61db +548,fa3b523c5ae20de5 +549,0df17e81240bdc0c +550,d83512010c876d56 +551,e88b92cf1af49d2a +552,0ba671250076594f +553,cb6ee6d9ba2b357f +554,40bc53994a8cdb47 +555,3e4188adad8961ae +556,2533301a6093121e +557,46d14fc419425442 +558,1c8384050c9abc9a +559,1168cb0ef818dadf +560,95320d9b9d8fccbe +561,bd5adac121e0d2c4 +562,d9fa7bd8402937d6 +563,a88b9a246f6ff244 +564,0ab8d280281b8598 +565,3748210668e0fe6f +566,24a71081d0ca215b +567,0385702acaa25717 +568,2005c642d72b8d8b +569,f0edcda2203a79ba +570,5e8c0946c2269279 +571,05c24f2d375cb57c +572,25ff3f2bb8c39187 +573,ed191dc1216cf9ae +574,dd974b98d5922fcc +575,0446bb501cbb3369 +576,719181c98ed9b76a +577,b49992b3c61bf177 +578,1acbf5bbdb163edf +579,d9ae94fd5e554fff +580,dc00f413c703d4b2 +581,13422c7b30608189 +582,55438ea3324720ad +583,20744004ee5d0120 +584,e9112a98172e5e1f +585,d58efc8c6f8d3221 +586,0945a8ba770a8837 +587,d2ef53114ce672e7 +588,7fcd0160cf16937c +589,5eef307958da2e1c +590,68781d7f98f25fd6 +591,6b8f5b49521df7ba +592,9909280096e11956 +593,7d48bbc390461fa0 +594,0fc37e3e112d7c3a +595,27d6c627366e301d +596,3e6f1d04a9db2629 +597,0a95786c1469acfb +598,71a330339465a9e5 +599,558bbaed9cc2fb1a +600,0c790118d36042c7 +601,4bb78f47eacd412c +602,7426f7f5a2948bee +603,7f90e69b50f76b90 +604,3860a627dee2763a +605,eb716b5b325e7aa0 +606,7aa07bb35986ae58 +607,b607746de63e6fb0 +608,7a0150014de3fb4f +609,503c04a70a30d884 +610,83f989db591bad01 +611,8e58493e2c519243 +612,6944baeea95064b4 +613,a0fd2f6811b8a086 +614,ff845642b3b4cf53 +615,7667cebc77e06810 +616,a43f28f5f58c87cc +617,17b1a69b62a5b7f3 +618,a90fce0a26b31ada +619,9d396a9b6b25650e +620,d387a0b31b65e2e5 +621,a7a105db0faecea5 +622,47245da5081298d1 +623,009b3e8d8be8476f +624,8dc93fe7de75bae1 +625,cf1d07541f54e3e8 +626,eb61fea47bff2eb4 +627,d6a88eb597f38e97 +628,e7fc1cccdaa00045 +629,570d20914c3fdb74 +630,97c6d7ad5da4d509 +631,f6fe98625b6daaae +632,46d4a1eccda25732 +633,04e9d21448c54785 +634,5ca34214c011141e +635,a5ff7cb9e6921e57 +636,d6b0bb07b6bc3bb1 +637,b499f653c04799f0 +638,66599c3d965c34e3 +639,503ebf1818d4e54c +640,d1fcedf05fe2a6fb +641,2f360b89e6381aa6 +642,a3c270f40f7f2671 +643,ab70e47e5741af4b +644,4e594b53614c7c85 +645,227d9f7cb6f52805 +646,09ff7993d7ba8137 +647,1558ffeb162b1fe9 +648,fea7bd9abbe5f1e5 +649,e5eccfd11a367781 +650,b0260628e25b7114 +651,cdd0bedf944bb6e5 +652,4fab2092710be0de +653,f6b4f4622c0c79d4 +654,53fa3f1ad537b901 +655,436959aae66d3973 +656,04c31732232568a8 +657,0629a6013648fd44 +658,0dfa01ced60b6711 +659,3b17e918122b2fb4 +660,6715eebf31b2a7a5 +661,ae89a9db0536cccc +662,6aca7c9619d982f9 +663,20391f3bf6fb7f36 +664,a63305e911fe3dc1 +665,d0d59d6d551083b6 +666,7cbd4a0853f26d72 +667,3266435bbf105d24 +668,d411e8fda78677ba +669,b0f3af250f45173a +670,f287792c638516f8 +671,7965726396f5eeec +672,800eeacd77a8882c +673,996c74bf36e6aad3 +674,c154d5da9ff0c015 +675,658cca15fdfa7988 +676,faaedf520724161c +677,d3192e6fd99378e9 +678,d0daa82071e574b0 +679,7365ee72fdbb34c9 +680,118fbddfa1403226 +681,8b1cf5e1ea809d68 +682,641e2f8c73d2a075 +683,2295c0d87b24ec84 +684,cc2e6f1e806b2b55 +685,f1b888af721a6479 +686,6b574fb016e99f27 +687,4bf2c01530c51977 +688,cdc511a276fd116f +689,d9097602d93aff1c +690,7a712b8dea36e3a9 +691,4d0ac3dbbf703633 +692,04fae3e86b39e360 +693,f4a4f1e592de32e8 +694,e39dd98949bb4403 +695,be172aa8b6841204 +696,e8db761779a63fbf +697,2e1bd9c6deb6dc6c +698,d9140daec6dace78 +699,1251c20da9452b9b +700,b241e07b097c7ff9 +701,905ed04835511814 +702,f96aa93b0c33c464 +703,71a37682157fedcd +704,38505053683f6a7e +705,5bdda1e157444a9e +706,d8d513f3b8bb2770 +707,a5d1c964aacb854e +708,2511a84d09ab5c11 +709,93fe9f829328b500 +710,d5739d00d9d5ac1b +711,213ecf43f39125c5 +712,8fc4e1912de9a73a +713,af73664f9a8c71c6 +714,1c4f7fb1f49be15b +715,85ad183c22df3694 +716,29ce50b1129b2a0b +717,f7e330cf07709dbe +718,4320495f20ffadca +719,2dc4d3940dc6edc2 +720,2313d0a4254f2db3 +721,b2bea179bca28baa +722,906ef8d61fe98a54 +723,2242a8d345510507 +724,1b455be6b3534c9f +725,913f45eee908ec08 +726,08fbe6503965a42f +727,e868eab27eb2ec83 +728,e61a4ca8ed914f5a +729,8183ae5a3c3161df +730,5488245670a3011c +731,00c5af02ce8d2b99 +732,b59d8145fa64a4a6 +733,5e8980746f5eed5d +734,6a6c24096785e997 +735,16e29000f0290711 +736,36e7f660eaaa2130 +737,3b280da89e612f60 +738,6a0827053c1745c9 +739,7f6ad64d670cf3d2 +740,5612f604694ca611 +741,e35b4c1adff68c7e +742,38995e57e0778390 +743,9ff944af8b1e591c +744,413edcf07e735ca0 +745,58dc60f4b7457cc2 +746,778e09b48b166403 +747,edaed0432a05e133 +748,782b12f8ef699445 +749,0430e2fb3011b1ec +750,015a395434e080d4 +751,08e3f6389b668a45 +752,f10014517726a41c +753,9b3f15a1bbbc6a50 +754,64c00feda96d326a +755,06edef658cc92e05 +756,63f21fea1fb440b4 +757,29d598c631ac3f6d +758,7a84cdc144de9283 +759,57b39b025ff972d7 +760,ad4892bd439a3062 +761,86c097522e71b3e8 +762,d9b16b9423598f0b +763,76de48c02c7e88e8 +764,753493559f745388 +765,36556d3ac0652d48 +766,45c0dcb7bd5518f0 +767,2227507237a86146 +768,92178d9273322af1 +769,26a6eb0146c8541a +770,598d7d80de0fe665 +771,516d6dfd638481a3 +772,3417ec824977d704 +773,015be7a276b45649 +774,99911cc8347374f3 +775,3657eb08148d298c +776,df26670327645d06 +777,70b657d4828cd358 +778,4851c1a78a085fe0 +779,b111bfd2e3a050db +780,278fbe14a7e6f521 +781,9dbd5e868c8926e2 +782,3123bc01d41a7420 +783,abe97321ddaeb2d8 +784,93cbf91102ad8db3 +785,9fe3e5d7b9289522 +786,04dbac6a3c6b98db +787,f0f42dc64f56a8ec +788,e3a2ef68a4cbfc50 +789,b0f4e7ba107087af +790,1e05f53a90c1dfdb +791,bad2a059778b72b4 +792,59811d3c8d300c7a +793,17fe94b1660d8f52 +794,57ec19abbd9fac60 +795,a26998372a517e9e +796,ed20f50c582e034e +797,60b2639ccb381066 +798,0a4facf9da575a0f +799,47f971519f1d8041 +800,006868641aa97172 +801,dc3b410590a2ce25 +802,b5c441eb11ab87bf +803,b43f75bd71143adb +804,ae7403fbc857db4b +805,e6906512809e7da1 +806,4cf81c85ba10b83b +807,3c5bfd88c27c1553 +808,2daa199d1a5510b7 +809,c0c696fbde66aa6b +810,832509df5ef067f8 +811,a4804f8756336d09 +812,ad8a8cf6ba0871a2 +813,a8b4ba24ab940f0a +814,4136e0385d82fd15 +815,cccee29083caf9a7 +816,a628c84001073dfb +817,4b6b7fcae9fc3ffa +818,61525189235f572b +819,e6fc9914d44aabde +820,7700808ccf67402b +821,77f181dacccc524e +822,2035dcdb984c4f70 +823,bc246c55118d2ff5 +824,dca8eb6f3c004924 +825,b36f8ef41370f5e7 +826,fc893fc52241be84 +827,7a49d3e7db93f1b1 +828,a6c9d77c17af7c92 +829,f197c7eda9af21fa +830,897171e3ff067d53 +831,e137f0e1c0eda69f +832,69ea5e3298eade84 +833,2e7a152ff9706e38 +834,e0a5999ffd049133 +835,c5348417e5beccd2 +836,e9349fe473f13f00 +837,b44e0dc257eb1811 +838,5d156814c926be8a +839,4241c787807991ba +840,3d4a4f5444a71e7b +841,733d043d5f857815 +842,6bee9e55db6c0a08 +843,22a54664516ae551 +844,c3158c93f339b31f +845,585f4d61288e16c4 +846,8c98522d85188c38 +847,e1936919d7a02a58 +848,1cd428fde5f7715d +849,05127ce35ae18857 +850,369a0f0a8aa5d972 +851,5d3d85cb971d04c6 +852,f1a56405dedd8030 +853,84afcfb6a7b31eea +854,b14bf23bf4776b62 +855,4d1c56ef8f806c6d +856,924e25e1416de82d +857,937998f36ffc7e7f +858,01b4d80f2eabfbf9 +859,de334f8a910bc7b0 +860,1ddfd20f9d64ae93 +861,faece2fc76bdce37 +862,b483374b95f84ee5 +863,3db33653bcad32f5 +864,43d8ed8c62385192 +865,9a74a09edf436777 +866,f0d4449a6f210018 +867,1e4292ca5cd1d1af +868,209dcfc614503d8b +869,ba8790da4422519f +870,e9aa3095d4beb6ab +871,6e8113f077521f24 +872,e836020c4c24797a +873,55fbdc9cab035eba +874,dd3eeb56ac2d53c9 +875,f0010a27352c535d +876,fe1b9364138b22c7 +877,9aca50259fb0273e +878,79b4f28b1d04cc97 +879,a05fa727ec0532b9 +880,391c6f28b5c46a41 +881,8ee670866fa20259 +882,32dc5be8653abba3 +883,58b62c42b54f2d43 +884,6cf3d1da42152834 +885,e6b4662f3fbc397f +886,91e85bef96c07c20 +887,7fa260fc515b0a42 +888,0a7c5b0bebe61035 +889,566fba711e30c640 +890,948d25052b309c74 +891,7710a57c7beaf158 +892,ba60247df60d358a +893,67440d01609507b0 +894,018dbc26aa8603a1 +895,8a34c0fdea7163a2 +896,e7878fd85a54df68 +897,bb05adb558d75016 +898,2a99b56dafcf790e +899,81cac1b6564e9d11 +900,9d2ee63c33e96c0f +901,38e2dafb2ba400ab +902,e3522e6eff6877b5 +903,e296e9bec9bc9627 +904,763cd490a6b92dd5 +905,b8cc2feac18b83a2 +906,f0c6e30ecc0feac2 +907,3eb23a5bb21ba88c +908,43cb703923e5a84d +909,b302b911413732e5 +910,d644e024d0008bd0 +911,3829b3966f6f51ec +912,6fb1921be5435d61 +913,c63497b9db8cf201 +914,03c2dfa078c0d7e2 +915,e9790b8be5924be2 +916,40a87c1e09a5bf0a +917,564c88768407e929 +918,ef2aa38dcde18a9e +919,38341b76b359e9da +920,768b7fb2a86db4b0 +921,02c5ff8653573aac +922,b7cbef1b78106e78 +923,b15255b50d651206 +924,32eb8cc774b2eec0 +925,98f1d93d30d67dbc +926,e3245fa4d8071aad +927,230dbb696455908c +928,aa0587cc5514a57f +929,6f090d3a73826244 +930,87b7fb4f4b18b177 +931,4c3fcc0311b61236 +932,4b083cba70953d9d +933,d37c566667f8308d +934,513f8bd48e62c5ef +935,0be2de71a3059988 +936,290adb3e5cffea25 +937,20975cda8f782b96 +938,81dcf4324c979a75 +939,0633e9a322fbbca1 +940,918ba02cadfc630f +941,27f5f91a052181cf +942,0c99f6d34d44adb4 +943,5ecc46f0048ed38d +944,ed0ab819182c250c +945,fd4d2f929c52b9ed +946,ebb769e7ead157ce +947,ed95a1ead557619b +948,57c6d58aea6768da +949,5f9483b6e6b5b7d4 +950,134c362f4fe389be +951,ce36281046b66c80 +952,bbd9d73f42ae2c39 +953,05a13919478c6652 +954,2fb4c74c01007966 +955,b1fc94b3e6331ac4 +956,bb526ce5031fce51 +957,0dc3a76def4ff857 +958,9c2a7a7b41e35c6f +959,41a1cae39aff9e35 +960,3e945cde04292b0c +961,e4838d4db13908ab +962,5a000eeb089ad142 +963,3656b79b6abb3f25 +964,6b0800e7b52e9d58 +965,5a2401c43ff014f7 +966,14876d61a8d19bf1 +967,ea692314d6562034 +968,1604114e5848f59a +969,5f3aaf51475d1505 +970,b22fe4bfaa5f78cd +971,69daa335f996084e +972,279a62bf15bf8a72 +973,c5ceab02b62eeb79 +974,905cf8318dbac5e0 +975,f029f3fa1b718127 +976,505929dc36c00f68 +977,5330859e8b6170ba +978,f5e30b46f72507bf +979,dc380ec2807d985f +980,d13cff60964a0676 +981,74a3c2c8f12ac8bd +982,03e3f9c784d5b96d +983,6d42ab7877150a88 +984,aa56a8ef68d0601e +985,01c66f9f8bb304a7 +986,26c00500267708b2 +987,0d74c5cb2610f09c +988,f5baf117ae5a25cf +989,c1711498edf9383b +990,8cb62b8fe4c0f137 +991,133ff8390a265a4f +992,22bacb74ac427321 +993,493dcb8f16d8c21c +994,45a1ec1ba03c2ba6 +995,118949106e8b75ae +996,aa9d5784736dee18 +997,59c4219329ffaa1b +998,b41985d6e87ed7ba +999,d956e7176b3f723e +1000,69ad9e73a458d536 +1001,c54199122bb88482 +1002,465c4d6698381c65 +1003,89043be47cb6a8da +1004,cba8d3b7fd3b70df +1005,9a872c2488dd406f +1006,567f2092045f8532 +1007,f548a84d1a835798 +1008,2b5669052605d206 +1009,711445e46998c06b +1010,8745074093b0e40b +1011,a47de80b2902dbf2 +1012,d6f0d1f7e1baaf52 +1013,5b854909bacc399f +1014,47c7632298e2c026 +1015,6192c2c220ed3eaa +1016,80c759fda6ab2ab5 +1017,bf56267cca084fd7 +1018,29dfe3fa9c161e98 +1019,75d2f3b7727508b2 +1020,fcdfb595cc7347c1 +1021,004983e95ccd84a4 +1022,78b7f2daf8b868f2 +1023,5bf0a068c51763a2 +1024,eb2725d4dd982804 +1025,ec953d20675dba0e +1026,dcd2f653f4c2627a +1027,d1371c45ceccc056 +1028,64973ad169604797 +1029,f148f00cf0378e41 +1030,10d6c9998448c939 +1031,491180798dbecfc0 +1032,fec1b89011e12e5f +1033,1314ac860af3ef42 +1034,917438f549ee1207 +1035,c90985310e52af59 +1036,5ae8d2255d3b246f +1037,b3ad2115684fbd7b +1038,978d4cfe76be7cd8 +1039,a3f84524ff6d05b1 +1040,093ef4982ba5ce46 +1041,f1e61a296ecfee4e +1042,daa9c43fe9bb18bd +1043,cdfaf2b457caaf58 +1044,842ee1985d9a143f +1045,c24d1885ccb25513 +1046,b3b6a2665857fe98 +1047,bfa5d34eff4e8aaf +1048,421ee69350ad0e66 +1049,cba13ee26cb8baef +1050,5d21379a27176c42 +1051,e9563ebc86fc4ce6 +1052,c64e8cb8cc6dbaf1 +1053,38015596f50e96ba +1054,93158041aaf356c0 +1055,2abb6bcd6d04b03d +1056,7d3b30a2d4286075 +1057,4a70a7188ddb548b +1058,32595159743cbc62 +1059,c6135b4cba782404 +1060,756863714223e627 +1061,34f2f672e5b1cd22 +1062,b89f45455dba755a +1063,2f1baf27861b2092 +1064,da5a5bf56c7c8ec6 +1065,e5c4f0f00a297981 +1066,217c648709575596 +1067,eae82561cfd5b3dc +1068,6a6a901e1e675c44 +1069,42f1f8e1e2f547a7 +1070,3ec54081646a7a3b +1071,f98249dd41fd6f27 +1072,1eb4a1e131147508 +1073,cb95d7475051f119 +1074,ce12045ec15877dd +1075,7d28d03f60135c00 +1076,41c3429e134c2868 +1077,a4a1bd800e891be8 +1078,3efc6b427f20cb4b +1079,213a64befc03d892 +1080,7b2c111aebab4247 +1081,9c407350ea68d42d +1082,8f9161733c71b603 +1083,c9c3a4ec1d58c8b9 +1084,7c41e0102f040abd +1085,8edd6f9a1c66f889 +1086,e0e8bd1042114341 +1087,465622ab02ffe971 +1088,2d7fc1d626812d7e +1089,4b7a8d305813447c +1090,357e236ac0201d77 +1091,665b77dfb81eb54d +1092,46aea7a3f8f174de +1093,dbb1378b6b222fcb +1094,a2814bec1939b4ad +1095,2e639be996ddc934 +1096,8d243d55da9a99d0 +1097,b3ebaf5f798cacee +1098,209f7ec12d21e643 +1099,eabed7f42bc3f228 +1100,c25b2861b28ed09d +1101,91575db4e1ef9846 +1102,87a13bf63354fbf6 +1103,0f6887eb7a2b9e07 +1104,2afb19ddf2956f03 +1105,a925cd3f8ca4aabf +1106,298ada4f8bd1bb4e +1107,cb5d3959782ed36c +1108,2f56880f8b6f7bdd +1109,3b998fca528224f4 +1110,49d9c933e8ae5ece +1111,e54219a59cee6f98 +1112,409b5a98cfe9708e +1113,1e515620fd185314 +1114,694fd87eb202f05f +1115,d7ee2cfa105b630e +1116,916775e634f67ba7 +1117,adac30ff4216dcba +1118,aad82e76a38b690e +1119,22f487e10f4cc668 +1120,1bc34590ee432b2b +1121,93403ecde4c033e7 +1122,d0fbd82b98b076b1 +1123,3268081cdf51529f +1124,74d52fe48ce4b841 +1125,d1755bc9c1c3ae68 +1126,15245764a8d26d59 +1127,3cfe0f8e1baaca6c +1128,dd963995ab7b5d46 +1129,912655ae0d3fa04c +1130,de3347a4332b327a +1131,24f034ebe057f604 +1132,aafa307ba6369416 +1133,ab247467637cca71 +1134,4a23c8f07a79ada7 +1135,1188b8d9a5052227 +1136,59161e117ceffedf +1137,e136c4bca6f5b756 +1138,6c70bacf85fd4b1a +1139,85c9405dcde78454 +1140,ae83bc017029c250 +1141,e7e30d5741e7300f +1142,7acfde3f3c54cc71 +1143,281bd0069cff2872 +1144,15c2551ae39d1dad +1145,3eb48ce0d4fe759c +1146,99676fb3a8cbcbfc +1147,791f19ee00db53f6 +1148,6b20e5ce7c7dcb26 +1149,edec0f20639fd147 +1150,20aea11cf5689ced +1151,c6a9a7994047bce4 +1152,22694ad677b95f5c +1153,11e751325e612a98 +1154,d41c91901efbc0ba +1155,1129256953d64121 +1156,ecf0bb70e4be438c +1157,f7fb95db1954afb3 +1158,93f8d897897069c6 +1159,af1a8b87316e04ac +1160,b82e67f348ce8452 +1161,b78b207c3ba61c03 +1162,980db24b5a004d93 +1163,f081937046217589 +1164,0bcd2339b89af00e +1165,2598497bb39b4672 +1166,d558e4bdf7bfe654 +1167,ef2e99fcde0ba99f +1168,82b03a85bdbc4b3d +1169,e812ff149771f68a +1170,8eb93a18e744bbba +1171,b53269b4d0fe080b +1172,f1f2c5eb591e0b08 +1173,c76fcc2e2dea8b69 +1174,c70b0112cf8e0465 +1175,b14e0c2a9d121286 +1176,185e96bf1ef85019 +1177,8dae9cc81a81628c +1178,890be37c8969dd4e +1179,654a80cf05a694e8 +1180,c5ef250e57730d66 +1181,7673ef5eded1d722 +1182,37154ab9b7f16063 +1183,8d3b061f27aca563 +1184,813bda733ddaf6c0 +1185,056ef5b397ad6d00 +1186,3a3248bc5788dc33 +1187,82bf41aef70251f2 +1188,824819b2c1775148 +1189,045e862dab2ad111 +1190,b411e982f13df32d +1191,04f427cf6c7c53fe +1192,40870490a8221123 +1193,4b02afdc64fc5d6b +1194,2ebecbd38eaace08 +1195,389bebe721bf9d5e +1196,b8b501f2fdb582f7 +1197,75247c291336cc53 +1198,a80fe267170d1463 +1199,ed8ccd144a484ef7 +1200,7ff0b4dd8fa906dc +1201,1956183ed4e3d98d +1202,d01d8a69a1be6881 +1203,286f2561d0320683 +1204,5b2d2be6376e1e3d +1205,f08b112255a85c97 +1206,01d73ade906136b4 +1207,2bc8b80ca68cdf49 +1208,8b9cb3eb1ec20491 +1209,3fa11175072a323b +1210,e98cef2c61d09382 +1211,a555db79340adfe9 +1212,c2629bc9d9cebb21 +1213,5f85c741b85baf40 +1214,5b9b6c114b351c38 +1215,2419e6069c8ad62f +1216,3cced5939689f316 +1217,acda04e9351390f2 +1218,24c7b1b3c2e48297 +1219,4ca3a5fdeb37bab3 +1220,bb08f95b93732054 +1221,1f0e07059cb52389 +1222,21de9f96d4bbdab6 +1223,9be92b139bb80bd1 +1224,80968e364714d527 +1225,fade3bf15fb12506 +1226,7bf54d1ca2f31d40 +1227,22a573f676f07006 +1228,531cdd601d4018e8 +1229,0b5c1a30284bfd6d +1230,228cc2b235c5468b +1231,15cfe746422d2256 +1232,5931a365893bacfb +1233,6da3f3f312e821b2 +1234,c2c214b04969f8d5 +1235,30bf0ef780d0de4e +1236,a8fd5cec7a2fc0a6 +1237,b6be98b971ab2613 +1238,417297f0c0963578 +1239,0ea759a42a4beed3 +1240,c89f97195f1f8b74 +1241,ea28e5c01663ea50 +1242,c2ed8a94c30226b7 +1243,fceb3f168424b711 +1244,b71637f132be838a +1245,a9ba7674c36c2b0e +1246,5ce82cf1d141db5f +1247,1e8015668120599c +1248,3f7e24ec2e06f970 +1249,bbf13994f7fea1b8 +1250,a0d31ab600fe76e1 +1251,7eb7a474c810b31d +1252,a3a387c09c83d904 +1253,0e7d9b4639a2353a +1254,345ea601172957f4 +1255,219a9a2c5fa84fa8 +1256,7e26db3ddc95aace +1257,6455597a79907ad3 +1258,f801d12a2ef6596c +1259,e497c75dbc680c53 +1260,2bcf63dc57e62dbf +1261,cc505291e37f648c +1262,1b86a36fc3a044a0 +1263,8ac232c288b182e7 +1264,666aa425a9a4e2ab +1265,d03766c6670ec14b +1266,4d3425f717d7de9e +1267,9e176ee2949a6a83 +1268,551fb3d8a143ca1d +1269,a267c0f7f0e59c74 +1270,fef222391903ae93 +1271,be199c26638efcb8 +1272,b7e8078436492926 +1273,97c779b4edfd9133 +1274,2124536f869fdbd1 +1275,316718df0355d3cc +1276,b928bb7dbea90bed +1277,42a2366b2bbd3d6d +1278,2cf017f54533f090 +1279,1717b64369a5a662 +1280,adcb1d0404a38272 +1281,fa19888e18d3cf04 +1282,1eb06b2eecdb444c +1283,4455653af3812345 +1284,b8df1915c38a0d9d +1285,29faaa28c3e1132a +1286,e437b59e795d90b3 +1287,b9affd4e26f67a45 +1288,304645732cee77c3 +1289,e74faf1c45affe65 +1290,b415fc192744b59c +1291,2e53032a8ebc6852 +1292,f3412b0c2b3ff22b +1293,5b1d7c1640989d96 +1294,052aa4458342bfbd +1295,1719acc3d4d590e1 +1296,f197ca4c1db0c064 +1297,55f685b11efdaa1b +1298,d2b5fc5f7e5916a3 +1299,65c8db57d818dadf +1300,18cb062af9c77d16 +1301,0dcec29427bcdd25 +1302,9c4f7018e842a555 +1303,43c36dc8e19a0bbf +1304,3be941a9603a9596 +1305,378fc44b4c9355ed +1306,8325558a9602c503 +1307,11d246a2800b0c7d +1308,b10ca63bf3030a16 +1309,3f8bd787f6762fa9 +1310,eac31f8cd998a181 +1311,0d2cd95277b8f7ec +1312,8970aff340d785bb +1313,2d7478e9426c7ec7 +1314,0f73dfda02f29fcf +1315,cdb9c2ab16595dbf +1316,b5d830dc0c66dc44 +1317,6e52a484552fcb73 +1318,fab3e32716ae3505 +1319,437497b583f07fcd +1320,e5c5a90ab024aeed +1321,bb7b674f2208d197 +1322,3fd2a87cd1faa48a +1323,ec748ecef4404226 +1324,f9c5e1e73c1426ee +1325,a99f5469febc344f +1326,8f3e1a0151fa2fd0 +1327,7c58eb143884f150 +1328,d9253dde85cec9e4 +1329,8c8002d565eac149 +1330,7efb1e90ccdb8dcb +1331,3cf4fbec4f132eab +1332,f5fb4bbd0355c1e4 +1333,4630f3f79fed064b +1334,03c8031d262c786c +1335,cdf5b0025a17b852 +1336,9d08cdbeba67dc2d +1337,fed9e8c8f6bbd205 +1338,c9120e04aa8cc1cb +1339,dd110b069b724dff +1340,10c83070ac3bc7cd +1341,f54af268cd9b9599 +1342,2ec0b256f0187398 +1343,26fe86c4190b0090 +1344,b90ee96afcfd7c17 +1345,abfeb268f8157bd2 +1346,686399241f72d558 +1347,91cf4499ea908837 +1348,330498742ae0ca53 +1349,4f3791ad7a540f2a +1350,8be864733334413e +1351,1ac002bec0f02486 +1352,ac1da6d8a64f0f18 +1353,b2fe2e066fd4b5de +1354,403395d7c6d22c08 +1355,3697df3207473be5 +1356,e35a1cd0ad2ddd6b +1357,faf55465fe5c26cc +1358,4a1f79c6700a290d +1359,fdcdb8cb735d28bd +1360,2aaaaeb7a0280344 +1361,8e77aaebf0b14ddf +1362,7de4460fcf8e9cbd +1363,82dfab661f97d6f9 +1364,d89fc20c5e38fe3d +1365,410dfbb1b64b1d4d +1366,99a4991d68cfc587 +1367,72c4e2bd8d772702 +1368,7a6cbd9b64075d53 +1369,25f38645b4120c88 +1370,f84a02e6f5ca49b3 +1371,22be54b7b12edf32 +1372,0086f91ecc5a1b03 +1373,e1ba3bf223ce9bd7 +1374,e83e26ea7d1edc67 +1375,b4566d855eea62c9 +1376,bf3be64c1adceffe +1377,d5b8d8ad399f1ea5 +1378,281f2b251dde63d9 +1379,a7690d99300f95e4 +1380,730832a5d0888ccb +1381,ff7e28f1848f23eb +1382,d86b893b02bba37d +1383,dded580433f619e6 +1384,5a34a0ac6c3a6dd5 +1385,36d6a3f4818e6177 +1386,1e09ed7ac5daa68b +1387,776df19250a45625 +1388,c2e4477f7da5e101 +1389,413fc0ea56e5f76a +1390,24a8127fc2c8c041 +1391,296244259bc35cd3 +1392,b32ef8d1ff015dbf +1393,0d1ee4a7f1720b0f +1394,8072730c59f5a410 +1395,243335de87b05d75 +1396,a765b21d955b1404 +1397,d80444d5c8d9a35d +1398,d4f5e286d7edc630 +1399,3e2c5cb45267d46a +1400,0ab5e6c1730773c1 +1401,dccda5405f2ccc54 +1402,c44127e34d393b05 +1403,00ecbed8841098f7 +1404,e204852d99d495dd +1405,b320162f8e15450e +1406,77ac5a8e8dfc1191 +1407,9544832e98808980 +1408,d24be988cea832a5 +1409,b72ecdcb0fc8dbe1 +1410,cc57a47a64042e2e +1411,dd5c3c946d4aeb42 +1412,4562c0c5af8fb849 +1413,6863955eb04243c8 +1414,40d961a8c9403568 +1415,caed7dc64055efe8 +1416,f5e3e356686a8391 +1417,c167b68d787f81cc +1418,dd9e48292ee1b183 +1419,1e7096a8fc9c759e +1420,8d42225c923ab12e +1421,94c633973a0acb5e +1422,9e0a2ceea15d092a +1423,40698e11b213051c +1424,82d0c367325b5a6c +1425,0954df12b83be4ab +1426,0ee5975dc8d00dda +1427,0a7328c3ba3b65af +1428,fa55fc6c982cd8eb +1429,8a9c24ccf6f38793 +1430,fe0bde84841c58b2 +1431,81c88802ae3e5dae +1432,39bbf873296142cd +1433,1f6df701cafadc70 +1434,1442005a92dc4903 +1435,30ba156439d05067 +1436,f7be33650c90352f +1437,adf1e0481e8e9720 +1438,8dccad065318e759 +1439,beda12beed912cb0 +1440,3579b130df5eb3f9 +1441,b35656944c94e336 +1442,dd52e1a16497e7a1 +1443,d67498d1bc8276a8 +1444,7087d93df781ae0e +1445,5655f8ed056049d2 +1446,e998740f32231ef4 +1447,fe4ddb0c3387e152 +1448,271c40fe76866120 +1449,2afca3345de83de0 +1450,e51a1e571472a198 +1451,57a188791d122587 +1452,557f52a4d07c874d +1453,f3806f0752a3d67a +1454,c918eced92333764 +1455,1307a82a522c754d +1456,94de2bd8b789ebc9 +1457,d21b6bb68bf1e283 +1458,e3a6cae00b5fc2f2 +1459,beb23afc3c616f0e +1460,49e3ad41546c5573 +1461,006926cdfacd8a64 +1462,8615007e8e53e4e9 +1463,91a2d01e5bb2f723 +1464,b43d2c6cd62bf023 +1465,5448172447e599f1 +1466,86b1d6db721aee6a +1467,4ec5ad4de3dcf9d3 +1468,4bd42c311d7d0418 +1469,7efa3f573d12e27f +1470,6a399b76a854742e +1471,cf36292b77c3ad73 +1472,2543bb164f10330d +1473,1857b52734084975 +1474,8b0d6c6b6b16a621 +1475,7afbafe6109ae1f8 +1476,0be6e08a14984ae4 +1477,efbb075c57feec13 +1478,c443ef998f573402 +1479,933954c2aa6ef72e +1480,a23197f5a5b45e6d +1481,ba0ad6aaf54902d6 +1482,60f5157724f176d9 +1483,a10b903f253a9ff4 +1484,577ad56033637178 +1485,77f13b2cbdfc6984 +1486,a311b4278bc27e22 +1487,4ec246f086d9a286 +1488,1775d899101e0144 +1489,6f807c1099006c4e +1490,551a5da578a6ccf3 +1491,e4494efb9fdb2898 +1492,5cd67f3a910e64e0 +1493,383ca99e69b02521 +1494,b72462149df7fa4d +1495,a2ffd28515feae2c +1496,9a88fc4d0ed167b4 +1497,1ef6a03da71166a1 +1498,fce6f749f8faffea +1499,d7fe7154a056797f +1500,20365393c3e2e0a2 +1501,cff54527b0b282c1 +1502,6f734a2ef8b441cc +1503,ca8c69d89fc82a98 +1504,ea3c38abb33fa9af +1505,4fca864280fd60d6 +1506,5ef1895cbce3a46b +1507,2493c703761039fd +1508,87cdb88dbd1eab82 +1509,2ad489edacd228bb +1510,ae6fa38bd4a5eb0b +1511,50510f771930e7b0 +1512,ec7508c43104b91a +1513,0a7e48b175411db4 +1514,5ef32539746fd592 +1515,f979f3477d14fbe3 +1516,17642df456020458 +1517,cf945bb783f84f5a +1518,fa9b99b12ace9ba6 +1519,0ea0b549dcf1d8ec +1520,79c62fbd839d5af8 +1521,720e5791a3da48b9 +1522,e9f6cd0f815f314a +1523,13a0292750d45d15 +1524,40bcd0a5c6dec084 +1525,eeaa16412d20ffb0 +1526,ef4f3576502cfb15 +1527,f858064ac390e42e +1528,58cf7ef820f1317d +1529,160ad0605d11bb81 +1530,b5a08d2471d81ad2 +1531,14b5b1fd476192b4 +1532,b99aeb2ae78af144 +1533,32ccbf51651d5fb4 +1534,a88455764ff00f4b +1535,6ebb6fdd3b67f3ce +1536,c4bd9bbdfdf78bd1 +1537,052d1fea52213eaa +1538,0b8f7894dfca4bd2 +1539,f98bfec1d22560c7 +1540,a849d6729e7f2dee +1541,4ba6f4e7311b6e4e +1542,d1829cdc595f79bb +1543,66d0cf9b82e94f2e +1544,c070117c601cd4a2 +1545,2d3ecad80920049b +1546,626bdaf981118338 +1547,9663405a87013872 +1548,d9cb0ab638c77ee3 +1549,732c6be41ff2114b +1550,612b6fa7b42b7616 +1551,afe9cfaa54ef57bf +1552,924de42bb71f9161 +1553,5f1045813cf223a9 +1554,32aeb2598a30e473 +1555,fca027f60ee93591 +1556,7902559e6afd864a +1557,801a361b7dcb6fd7 +1558,c1f6afaca6185e7a +1559,938e9e96c8be5f0e +1560,105c170fc429d296 +1561,07a880b7e882c118 +1562,19412a2fcd9cfe74 +1563,8c51f51a5b23d38b +1564,8778ee8f86395c31 +1565,fa25b36590560bf0 +1566,6fb5c7ce70450e59 +1567,f8d78b92b81b9d51 +1568,9164721b41797bdf +1569,e972f6647c3e5266 +1570,8f6cffd5c4cf0ab0 +1571,8d3e19cd63f1b45e +1572,d6a2c516fc7b344c +1573,9a7ea4ea588a7692 +1574,d46e742299c83dc8 +1575,9554c1ec15c7455e +1576,1100b48093d381de +1577,b4549658b44c51e2 +1578,ff9c5cdbb3a4d8ae +1579,2557773232a970b0 +1580,c03bab3b1ede682e +1581,f85cc8cf714aa1d4 +1582,71310cf1249dbc18 +1583,07c4836324176a5d +1584,9a7cc6220d024efe +1585,f052d85d98201acf +1586,3a9174b315c90706 +1587,e5c9210b8513aace +1588,dac7f2e788d4d088 +1589,32d12b0d1bc6d513 +1590,096442d347e2c3de +1591,86edd8a9ec6ad96a +1592,a4a7287ae326fffe +1593,00f0ef103b19740c +1594,ad95f46b30aa1a7a +1595,4d6d4b43c630ff77 +1596,4805e0ef5870e88e +1597,637902f3798b3933 +1598,daf5423a810364ce +1599,075e9c97481c7f93 +1600,fe3aba795b24c839 +1601,4014202553dc7bce +1602,82a97fd20f7cae9b +1603,3a15193e8ec1cb89 +1604,aa3c457b089f3c83 +1605,c9d89b79ef4cd716 +1606,049300ce570eb892 +1607,aa86bd9001d89d58 +1608,4f58c6fd5f7f9cac +1609,8b5c9e0fb1896878 +1610,8e52e0500d73dd15 +1611,fdd546173b1c3f4d +1612,8b43f14844754c7c +1613,15306e3ef29d0846 +1614,2529d2ea82d1de08 +1615,f9c3f1d3a51dcf28 +1616,0407e5b89861a0c2 +1617,52e92aa491f36a22 +1618,92075cab5fb89c5e +1619,31e7788bdcd9a436 +1620,f41ca81d06f629c2 +1621,cbaa34b5b84505ee +1622,3a581ec4181569b9 +1623,665a777dc8e31db1 +1624,b8eaa8dbf02e9819 +1625,b7b001e449ad8792 +1626,752f96d58be41d7f +1627,e434b68916d73ccd +1628,db9518a19c912d1d +1629,694d4e1212f1cbaf +1630,3125339829998be0 +1631,4e9470e9d8737184 +1632,e4abab05aafd09a2 +1633,845684b8e068318b +1634,c4455dc0ec417830 +1635,1b90d6212feb9fb6 +1636,c66179971bc75b9c +1637,275e9d3242974107 +1638,f06bfa77fabfa0fb +1639,4a7e9d1e2c2a6bff +1640,d16686c16228693e +1641,2c96b5c0ecbd7d6e +1642,91d20c8ec7de92df +1643,0340723a26829eb7 +1644,6fcf5be09e73ee6a +1645,efb81e92238e53ec +1646,fe72dae20003da41 +1647,237c99ab32ec289d +1648,aae3da3f6cec4488 +1649,39ba30ab3b8e40ed +1650,c09ab7bbaad6a48c +1651,5fd58fa4c25b87ea +1652,eb4aa4040576d085 +1653,a5be4a18fd54d2a9 +1654,51ac65cc61e4265c +1655,078b586d11190df1 +1656,bbd227db7741e45b +1657,1501452c86bf290c +1658,d769a387c727946e +1659,9e6c71a3714084f0 +1660,a342776e93ab6530 +1661,3be00a44bfcedbaa +1662,8ce86761e072a5fe +1663,62377b80691d272e +1664,0489e50e3f8d0cc9 +1665,3ab716788766662c +1666,58dfb3baf5905925 +1667,f2b5ce2eec441595 +1668,8ebf87aefc3d768b +1669,ef25290f2ffd3755 +1670,be1fabde24cfef04 +1671,b453053dcf3cc3ea +1672,54e0e20786082c1c +1673,8a3fe395feefae6c +1674,345031f4716ce323 +1675,1a46f6aca7db46ef +1676,aa11808d9e91e6fa +1677,3c7bfc9a8f47b958 +1678,09f0f0dd703bb488 +1679,868be13d608b5e99 +1680,af908b71ab2cfb97 +1681,256141aec9d3dded +1682,8af28e37de8d4a44 +1683,5c4a1a77fd17085e +1684,94badd70afe8df2e +1685,9551ac0c15a8c370 +1686,330df6a28717128b +1687,0b159d90e6da91fe +1688,4fac344b07308352 +1689,3a68f399a973eec4 +1690,357a2e58f296cbce +1691,b08382a087d1bf76 +1692,b396713ab65c7c0b +1693,dbc66124eec61ee8 +1694,b0e708d2b45b121b +1695,67e36557033205c6 +1696,0e59282270437da2 +1697,e05728fccea150cd +1698,c205b5abeeba46ff +1699,6ebfa309a8111cf1 +1700,451c03c0884abab0 +1701,526ba1322c9e46ea +1702,01b66373d32a9ea5 +1703,fddfcf02df995b37 +1704,f09431473762a18b +1705,fd4c2a3bdfabb018 +1706,453fe8f262aa0bf1 +1707,b91ef71ffcb5495c +1708,26f86ee81af75239 +1709,caaf547dd2ed3a6b +1710,379075d9d31deba2 +1711,9c4e55abd7292535 +1712,23ab2a4b453ec526 +1713,69b7144ce0a3938e +1714,41e6bf91e7d53a4c +1715,3a3c1d4dad9b99bc +1716,7bf72165703c5567 +1717,2e01e1ab01b4e406 +1718,02fc0c686125c0a2 +1719,bc36a02337a1eaa4 +1720,7242ff577ccbc0f3 +1721,632d5ca92efb01e7 +1722,360dcc1403fdea7c +1723,fbac28440430603b +1724,6258d95a82711a1b +1725,50bc74a685f97150 +1726,445bcd288cf826ff +1727,7ef0a7f5ae57612d +1728,6442778b61f619c6 +1729,eab6576a47ee7783 +1730,c50ff22d8b8f1cce +1731,0cd2582503d3a475 +1732,0eafc045f2d5a55e +1733,bc469e346041c8cd +1734,9f476ca5a1d56c02 +1735,ed4b50c6ba9e6b8a +1736,c1281e315f9a5db0 +1737,63e7ee2a9773ee8d +1738,4b89ac7373ab175a +1739,754a7739e292691f +1740,36d04e1508edc813 +1741,d86c7114f3e49d76 +1742,3d748e9732ca8eed +1743,c365f13da6387461 +1744,f20bda14879d031d +1745,16338358d1542d05 +1746,95dadd5c507a7c78 +1747,69c4274f733ff6c4 +1748,09f0b96bb0b3a386 +1749,46abf65893c64bcb +1750,b4026e7347d4ec8c +1751,6c8068af4f468780 +1752,0a685a48740ab8c2 +1753,517bfe890784e73e +1754,8d9915155745aea5 +1755,6884b87b242ea7e0 +1756,892ccf234ab98bdb +1757,5a154c27e176a385 +1758,d731996145768c02 +1759,1e490b0cbf027604 +1760,27e03c781b277b5d +1761,c894410ae2d69c81 +1762,d79a37afdc36020e +1763,ba4bc887ec15612a +1764,058b7a899c5e70ca +1765,215535271db13281 +1766,fb86e2b9d0e793ad +1767,b570dd4fa6505a73 +1768,8bd6bfb328d8c03a +1769,030d3d24346bdb68 +1770,32994cf5ac0a640d +1771,b884b53205a45544 +1772,c5179157bd8813b7 +1773,5f4e75bbd141bea1 +1774,d6dfc75bdfe028a4 +1775,b537721dd3cb4cd4 +1776,c57ebee372992786 +1777,6f13bb359633bf12 +1778,e46da0ed36428fd5 +1779,4b3b83f6ee1b1faa +1780,6b6a823e8306ce4e +1781,2c05edbd7aa5f3db +1782,b327a8a002017857 +1783,8504cee56cda7ae3 +1784,fdb23487c67f2615 +1785,5196e6b7b7556352 +1786,a0b19525884bf2df +1787,731d85a6b91e4473 +1788,2493dc5737fa8000 +1789,b46b614dac586a8b +1790,be9f054a2684b4ea +1791,c518a2030ee91f21 +1792,745492e5e36a357f +1793,263a4aec62feb0ce +1794,498506ef09e28fc3 +1795,a9f6ae92cb2da44b +1796,8039345270ed801f +1797,19af793bc3157fa7 +1798,4bf5311937f6412f +1799,a1a99a7ef8872cb6 +1800,677f0f3b393d87db +1801,bf9a9a368abda086 +1802,add99ad30a08c412 +1803,be9f263ca116f21a +1804,4db7db5b447d11f7 +1805,52c18f5ccec5098e +1806,be46463b952a7139 +1807,a0cb3d182aee5ea3 +1808,6b3be0ed352cb953 +1809,08de0f0f9c8ec83f +1810,553d730692265ecf +1811,2910cd083a383f89 +1812,cfcb4118cb4c1161 +1813,2fd2fd698a7160c4 +1814,d2fad32963388036 +1815,99d1029da3873856 +1816,67991d74cea895fd +1817,9de4a7563c6e21dd +1818,1c2da7521e735927 +1819,f6c6527977c31878 +1820,c77b629099d444f2 +1821,793365f14cd29c76 +1822,4f3df26953a1900b +1823,7489bfef48778704 +1824,e0818ffbf22af865 +1825,8b178944a6fde039 +1826,1240231b58591b0f +1827,33b3f5157f4989fb +1828,6649769e14616c5b +1829,c97df3af4941dbd3 +1830,19a99cd2122835e2 +1831,93f45c412759c791 +1832,ca63d71461bedf26 +1833,a96254741f23f97f +1834,64b0a5d15459b568 +1835,ff5d43a04f1d5e32 +1836,63092393caf3d425 +1837,1c3eb3b5e5df49f8 +1838,924f81bea39611fa +1839,5910dcc876b6b6b2 +1840,20c9013fd03d5cda +1841,d1926bb617a8e4c7 +1842,6a1d4b71d96413ef +1843,1f0b7cc846a11b4a +1844,679e4090cd6d17b7 +1845,e10f898d0186216a +1846,ed077d4f9325ed37 +1847,24c1e07246bfd70c +1848,5d2487fc5264c47b +1849,4cf92ee4408e2557 +1850,5370c298cc89343a +1851,df6e2831f8d4afab +1852,170a3e17c9588144 +1853,37ca986d685626a4 +1854,267deb7f6e812a8b +1855,bc96a65d9f9315a5 +1856,206f80b69f5b71f1 +1857,7b29e859d2c12138 +1858,9f92ae977139b2be +1859,1cf3aa1306220a5b +1860,ac3ba0012e67e85c +1861,6ee47f057743874a +1862,0d2a6ae7a73ce85b +1863,7cee0f0565bc1825 +1864,60825f33cd15d632 +1865,7e454fe1cecd7a44 +1866,4eade431edda8fbe +1867,5145c2667c10ad86 +1868,3b64c5ef2556739c +1869,6cd693328e316b21 +1870,f51115b53fef7cbd +1871,455c53008f1f0aac +1872,8ee3bbc98f628804 +1873,d0903e3be08295c7 +1874,6d10b7f133a608e3 +1875,004e4b8fa08c216b +1876,f08b72c5832d7cf3 +1877,28100e997b726199 +1878,7f2c45951fac4da5 +1879,b4065300cfecfe92 +1880,5754610bd337b5e3 +1881,74831ac013e3f58a +1882,52818aac2b61e4cb +1883,2768540c627756b2 +1884,f344c4301ebe175d +1885,24ad2daf8d89d6ab +1886,71931f5dd34c1cc9 +1887,a87ba5945aa9efc0 +1888,d0cc1444af098227 +1889,dbcb6bf9e60d2927 +1890,0fc3c11b45847a5f +1891,a769c6f291b2d8ef +1892,c44205272c2090cf +1893,bd9e6c10ea61e723 +1894,02fa6bb324de173b +1895,545c313ccfd55ca4 +1896,cfa5d1785191575a +1897,cabb08fa780c5b0c +1898,a4e922676d3c077e +1899,69af2ac3d4cdbde7 +1900,9193b6fc394615ae +1901,769c9d408d61f35e +1902,86de8886e6d5d3eb +1903,a23d8eff0ed28b62 +1904,8307f6e6746a9859 +1905,e568e634ad7599d9 +1906,03145d8eaf55208d +1907,828980f224cf6774 +1908,5ae141dc142b2d63 +1909,79a82899d6b70975 +1910,68126c3ac949eec6 +1911,d65d58a5ef5337ad +1912,1b1ef79898d448eb +1913,2df0d5abf3daa39e +1914,fd368ca5e35a53ee +1915,93f09c883779f3c2 +1916,0fc9868b27f0922b +1917,9634b4656ac587b0 +1918,7344b92c16c1ea03 +1919,0472cb98a10b400e +1920,8c9fbc26b67603a3 +1921,d48eb5000ec2cd11 +1922,b40a23a72507d85b +1923,1625c618b103b6cc +1924,b585d3e0e779978a +1925,17f35616782c4981 +1926,e9073c573ce33bc8 +1927,024b866da9691d80 +1928,1e7edb9872356a06 +1929,621db4f39ae70e26 +1930,5cfe8309c4341b22 +1931,c23164a817b8416e +1932,1e6194cb467e3950 +1933,299eeb1e1c4d189f +1934,5f6701ed9cd8dc75 +1935,4ea55be49253442b +1936,8d097a8e67ef96ee +1937,9a553b033a168bd7 +1938,a4f95e51efc5efd0 +1939,a422013be415fb00 +1940,280efb4de1ad3985 +1941,bb40e9603bbedb9c +1942,b6e1b49018a717fe +1943,3e6e0596f14888ef +1944,7982ae4c20786552 +1945,f37977a8e41260bd +1946,fe126f5264a3783a +1947,c2d754671b33a80e +1948,a399de37bd0f5a2c +1949,cf6c23d67f338123 +1950,46a61e1918b4b884 +1951,322b77c4bc0380ea +1952,bd83c05f87828a8f +1953,b8897d9b56e32dd2 +1954,3d9c4bd298b38e47 +1955,5a04506f06d18683 +1956,66a3eae3060f06a5 +1957,4fc9c8925e47d406 +1958,c0f6c93e6edb4c05 +1959,c49e2dc3ed2f51ae +1960,a0795d9176fc874a +1961,73d77682d5a07f9e +1962,cceacfa21e862f63 +1963,508d64a7f1401aa7 +1964,23801ecac0d95a4f +1965,99521aefe7272a1b +1966,1921b6b32bd0964a +1967,35834a6dfdaf3d4b +1968,2fa1cedcebad6b4e +1969,2e22d427a41ce18d +1970,73d265f4d8cb40ee +1971,12cb2c307a56df0d +1972,dc759cad22db18bf +1973,753adbb24faee12b +1974,5a7496eddc6c79f8 +1975,6e929e0d01e2b7a3 +1976,67d44448f2ada783 +1977,9a82c2219fa985fc +1978,a6857e8ea527a38e +1979,a87795d0753d1b3a +1980,53b3254e0d322005 +1981,4a1b01ff6bbf90cb +1982,c5df8450c785dd8c +1983,793427dc44b829b3 +1984,e398926414795591 +1985,247563f3b55886b6 +1986,92f2f831976d1391 +1987,c1cc309a97192089 +1988,3c32970e1c277edd +1989,495c4ea9cd1acf5c +1990,bdf56d901faca585 +1991,ece2943efe12d1ae +1992,67b605dc44ca7580 +1993,5e3267bc35eafdf8 +1994,f8d29316458c5fe0 +1995,5ec02d36d7308923 +1996,1ca42aef21cb5cb0 +1997,a0aad63a67c14d74 +1998,b12e9d66ef9bc4be +1999,2009a9ab31fc4a11 +2000,ffce49a94589c4ef +2001,c2c1d7c37c8c1770 +2002,dd94c0fe90335f81 +2003,53ed0eb8617705bf +2004,c6eb7b1de4ee1c71 +2005,8780a442e731dfea +2006,f1efec0f46eda4bb +2007,287cb462fe3e3323 +2008,026641d0bb66ba14 +2009,4c0e0df39af36f25 +2010,3213e2334f116da3 +2011,5f795ef801e9e691 +2012,ccc7dcc3970991ac +2013,6f9f7b329d835cc1 +2014,7b2f8c44d23b4fd2 +2015,b9d8a866edf08568 +2016,d56dfb1e572002d8 +2017,6b234b3cd32081d1 +2018,5372fa0312ce6920 +2019,63f97aaa1041cc73 +2020,59185336d7faefa0 +2021,8e89ab85f6f84372 +2022,28a0a232dbc203c1 +2023,54cf9b886469fde6 +2024,8d8ce887f008e2c8 +2025,3b7c482258df0782 +2026,49c6294ae2cfd961 +2027,7ec1947aa78c7717 +2028,e950018446e362c7 +2029,b54997bb116bfd0f +2030,37dac7381057ad10 +2031,3911b6d2c1dd8462 +2032,83d638c677cf35b2 +2033,19260d9ba91aed8a +2034,600c25112f9a87b1 +2035,0b68d34e4d95a620 +2036,8ceeab50acded3c7 +2037,71e9c80a5169ba33 +2038,aa7be51b0aed37b0 +2039,81c2b199c93cadd1 +2040,239540dc51850c34 +2041,ed08b725726b12b4 +2042,1c2c4ded301ddad7 +2043,95bb5531177a5c8f +2044,64545be17221c1fa +2045,99b2b8cecc1c6cdf +2046,cab01827de31b307 +2047,7933e41316c6ba8b +2048,0d766ba50fa43669 +2049,a57caa3ab354c129 +2050,0ba5ee790c5248f3 +2051,7b10b1a3005ee9b6 +2052,bc781c1b9367fc92 +2053,6b089cf386e3d582 +2054,94e41b952a7e6228 +2055,da6ee8a5fad0d9c3 +2056,5251c0f140ec8242 +2057,3227847554a0872d +2058,bea60230035f0198 +2059,1ee4370692b794f1 +2060,8ffd492d2b0310cf +2061,78ed9770767094c0 +2062,968685d490639068 +2063,1d0eb9cc8e2212d9 +2064,47d50395c754d5b0 +2065,c67f19e469aa6e6e +2066,1946a5e8599d1c1c +2067,9b778472954d0f3e +2068,2baf2cf5f9a20192 +2069,f643b59d098c513e +2070,05858538a8c8cc31 +2071,77c83d79f1bcbeea +2072,389e296a6490493b +2073,778bd25b60b06b4a +2074,f54692f5d66fddea +2075,391c06f683637cd8 +2076,00f6724801e14315 +2077,b87283bc03058edd +2078,eb0d566aa2fffe76 +2079,456be3de19e3f1eb +2080,abb6e76a637b9e68 +2081,cbc2519d4e5d71da +2082,9b83f4cabd851807 +2083,13b5f283f97f60fd +2084,b5e1aaf4f00561c3 +2085,580ac26a51c579d9 +2086,9d3a8c401a19ac68 +2087,8123caf64fb3c567 +2088,73e0fc6cfbb9c68b +2089,18f0ceeafc5e9cb3 +2090,105891cd9506d53c +2091,84dacb470ac860da +2092,2c342b58c3049144 +2093,d7efd4a9b288ddd4 +2094,f28fb0fbd71aadf4 +2095,6baea16d910b2ef5 +2096,59f85f3e7de84784 +2097,6d837f6c9e485236 +2098,19463f0cdeff7edd +2099,f45e0b5036ae36c3 +2100,b1e86913a6a9e45b +2101,3f72a48e545a23dc +2102,d4464b0237277011 +2103,980f7c4e2fd73817 +2104,7320355173753fed +2105,4bccdda034f581ee +2106,879b8e45fef81ed3 +2107,7946e253790c213a +2108,6f365717267ddf49 +2109,04c9e54e1e5798cf +2110,bb6525ec73322313 +2111,2bea701f5be8efb6 +2112,319280b6cf12129d +2113,4c1ce89625e7e2ec +2114,3e4c6c9afe4990aa +2115,72f10ada08220a92 +2116,6772e2709d8f4bda +2117,d00c3ae55ecab468 +2118,b08698ffbbe24e44 +2119,56c0cc91861db56d +2120,ceb5db6fd7feaf86 +2121,e9821b6ec77749f7 +2122,9881ce2848e6b917 +2123,0d48be387e11cde8 +2124,9386ce5f6ed33ed8 +2125,8af4f6c14b040990 +2126,b1be3579f0148eb6 +2127,373edb0cf1f0e16b +2128,176f2a23f41004ee +2129,4fa933323987937d +2130,31fe3a06f8f9a9d8 +2131,84690dfb94da845c +2132,bbf2f7eebbc52910 +2133,f3263ea776f3333d +2134,2dd4442bc68c6137 +2135,a8c3a1537b811653 +2136,59086d5f7d9efc66 +2137,d57788446ce3aa90 +2138,f8aa6584b4bb001f +2139,b5e7b974e0b220c3 +2140,b98d44d92919b494 +2141,aa5116ef6f750d72 +2142,1af84b284836a9bc +2143,aa8d423057268524 +2144,e31696c84c63892f +2145,57ec157425eb47a6 +2146,f138b81707f93ee4 +2147,d7545fd8b67da1ee +2148,27beb01c60d6d8fc +2149,169484eedc6f7b8f +2150,33eb6240aa41f85b +2151,ef5bf1d3485d59c3 +2152,b8855c2e2f719315 +2153,d9a6d61cf9cbad96 +2154,b61300c1c2ca8c8a +2155,e73318a7a8806afa +2156,82dff3a428fb2a98 +2157,9006dc48f13fe1d8 +2158,0f160701dd2e4a13 +2159,d7a331a33ee18988 +2160,5f14381c043669d3 +2161,ca6e862b353aa4bf +2162,55f56dfa8c53734a +2163,b1e1819c5ae39fb9 +2164,e218ec2e68c64ca4 +2165,541ad101045d42b4 +2166,c3c25b1b99e95942 +2167,f7dcf488ac6b8115 +2168,92c7582c09a6b0ea +2169,d2c629c2fa2cdb5f +2170,faab09ba9f0d837e +2171,a7452cfbac2c4686 +2172,30363278c8ebf5c2 +2173,7543b809041a63ca +2174,726ec21d9f66da14 +2175,9e2edf44ed9bcb6a +2176,c38480c5234cd496 +2177,9512924db93592d9 +2178,89c9fb6556cbdcae +2179,a82702ba438f5d81 +2180,a90108983eae0ab1 +2181,494d727b8d22978a +2182,d5d2cb6e19dffcd4 +2183,4ad8f94623786136 +2184,951e985d7ab6b15f +2185,c33c4cd3b15af703 +2186,f645644e177fa0c6 +2187,98a58dc4a40ad40b +2188,8ce69606d818e0b0 +2189,bd6a1e4449525416 +2190,ed79986f92954720 +2191,b000e20401bd982d +2192,f54d4f006b2ea765 +2193,bebc85e0c6ebf6f2 +2194,8e61651331cda41b +2195,f15091903ced4b98 +2196,30ca7e132aa9baf8 +2197,f03a00eab6ff329b +2198,e45e8a19bcb3d895 +2199,ac6233166dbb8ac1 +2200,bea5116d80fec35c +2201,fd8528881e8ce6a6 +2202,3dc9da9b70f2f7d0 +2203,9d46f32c0f7a6799 +2204,66c649aa60ac7b7c +2205,b0b43c666ef21767 +2206,0d004b5dd60d91f7 +2207,1ad1b67def78b137 +2208,2650586de6a53271 +2209,94c2d06b76d98799 +2210,944050e53af8350a +2211,f54bb8e1784142f5 +2212,8968f369fc7b3d67 +2213,0870682f5a848163 +2214,a7c9239c10035902 +2215,9744e2c878e4a934 +2216,a0c0828f865b3477 +2217,5b00e6a0a0d52aff +2218,7cf40a210c431085 +2219,58de38d75bc7554f +2220,19d1fd85166cd0f2 +2221,8c455d8035c5826c +2222,632e1eedcd7bc8d9 +2223,ef4800cae192f02c +2224,49308a6a381f133f +2225,18405d9014b3d817 +2226,f83f74430313c307 +2227,b54878c71899373d +2228,e0d0cf7e05b951a9 +2229,ba3e345f61d199af +2230,d50bb19502a851e7 +2231,75761a9cbfecbef3 +2232,47af6d0ba7af3952 +2233,b61f5c854b595be6 +2234,5c3ca9a555279fe0 +2235,fac628d126f111db +2236,c3310d37372d5dca +2237,4cce4e58be4b992c +2238,623823f9b3979110 +2239,a240992c385ebc55 +2240,920086df5c31a8ed +2241,0725b89d9910d72f +2242,355480b929200e1d +2243,4aff27988cd108e6 +2244,2fd471ea1dc2a442 +2245,a5ca4d5077ff8250 +2246,316d51a0301e924a +2247,05dd1d387cc1cf30 +2248,0535d53840ed55c0 +2249,0d15519118996218 +2250,fcb207fc508b571b +2251,71376298f11d0d91 +2252,467711983b12d3ab +2253,ce3e78010593f036 +2254,6fbc999de05dfa40 +2255,845016d1acecac3a +2256,f32bce744b2acc1b +2257,f329255ff661013d +2258,283650a1c08797ec +2259,284139bd0934aeed +2260,36e9077991f4364b +2261,ad14def0be828c87 +2262,b054d1888cc405fd +2263,e962add395620caa +2264,29579c8a7d29d792 +2265,e3d47a0529fc259f +2266,29d0f6620bf4809c +2267,55396c89b4d03af7 +2268,f247396149b700ec +2269,21e8b60bbc30b7ff +2270,ebfcff9e1fd8fdbd +2271,855e8cb16f20fcf2 +2272,31365f40c1c471cd +2273,76afdeef70a38016 +2274,894db0d2f13f89fb +2275,d769ca291babe9b5 +2276,252fec944db5928a +2277,2097758e973d5f57 +2278,33a3746811d21ad4 +2279,939dcf6d674345a2 +2280,d9f89373bf469ab1 +2281,57b860157b747d7d +2282,1cd455426778bbbd +2283,3de7967861b6ceb9 +2284,11804e316bf67628 +2285,5b8bd892970abe48 +2286,5dab1b329e9ae1e3 +2287,4780ea5a59a908f2 +2288,953ac21d77afc95f +2289,4506234117925814 +2290,3522ed20ddb4017c +2291,f90f462b7ea839c2 +2292,e1fd1d8933d78c23 +2293,bf0d5c20e9244a46 +2294,babb0a51df08a196 +2295,5382b39a5f889467 +2296,80f3751a14036ee0 +2297,98dce92448795302 +2298,2de4c4ccf041d935 +2299,8489a1791f00724a +2300,c7b1dc84b68b80be +2301,369b5d9e7931462c +2302,8db0413489960769 +2303,981273567c5c05fa +2304,96ea14f61b6f2132 +2305,5b81243f601ff382 +2306,2b391f1657c26385 +2307,82909d21a8e18b1d +2308,22bc9cbbc240a371 +2309,0cccb25fee72ebcf +2310,870369be92fab00d +2311,14538f957b4513fa +2312,74606f0a74c89410 +2313,0f903c5865bf4fd3 +2314,f8d646ab52d139c8 +2315,84ca32df8513deac +2316,516a720f2082c66a +2317,deba991de726b389 +2318,4c49ea1dfde9dfaf +2319,fbaa04f83b9375bb +2320,768aa3eacf54a108 +2321,c68daa7795264fe4 +2322,f6152cdc84c2dddb +2323,19cbe55ae2a080d7 +2324,9f381fa1e97a8f7b +2325,9911ab309c7a9bfd +2326,fbb3eb9296ca4fb8 +2327,d82b97e3029d4d90 +2328,ab5bff890aaaaf19 +2329,881037729a274ec5 +2330,b209479467c999d1 +2331,635f9488a34b8764 +2332,2b2c179f546a1573 +2333,d4c41060c6145bd2 +2334,44e6faa2c267a854 +2335,93a0ba47f193eedf +2336,72cae1559c7e57e7 +2337,d8fd5d641c292a1e +2338,eb0946bfd5c4939b +2339,0ae35d9d3e27f9f7 +2340,c963ddb06e48be02 +2341,f504c92820a7b74f +2342,8845b30dfca37825 +2343,b0613c6caa54b9e5 +2344,3f4273e90243079d +2345,0857e4c44012cc66 +2346,f28ae338d2f40047 +2347,5a8399344190a04e +2348,70ba8a42679855f7 +2349,4fb6bad40d39a695 +2350,ec0a09adedd28e9d +2351,053a94fe42d13fd4 +2352,fd93541a2dc601c2 +2353,b72d756aec9e0e66 +2354,009b2e44bae051d2 +2355,6c2519f99942b772 +2356,3c74ab8a5fa32f55 +2357,9a71a181610e4914 +2358,95c0dac1da405654 +2359,ee883fc7725999c7 +2360,4289a1adeaa2937b +2361,c65d015308b5dbcc +2362,dd910bd6d2288450 +2363,f87acf92ef25584f +2364,f0dbbc405c0ed427 +2365,a6d09e84e9566fac +2366,c2140a05e757da34 +2367,1f80ae3eb6388bd8 +2368,3d27937903176d27 +2369,6bdf341b6946cdc5 +2370,1912d34ca6207f8a +2371,99a5eff3ce4b2e49 +2372,287afb3154dfdd40 +2373,3007d99cc6bc12db +2374,472a78257424f38c +2375,8c0e13d480f6e1f9 +2376,afab659c2408ee2b +2377,c93e80def59db737 +2378,f66163f43d1d5e6a +2379,3670229bee1a74e8 +2380,e1408e8a4ee2a702 +2381,5257669d6a8fa578 +2382,7eaa72c680067ef5 +2383,708014b92a854c78 +2384,a00dc1823469795f +2385,1b078bb77eb560a7 +2386,c77ad5ae30be15cd +2387,6c83b74048bb9251 +2388,70bf4a7417ebff1d +2389,8c76e01d7a4f3073 +2390,5dbef111ea652512 +2391,83b27d937cb27e4d +2392,32390d32e72e438b +2393,836122fb2cadfa35 +2394,448f2645e1322ef1 +2395,4bc142a75a251270 +2396,af334efc590d5306 +2397,3f21ee0628f363e8 +2398,3ec9f5dcd74ee8e5 +2399,b12861b2054a5339 +2400,6db3d8487a08d9c8 +2401,1622bb343ca0ffa6 +2402,1b58473b9adc9b3b +2403,0297d671804517c0 +2404,5f2b659b31f48c9e +2405,e81fa3bcca54914d +2406,c06999648b801792 +2407,e03824c0729a5624 +2408,451a0bf9440ad4e4 +2409,d908aee4c9139811 +2410,68137bbec5abf9c6 +2411,996c71e7a11182a9 +2412,ce1336238fb7dd59 +2413,598755707fd88593 +2414,7482f07617521998 +2415,0ad23892d9762bfe +2416,679f2ecea24ea2f8 +2417,2bbdac945605edb6 +2418,6e72e607f3054320 +2419,30d2c302726faedd +2420,412f4b69daa4f3ea +2421,dbeb0c1da7507edf +2422,2717dc6659d9d54c +2423,628c872288add50b +2424,1011a0e884880174 +2425,5c154b66b49f7ef6 +2426,959bcd1a5754dd1f +2427,680485c1c3925d59 +2428,019e76e5f9b7683e +2429,4a812263a08e14e8 +2430,34761aff94ffb9e2 +2431,cfeff97f9c3ac3ae +2432,dd1a8acaaf7a769f +2433,960ec264f6670e4f +2434,7766e870fdee98b0 +2435,62481776eb70bd40 +2436,97ae3dd7e831622f +2437,70bf41731d1b258d +2438,30fdc64ac1a8a86b +2439,ee712d9fea3e803b +2440,00c95d97164a795e +2441,cc62ba5ee3371261 +2442,78a430472e8c0c08 +2443,708d31de0110807b +2444,d1a5e83a90b1ccc7 +2445,fca415ee4e35378b +2446,902c33584adaed3e +2447,269f21f20c797a02 +2448,2e62111bb6bf30d9 +2449,d6ea951cac6a64c6 +2450,279065107f32a6c5 +2451,659a34aa8b848cec +2452,fed65dabeeb8a270 +2453,fa839b55a1e2b3df +2454,8f029e529bd0d758 +2455,27beb047ac882ae8 +2456,dd444e58866f346f +2457,84bf832b92c31f10 +2458,555f7b9898d93b39 +2459,22401bb868b5ba34 +2460,86178de73a1c05a4 +2461,4664e81b120e1089 +2462,637f94c344fdd2b7 +2463,3472fbe287c539c7 +2464,63f2ab4606b73d9c +2465,491da64c70356cb9 +2466,f5c31750212fd8f5 +2467,011e8b390822ed25 +2468,d8724d8b553f824a +2469,df70b34776bd8ecd +2470,8531e8f056c84fc7 +2471,c3ce2febd3018b02 +2472,e85b8bf8ade32489 +2473,cf2837902bf6cacc +2474,953a6762df3400ac +2475,c735fda9248cc465 +2476,e176d9bacfe14b26 +2477,9fbd512c51bd0f7d +2478,5006fe720a7c8b31 +2479,f589633c18a6aeb8 +2480,86318424e2ff8aad +2481,cc3db5844ba6cf72 +2482,bae6ef501c26f9f6 +2483,92446f1555975e35 +2484,3e8e01117c68a4fe +2485,9699113170b1e161 +2486,4a1dd0c3773f698f +2487,5b1e6d9a3bdee15f +2488,661ffb9f52a8f695 +2489,ea2d878ac0bd84f9 +2490,ec0d929dacc8f0b6 +2491,2ad009533d16ff3f +2492,33d1174db10d0545 +2493,54bba38673174e32 +2494,28aabcce6b01db5c +2495,6cece06276533e9d +2496,2ba486fbc0a0f867 +2497,a0f9563659630ad4 +2498,9d1debf9099d6667 +2499,e6a90cb37c2a28e1 +2500,13a2ab86272d1b9f +2501,d01603cb62a5f740 +2502,80ea45b7a9a3bded +2503,4c7e013b09036967 +2504,b5073324647a093f +2505,d64d4454f0ba00ec +2506,d6b2760db41c6d6c +2507,e58af038820679df +2508,9df332ffd15e6966 +2509,c63b12cc052d9989 +2510,7ebbcb81fa9daed5 +2511,8904bb47f1fe6c74 +2512,ae312c965fab999f +2513,32248a60568c14c5 +2514,7460abfb5446e2b7 +2515,3304e1709f814551 +2516,1d977638deb7a735 +2517,8ac995de879581a4 +2518,e4eccc1d34fb2558 +2519,702d91a528d49a90 +2520,9575f4353ca62a7e +2521,7f624f0ce3113115 +2522,5548efd169d81765 +2523,0b762e3dcdad5b1d +2524,4b54b92161efa6ef +2525,852dacb1178e062b +2526,94032c5f4e421849 +2527,1da4607a3db7da63 +2528,ca3fa58f5c5c9f1e +2529,8a4bafa7fb282f24 +2530,420c3abc2fced9a0 +2531,086cb46fc8aa0af3 +2532,b1fd07ec21a26473 +2533,661f9c41e0dc8371 +2534,b74773de6a3ae551 +2535,e5cdabc86f80c8f9 +2536,12d06d7065d20be7 +2537,e4f94b149d9278ea +2538,179a12b471a232eb +2539,57f0670beed1f73f +2540,e20ea7eec3fc3572 +2541,c83505ccaed7aec5 +2542,38dda04f5176b456 +2543,d2ba856a4548dcfc +2544,28342ae815bed1dc +2545,cd08d0140c92e09f +2546,40337bcb7ba37612 +2547,8288c45d2e03fdd3 +2548,fee4328c149e971e +2549,edbab25d1d02bcb1 +2550,cf0812a5679a5e7c +2551,69acc25e495455ce +2552,f9ad38beae523311 +2553,dbb5d3031f2b46ac +2554,d0822e78ebd3909b +2555,f6310592b0d77ad0 +2556,9b6f1752124b8f52 +2557,c3739d97c1eba820 +2558,c18e5992a4026aa0 +2559,8c0989d57537e430 +2560,a451a022595389e6 +2561,bb3aae5e6609a7b9 +2562,a59192da0fae3690 +2563,023e490964e74b3f +2564,18a538e5f968aedf +2565,f126d85266004dc1 +2566,e0a8ddfa793aaae7 +2567,8d5b36485083bb24 +2568,fbe351c427618868 +2569,2c9607599c451826 +2570,71e030c6e9bcb43b +2571,1b2584ceabf7f85f +2572,e71c96e14ca19dbb +2573,99944cd879b26563 +2574,a39fea6ec436530c +2575,9d8a993c7b9c04b2 +2576,a9c92933ea095e8a +2577,43aa2c671dc7a97d +2578,7eb12f86f50af43b +2579,6166699dc75ae738 +2580,adf93e8ea6cc49c8 +2581,cc7d70e96bc29d2f +2582,aad98c01f2da2ba0 +2583,8cb3cf3f11beaa38 +2584,165476d453cbc4bc +2585,e11f5f82f670f8ee +2586,d432ee4ff6c06022 +2587,dc6b89cb31d55515 +2588,43e76445191a36ce +2589,06856711fd869169 +2590,59e14987c1ee41b0 +2591,02cbb41c818af068 +2592,93329700ccbd01c6 +2593,0b6b67208b7b2054 +2594,68faaebdce7b5f57 +2595,f719c81710fc0fad +2596,ec183d968ba32b32 +2597,ffb07cd4a1cdfe63 +2598,73cab08a77a93ce2 +2599,52b6e6112b357ca7 +2600,96291163788c8f01 +2601,26a53118913f6f1d +2602,ace03d236ee42c40 +2603,2e9d35a8ca252dfa +2604,a655890022007bd9 +2605,8396d6360577aa6a +2606,1d440dcea926f525 +2607,3548d22b8bbf7627 +2608,79947f51eeee4c1a +2609,a616f64edeb58981 +2610,03ca29e86a46740a +2611,54a8ab48023ac470 +2612,2822d2b9dc3c4011 +2613,1600dddb3f4390b5 +2614,adaf4c65dca2c58c +2615,12c74534106b3071 +2616,b39d5ee5fdc18b40 +2617,a217213992f44f65 +2618,8de75ecce0fdd232 +2619,9f904b36e746cc1b +2620,33a85188c92fe387 +2621,aa3fa108cf72d970 +2622,2c5a84f2f0a283ab +2623,283bcc4e2472eefc +2624,e6ce9d406139473a +2625,d31deaf7404c9582 +2626,c953bdf70c5f6cf5 +2627,a3d0d07a3a5b7ed5 +2628,45546ceb255499f8 +2629,cb81165cb6500278 +2630,736744506a9d7177 +2631,b6960aa3ac84bb79 +2632,3e809d5dd0ab4495 +2633,ae1ed9baa289c1b7 +2634,605650acd925814c +2635,f71542b761a11600 +2636,7bcbc5016e801d7d +2637,8487db8c99dfed88 +2638,71d5328fdd2f755f +2639,1e9e95bec48004c2 +2640,ab4d81e65253787d +2641,c7cf620f58b5d93f +2642,8f1b3b1b44d64866 +2643,b77ba3ca3f0a6088 +2644,59b24b016be0ada5 +2645,90e11559f267d53b +2646,ff9a0770c74d277b +2647,0f264abf939a00b8 +2648,a84769283cdbee55 +2649,60f10134a65e51e0 +2650,432386b4bc64538a +2651,93b68e72fcd9f4e4 +2652,3b13c018b77b08c4 +2653,7836ba64ac6635d0 +2654,6f86b83eb2703a68 +2655,74fa30ad228b650c +2656,75f6a86926b97719 +2657,057060d91ef1a537 +2658,437b5ebc9b997168 +2659,0b4487c236ef404e +2660,7f4840e5c4449f5a +2661,2cc31774bd629834 +2662,f55b0c6078a0848b +2663,dd7bfd716045236c +2664,cb0262be85460707 +2665,c6424d220a3fbd12 +2666,e173d76c85c3e4ca +2667,a6c468de0e4b4a1d +2668,192408b0218f7db1 +2669,6366bc5d7e1017ea +2670,154355c6bd7caaba +2671,88cc0b40182a4a4d +2672,9b49ef5b4a39f586 +2673,a1050f39999fd4ba +2674,3b7bf2d3d2ea5a2d +2675,fc5a273395b93546 +2676,66dfbb13b48a8a06 +2677,904e865c44a53aaf +2678,9f3336ae7345bb69 +2679,9a389ea9b70797bf +2680,d2d47ad6f946a352 +2681,5c43b35222dff5da +2682,6850ddf3daf07939 +2683,6887e7005a508d36 +2684,f8318a0ac0e0c738 +2685,09485f41e6515c6d +2686,ac7d6016665c166e +2687,32e5d895f2449561 +2688,8061d57daf6c1482 +2689,d43706092755fc78 +2690,cb94949069c141a4 +2691,a1e10fb7770f497d +2692,543a1925f1c88cfe +2693,f8cf2c60bf039b18 +2694,8c85d0971bc5f674 +2695,85fd22fa5d7b11e9 +2696,9e632ac4820f70d0 +2697,09947dc25278cd5b +2698,33a05d2de0c82b98 +2699,a0ad6e297a17013a +2700,177fa747028f53a2 +2701,7fdeeb67122b020c +2702,890966083be86b18 +2703,253fa425500c8288 +2704,49eca5bcf229021a +2705,a2f1da2c05e48522 +2706,528daed27ff64e46 +2707,326694da79bb136a +2708,87a48fbb1f47fae0 +2709,b811ff650106fec9 +2710,b4fa9411a648608b +2711,56ccf6b5d9cbe3d3 +2712,394926827f7e7783 +2713,05663b0c5c0cc52b +2714,e070d5a2a2ba8c6c +2715,64eca523ba18d225 +2716,8b1521563c4343bb +2717,71e994fc0ab8f4a4 +2718,af807371cf76e54d +2719,67a04abf157e6fb8 +2720,6980c5443e1da7fc +2721,58bcd0f9d30287ed +2722,3d8c90f10064500c +2723,154e6406a365c80d +2724,1e508076108c20a0 +2725,d1141d97f0420c54 +2726,ad7342c87de4ead5 +2727,418afd6a333f2415 +2728,9cffd027aaa5c78b +2729,2c2e68bd9d308801 +2730,7e0dec1c84c82d80 +2731,e428d82e02bda773 +2732,d0a52fc7ac34c538 +2733,6058592db554a7be +2734,524a361b18c0b104 +2735,8cd706614ed00f03 +2736,5962f320396536b2 +2737,664d7d3f833c6f46 +2738,f21df5992aa6a04f +2739,008c0ef51bef520c +2740,176d462144d28dac +2741,091f239f1244b909 +2742,62688737059619e7 +2743,5f7c385c52d48f8a +2744,39ffbd9437c86b39 +2745,6e8b6cc530cddc16 +2746,b19f0913c2619d10 +2747,206002f492665f74 +2748,ecd2b334e0d0e6fd +2749,06cb87a424341fb1 +2750,87c9213f188e5d0c +2751,46901d44d89f3640 +2752,1dee024a6d1c0465 +2753,73b27f1ffac33666 +2754,ce74cfe5b9d46665 +2755,397d2e3f69a00125 +2756,74c831c7a66b8059 +2757,8bf8c21234f8e66c +2758,8be5ee02f3eaf000 +2759,e3b6deac53411aea +2760,2d9ce6ec147ce5fe +2761,b79bc933b6248843 +2762,7a7268c78e4479b3 +2763,dd4c204c09cd08ce +2764,ae727875be810988 +2765,6e90a540a6f3676d +2766,5f847fa9c05006ec +2767,447d1ef8910e0b82 +2768,c8b8c1f8c4f552e2 +2769,178de5db10916642 +2770,d6642726e2bee1ec +2771,f970e12e5a0710dd +2772,248a9730bfd22c45 +2773,23277019595a22ee +2774,5e917fbc43d0b5c5 +2775,27284f6b78e4a2ce +2776,7ecaa25e847fc527 +2777,fadb5aa3a2e86922 +2778,082b730c4e2f53bb +2779,b8f2b4ff84eb3fa2 +2780,d30463b05cb92110 +2781,ec4aaa96c5ab0677 +2782,bb52f60cb73caa3b +2783,11bbc05502ecd3d1 +2784,15f457beb21dc4ad +2785,0b0ca4fb24b37c2d +2786,f6e97054655e00a0 +2787,f1191841b158610f +2788,e35de94b66437fbd +2789,63741f780cc91c85 +2790,db954491a24b1e2a +2791,c8154f14e20e1c58 +2792,e9b6484fda427b2c +2793,e4970d54a6641440 +2794,4f1be2f9b5fae7e9 +2795,011c2ad8390cdcce +2796,c2fe4d577b4a7da5 +2797,e8ce9b0d80b4fa4f +2798,7619c1c6c35b724b +2799,f8563972a293f388 +2800,ee901577bf7fcce9 +2801,4f6c63c20cd4897a +2802,9897d16ef9f451d5 +2803,6da382217f9f58e2 +2804,52b606f1512bccd1 +2805,d4330bab6a3e12ba +2806,b9da59f28e8e48f2 +2807,4ce5629b8e2c70dd +2808,0f529bab043832a1 +2809,23f3185ba9713b68 +2810,8fc387a8a9b0c54b +2811,57c13d2656d72257 +2812,b94a820bc56e6148 +2813,ad2d3d69cf7aeb86 +2814,c519bd48bc1c6586 +2815,e3e1fd8bed0ab45c +2816,a582ce30c519a73d +2817,c76e85043ea42d00 +2818,8c6cd0060349dd63 +2819,255f9f0843837353 +2820,d8c92c3dc3158a0a +2821,7f38187621c91ec1 +2822,d13d5b430c192a22 +2823,f464765c58fd8460 +2824,3e297a4e5eaf3f5a +2825,31df558226ad5dcb +2826,0dc24e0b8c144029 +2827,9dc1d77c94c645ac +2828,83e13f045767156b +2829,b60cc56de5323f5e +2830,c68e477590453f2a +2831,7f3621732d4bb0e9 +2832,346a404564885325 +2833,1c0513ad4ffb54f3 +2834,f3be52115b82db83 +2835,b32ee9db83e91cba +2836,7326825d9dee5ca5 +2837,38ad1744f674fab8 +2838,78aafa2cf12f1950 +2839,a8603a8fc43c3a91 +2840,e757a60ed5b750d1 +2841,b9ee68888c437bcf +2842,444276107be95869 +2843,52f3107a07d3f479 +2844,8ea49603cb51f7fa +2845,cdc9aed76894631e +2846,a171b223eecb2bd7 +2847,c04d60628eef9e06 +2848,d234a5ae8caedfb6 +2849,728086fee5f4a8a1 +2850,86f327448441483f +2851,861e8e4b31dbbc86 +2852,14625953bb3b8798 +2853,61dfad655af6e233 +2854,312ff61cd05b75a8 +2855,92de2476c1ad83ca +2856,98360a495d5a5373 +2857,9cf670a6959c40dd +2858,27e43d7271a3f5e8 +2859,9c52bd78ad0cbd7b +2860,4fcde1b37a5f5169 +2861,99c40b5d47405ef6 +2862,6b0d35e7ac4e587a +2863,2d8c16d770886aae +2864,72477b3a80fa47a8 +2865,3be58e6bee3e2885 +2866,7b4254558e118a8c +2867,1b7de30ca6433bdc +2868,2c3ce4addb370eb1 +2869,222d296f1bcb46c9 +2870,29c58e8795167e22 +2871,1bd109475977c344 +2872,59bee339bba48263 +2873,de7af510fdbe1399 +2874,d01aabe169a2f550 +2875,d57e6a35653b07f1 +2876,030b91bd9df1ebca +2877,a1eb5d6cc5bd477e +2878,5af67a7d2d1e9859 +2879,af23472127ad1f30 +2880,a72f9b5c61e5fc88 +2881,e6f3a1326e5c5ddf +2882,6609449b0047772f +2883,bb030dc431cfc4ea +2884,d8e63bdd113947f1 +2885,ddda91c38ccc901e +2886,e9d59982cbac5acd +2887,19d03e007c912b3d +2888,563f6bd47296ee7e +2889,0a2b0b9c8ae18ab5 +2890,4157ede397175309 +2891,9b81680a314eafd3 +2892,5876be9639446c50 +2893,667d3957420436d9 +2894,b0117b5601aa880a +2895,8188c6963f2378b0 +2896,0f2e2ed20f97c391 +2897,e9283032b075b6a6 +2898,83e4b9dab2bc9642 +2899,79b3165d57aeb442 +2900,1d2fd4bab8f78eb4 +2901,cb01b1bc011df3cd +2902,2493027cecd05913 +2903,1d2ba5320f967ecf +2904,6fc7b293fd94d5a3 +2905,97eaf934581e856a +2906,e103173270b755dd +2907,56ae84bd739b95d3 +2908,7dfcc307976242d4 +2909,1c2af98e1a632360 +2910,0ac79957e168a51c +2911,9b4189e50cf45d73 +2912,18a753ae572e246d +2913,6f0be1e2e76403ac +2914,97ba6c98cb931b90 +2915,7a331fd1521f9965 +2916,6fd62616075d7018 +2917,4146344788d81eb0 +2918,77d0da03af0c1e61 +2919,79c07c5f03ceddbd +2920,8f05829b965a4184 +2921,880bfb6a67304627 +2922,a6ace92bfad04ddb +2923,9807e57850604530 +2924,50e08cf8be591cad +2925,101f197fac963de3 +2926,295531b62e6d7294 +2927,a9d09d61af943a82 +2928,8a507cd1f44ba8c4 +2929,5b08f3661267f8ac +2930,b85bf0371021ea02 +2931,e9e16a7d77ba60b0 +2932,4104445ba0b6073d +2933,ded6d302fd915a24 +2934,8ae3f635d6cea486 +2935,530124af4954cbfd +2936,35646d3a13035514 +2937,0eeda8ae3ad38bc9 +2938,3de333cb7432a4f7 +2939,05bc6523841531ef +2940,32ae7616d231e514 +2941,2ef18d3c3a72fcac +2942,ce780ba75f57027e +2943,9698a10c0af30b0a +2944,33462445bc2acd6d +2945,538b9cd22bec1021 +2946,66068271d17fff3f +2947,3b435cff3f993fc8 +2948,df90ff50797125e7 +2949,72a4baeb71dd687b +2950,e4a14e4ff7caa1fe +2951,10034cecd28e18a1 +2952,b3fe3b2f1d4cde45 +2953,d28cb93246568778 +2954,52885df8eec8dd8c +2955,770d02b61554506f +2956,347cce7b0c5f322c +2957,6b7d8fabc824a274 +2958,1c05aad2e730b55d +2959,9b9079d9d92f848b +2960,e077b36333093f60 +2961,38b14172fc8e074c +2962,6c6e437a5110871a +2963,0ea73814549a60f5 +2964,c748f0dc1a9d97c9 +2965,df4e771976688b60 +2966,5d6117891fc08faa +2967,1a9f9c872387caea +2968,25744692f8406014 +2969,a07c52bffaa3cdc9 +2970,aad6531ecadd8907 +2971,fee86a1098c88bca +2972,4aa780a6fda58653 +2973,00663709ad236839 +2974,59c62d3c1acfd5f4 +2975,5d88a138ab7a6138 +2976,0ca31aae0cb2e5aa +2977,6d4424546a49afea +2978,8dd3517db974afcb +2979,994c0764c06129fc +2980,4482d4eee18d1c3b +2981,c4ecf1c9c57f7a43 +2982,293396e082698e1d +2983,7a93f10a8bef9bd2 +2984,7222f27593917fd6 +2985,62e1b4004f451191 +2986,667029094ae0c91c +2987,c870bc77295b7320 +2988,08f4fc2dd4e39a96 +2989,12bded4a7fb7537a +2990,dee73ccdb960006d +2991,49118b552811afb5 +2992,f7e9dd1c68ddb0e2 +2993,02300b9eeefc8dff +2994,dec73c4b132585fc +2995,926705cb26abdb83 +2996,36afb60878bf262b +2997,6f6b673d4b987292 +2998,2591b6fcc56fcdc9 +2999,fcf241a89fd4902f +3000,90c7da591db7b882 +3001,b79c8c5955ca4468 +3002,eeadd5d6c5623010 +3003,da91c3acbd340b19 +3004,5791a603beb1765e +3005,253c7abd4b9c3eaa +3006,0d82f7776161a372 +3007,b44565530f422775 +3008,30ca3e6afe34be8d +3009,c8f1dfd76002eb40 +3010,beb0990b1635ab83 +3011,69c0907f65b42edd +3012,bae713af3e89ee91 +3013,e12f3b0fb3d63d77 +3014,25405b303695086f +3015,e62baac015f85eef +3016,feaa5ac66bb5ce9c +3017,97b04591394ae3f3 +3018,b5f869f8e9763b6d +3019,22f5be474b50478a +3020,03fa5252d8510e7a +3021,e127f6b6777c1c1a +3022,0e20836cf06d19cf +3023,9b56ba34ac503543 +3024,009ebd1415ed9515 +3025,ad46ddde610031c0 +3026,9bb2c7959442f111 +3027,fa146805447e3523 +3028,bfb676d454a4e348 +3029,d9998a4179de46b8 +3030,5b9f9a5514ace051 +3031,ac7a255e0cbe0fef +3032,5f40e05f9295295f +3033,f8bee8d93ee92fcb +3034,aaed9cd31b4bff18 +3035,205e211573b28eff +3036,d1eeee9312df9597 +3037,69d4de89c554820f +3038,b63cee67d3bbb640 +3039,060bdfc3cec710db +3040,011bc61a67a30dd5 +3041,8b24add0b58b9d30 +3042,47ba91d0a6b29042 +3043,6eae0908cad49fb4 +3044,825c2d37e205548c +3045,23deb833f7ea8826 +3046,d0fd94d65f95cc39 +3047,1ec1f9a055a7dbc8 +3048,2d59eb65a3261359 +3049,bff3b1f6e04df86a +3050,8fa383ebff2be044 +3051,f3e14fb1b38d81c1 +3052,1d48a1f5843ebed1 +3053,7e6b3379e38814e1 +3054,21c580a15cb8db7c +3055,a84725b9147763ba +3056,6cfe503b52347480 +3057,2a3ad9205a7b5e99 +3058,20dc22588f5f188d +3059,7e78732c6f6c8fd8 +3060,2801c04fbfb59314 +3061,5251fb7f25897808 +3062,d528aba391f6bd41 +3063,beebd32fed8e8c98 +3064,2039a0093dc52239 +3065,99d3f6e89effedfc +3066,a0b7889d22d5490e +3067,6ea1098deb6f6324 +3068,09609527e04f09ae +3069,2279106add217512 +3070,b10de63bc3b21f47 +3071,2eea7805f5f3aa89 +3072,841804b60fc56832 +3073,18c65c86ff1a8e39 +3074,9efad2cf060f0189 +3075,741c30905bf1c550 +3076,393c7269b437f9c3 +3077,baa84090c85f186d +3078,0650eeb0559c38ec +3079,e5b7c6ad87580a6d +3080,fd943afdd7e59c56 +3081,4a7c1d47e7aea15b +3082,6697a7b7bedd3be5 +3083,d4bcdac729f89624 +3084,4935805e04b33ffb +3085,86e312db9cef7e94 +3086,886ab1af35886294 +3087,f40416dca9551a31 +3088,4fd990bd1e49eabd +3089,04ddae862b7f033d +3090,425d435b20a74502 +3091,ef19836845d1d847 +3092,0b39b65becb3e186 +3093,459aa04650b3bb7e +3094,2c2f91556ba1a32d +3095,350d2f84f022cba1 +3096,a4693d2f4f1ce3c9 +3097,c020f92abfa0fd99 +3098,6b81fc26cb2afc09 +3099,471296312a8e9d23 +3100,f55c0d329659d84a +3101,9d4a50b8359d4521 +3102,0bc146e010aa7e11 +3103,47bf08b6e3d5f8db +3104,58332838f1f0afd2 +3105,9fb5aceed706cbd1 +3106,007c06b85b65db07 +3107,7c2e0a588e24765d +3108,2e98cdb294d8a2e7 +3109,81cc0b35d85e95d3 +3110,97022f374e96ed47 +3111,2ae9ee5d9e403bcf +3112,c2d16680715f42a7 +3113,f44f7f8de3424eef +3114,ee4cca79622d8e5e +3115,a7bed204863e0bc2 +3116,3f13150335ed837e +3117,c477cff50c0bb73c +3118,da44de7d9dc97616 +3119,5b84ac38a63c35c1 +3120,2784115ceb1f6c0a +3121,88933370758fe670 +3122,8f2162e80592c9c6 +3123,7772bc99a12dd423 +3124,cbdaa210cb2506e9 +3125,ee1a15ab510c4cba +3126,32f7759d213aa867 +3127,74d61f4b4ae57e06 +3128,b2fe47a51d2ff92c +3129,6e7ef95882023452 +3130,1fae0ca49980ccc5 +3131,f4acb676427196ed +3132,d6ef5eaf9d4904a4 +3133,f23f24a41d832adc +3134,2400f58e238fd6b5 +3135,f8c8f14af8c4aa8c +3136,f701c0a8590f423b +3137,b29b2b95162a711d +3138,17c707eff38e782a +3139,0a78adc2ec1b2285 +3140,5b670459ffd2f7c5 +3141,b59a43028631e571 +3142,79e2e143b3ecba1a +3143,dc2e85d11c805fb5 +3144,9d24ec49b2032ca4 +3145,3ae90650849100c2 +3146,9366c37cfaa101bc +3147,18559b3c4923dbd7 +3148,d126cf0e026306f4 +3149,07a7647746d7a89e +3150,5d8044d3b67317d6 +3151,5e96e112cc0284a5 +3152,ab77cc33d3c91f05 +3153,b820651cb27cf243 +3154,5b2d9be932f34609 +3155,d5ac714f01fefd63 +3156,7c0869901a735520 +3157,4e46c7d812d17955 +3158,307e317005f93e23 +3159,f1f59e05ae443035 +3160,c2b43bb0a7f0d6b4 +3161,0f66cf381f392473 +3162,3ee35504dffe5201 +3163,ff1d2b980f392ecf +3164,dc19a398d0b5fb9b +3165,cac9975f9bb3694c +3166,6a9b6ef3e7a4525d +3167,3a5f16ef8f5db631 +3168,588d5e70e0987f81 +3169,357637211548f59d +3170,3c89e240d715c480 +3171,3b90c77d835d53d1 +3172,5f1409e811c528e7 +3173,e5b941f24c430ffe +3174,dd725f8e690af9fc +3175,7103f1aa32981e5d +3176,b694fdf8cbea2d9e +3177,8601e6992b561f8e +3178,27cf6c64ef70c2e5 +3179,fde6f0836e4228eb +3180,13c321fe1b14840c +3181,41777a36032b2464 +3182,1686fcae94ba983a +3183,ba75f6edcf91bb30 +3184,e334c349ae130c53 +3185,3bcf9d5f60f442bf +3186,c837f68c18e3908d +3187,cbadedde931a529d +3188,719706e0fab15450 +3189,df81b3029088a4b2 +3190,ac3ec1924c917593 +3191,9798f3e5f07682bc +3192,0d6d09624c224ffc +3193,396628ccb12989cc +3194,dfc3ce0ac04dcfeb +3195,26c75b0008b76fad +3196,749a59521e0fae56 +3197,840c7873f13cfb17 +3198,3e491080de955edf +3199,f608823ede90e998 +3200,5c6c47c0d92a84c8 +3201,1f081e1b10766d81 +3202,d2216169bae246a8 +3203,1e942bdd2ada357c +3204,0b37f96608b0258e +3205,3568700ef3e26e77 +3206,09eb428da8bc0446 +3207,3c985f574277250e +3208,d03cb10542722462 +3209,0d9b289745b00b23 +3210,f6ae6365473721a2 +3211,a5eb5c5de81d7c02 +3212,2cff927516a73635 +3213,dda9e8a8ec6ee8b0 +3214,904459015f4e11db +3215,eb92a403da430509 +3216,2ede62148ae2af0b +3217,2e2f706885d1e5a6 +3218,a095400817d3cdc8 +3219,645fc2b3cb633ad9 +3220,2b00a8f1710cfd54 +3221,918f87d5c54a8add +3222,5ad2247ace965271 +3223,b5c0ffe0bd173eb4 +3224,cc2605819524aeb1 +3225,bae1014343d2005c +3226,8c3d8aa0301bc11c +3227,34047d876fb44948 +3228,84366cffcbcd29f1 +3229,ec6647a8ba058e31 +3230,4a4d59e5b2882e31 +3231,a8bb2b53cf92c661 +3232,b147271286f7e26c +3233,32470958cd5e23bd +3234,916af785b32cb40a +3235,1821ba0fde2a0867 +3236,a8f38cec7253fb92 +3237,04a4afd346d41ae0 +3238,9ee6c54ba14367a2 +3239,d408dd27ba9cc11e +3240,dea84d09b5946595 +3241,fc943b7fb5a1ceee +3242,3791fdf495a85e15 +3243,751afd4d193d3c99 +3244,69dfa28a7836f784 +3245,e5ac3cfd9b87623d +3246,03efd68fbe514b12 +3247,1c1186e04e9cf7e5 +3248,7e142897f8e933cb +3249,12ba95658a861dde +3250,16bf4c7d3af7eb82 +3251,5367a7fa19ba6d6c +3252,962dbd6d812b9df6 +3253,688fc0a4b6f252aa +3254,358a759bd8221162 +3255,e0f3f13ea5d26028 +3256,bc6525cae9cbd776 +3257,4090876525200ecb +3258,a17f5ca7b9daec02 +3259,220b2a922d6f6105 +3260,a03429d92322bf8f +3261,2246d6a71add356d +3262,4e852150a73099ef +3263,88a979f25165a743 +3264,4406f46259268e28 +3265,0f475ee3f76d217e +3266,31f24c98907fa63d +3267,d7a36516424a7834 +3268,ecd25c241aae7637 +3269,137cf65c2539e78f +3270,917a0b3e37fa8a69 +3271,d9599625324daa6d +3272,78ff24c6f1111ed9 +3273,d820875532a24cf3 +3274,8110dca3ea34106b +3275,15afd9dfb9f85260 +3276,f973e5efe4fb3d2f +3277,4c27f7376819548b +3278,216ee606a30d831a +3279,31e20a038793437c +3280,a7642801b89d88b4 +3281,22ee1b8f6891a7f6 +3282,498a044c6311063d +3283,e3e0d64bc177c9de +3284,3d1bfde453aad753 +3285,c5f7c8e81a43a1e5 +3286,0f8d2aeecc796046 +3287,e9040aeb1346b686 +3288,dbd71a15b9e9913c +3289,3577930a37e343dc +3290,714354ceeb7fc57b +3291,d2013a7b357ab892 +3292,df303c26a12fd440 +3293,53fee24ec2cb084f +3294,e79bc3d9352dbd03 +3295,6db9eaae553ec7e4 +3296,e41ff8503ba34899 +3297,4dcc385703283269 +3298,6ef03ce9655ea569 +3299,5fc94f83e9ab08ec +3300,558ecf36962ed742 +3301,4370435f6d516b1b +3302,a9df004fdc7e7fc7 +3303,1eb104d61189b1b0 +3304,8b6685e5b793b555 +3305,22d5fbc3945bf8e0 +3306,88c836712451148e +3307,6c5971fec70916ac +3308,dab42b82d96775b7 +3309,e651b262222b9a34 +3310,43a4d243fb8873d0 +3311,b1e844ece6bb21ed +3312,e4c2fbc81d459daf +3313,95ed40fe542524ab +3314,3df5499e1facf4f7 +3315,d1bf5197b61d27bc +3316,0ebc784d55beb797 +3317,e02de561f7789269 +3318,dddd4356f7d7ee3a +3319,4353e292516fb0e0 +3320,01afba00c5587e01 +3321,f1ef5bc87bc60699 +3322,69d615ffdad73935 +3323,5ba7ef9cea160b10 +3324,2d9d3db55327d21b +3325,e92531efc17ff9da +3326,a3d3494e90344112 +3327,51e27a0c548bb3e4 +3328,d095cfe48334bb13 +3329,a9afec5505e3a639 +3330,979efc544548c07c +3331,3409f79b87c6dc97 +3332,81f72d3cc2243d95 +3333,978914c923677384 +3334,3bf23f2872454b8b +3335,eff097a5684bd3ac +3336,7f2d6332cdde0a81 +3337,047cab08e44df5f6 +3338,ef6adc61e39faf20 +3339,3fe0d88c43ca0bc2 +3340,a9bdc288e4de90ce +3341,037545ef19cfb08f +3342,318bce3626d246ed +3343,c41ec30c3ec46c6e +3344,2ed571eee4e2ad72 +3345,561d3599bb6c042a +3346,7399064b3add02d8 +3347,0c0dfd68d049bc68 +3348,7baf665762bef028 +3349,55a737e70857cea1 +3350,f5de9c6c9b54f15d +3351,b2be4826f7e2b9ab +3352,3cbde76a7f99765b +3353,e9aa3ccf2fde9573 +3354,6541a39ed30974fb +3355,f978b13ebe04e519 +3356,8bea961dcb7b858c +3357,0c1c1cebeb80158e +3358,71cc6d86c25922c8 +3359,b3709c221a20ccc4 +3360,c1f1e999a0798614 +3361,fc1142d65f18cece +3362,437821c811866eef +3363,0ce865e44c10ff69 +3364,00b80910e5a4fa8b +3365,1a540e56652f34d3 +3366,1630dc0cd3de1018 +3367,a4e3b48f72d81a63 +3368,9aba8337741cd300 +3369,26cece4a8e583a35 +3370,49ca9c37c5e83881 +3371,77e6e997b3a27649 +3372,b65bc18ea4e83319 +3373,7b4683ccc86a7bed +3374,25bd3cc73692dc78 +3375,4dd7fb10b7f93d2c +3376,9c9557a6a2d3c945 +3377,aaafcf37b7b68720 +3378,8a258121f28b037e +3379,6d511b29a57b74b9 +3380,c7347d6b941652a1 +3381,897e04a75662136c +3382,bf0eb80f976c0e09 +3383,3858c5bcc8ccd100 +3384,11ed26ffaf13ad29 +3385,bb6f309096dd6165 +3386,919e7c1f09374c79 +3387,3226101e1cd55ff0 +3388,8fd3609ac2742d9d +3389,e9a6fbc9c37a33ca +3390,1672856247e881cb +3391,9dc3a2938a24dd37 +3392,5fecc5fe83768043 +3393,d1aea8ae3c62bf6f +3394,b9a1d293fab59470 +3395,20d479bfc2b46284 +3396,280266bfd8202ae8 +3397,134d50f648b1ec60 +3398,9666ebd97dad0512 +3399,fc35a46014d49ba5 +3400,3e82aa67f8d5f294 +3401,841e5ee5ec8bea63 +3402,790ca277344afa22 +3403,6068b0c3e94cdcc9 +3404,de6f46c2fbf805a5 +3405,aff841ab43f48cfb +3406,6f292776badc5c34 +3407,61927e04f66f1d69 +3408,1fd8800b1380c93b +3409,60f88b87393c6498 +3410,2d3d4341a237f753 +3411,7d787974ce3dc9d5 +3412,4b61ecacc9a16ffd +3413,499d060d9d8fabc9 +3414,df369de42c4aaef2 +3415,ac9b5c2677f2c3d2 +3416,dcba9a169e875cfb +3417,b28877197a9d4532 +3418,3cc140fa3e832bd8 +3419,ab9f36e3e6de34c4 +3420,c61b8762979f914d +3421,332e122eaef12ff6 +3422,e21e2aef1fef2089 +3423,c35e23731aabbd05 +3424,70e90097a2d827f1 +3425,a41ee0befba48dd4 +3426,f16a26e898f4a75c +3427,9fa912ff9a90e9a2 +3428,a8017cb9651844d1 +3429,c257e246a4ae72df +3430,932f665575f5a1d0 +3431,7a2a1948226dbbce +3432,89a40c20a96958ed +3433,65175631518eedec +3434,5f5807508c747880 +3435,2a86322dedede7f4 +3436,ed896340a4559003 +3437,f7e3da57d7a39686 +3438,66e9ad693b6d6bc8 +3439,fc3dd236e44874a6 +3440,cf622821b06fff4b +3441,f4150580fe36bca0 +3442,e2479fb6dc3bb212 +3443,9900f0fcf3fd41b5 +3444,aad469ec00db6666 +3445,b3fdd74a6b8a306c +3446,5aeb5a99aff1b5d1 +3447,059d9e48999270d7 +3448,48ef5ec453eb0443 +3449,55b26c046a9a5bee +3450,12cbfbf16c88597f +3451,edf92df7a0781f80 +3452,1d98add83ecf5698 +3453,3dd660eb583ea00f +3454,4bde1881b1fc22ac +3455,c88c608c3176e611 +3456,e436095f376de5e4 +3457,50ac150a3635ed65 +3458,34bbf42b0e3344f4 +3459,f36fb801e3e3171a +3460,15943f3b47cf3891 +3461,3a749fdeead7f2e5 +3462,23ee98f17fc5f48a +3463,61a28ae61b388464 +3464,806f0044bfca5803 +3465,038f504f9b48560c +3466,63a59b92e7de7fc9 +3467,03993990d3a247f6 +3468,e5edb3eff6df0c40 +3469,5e46b8a77cda559f +3470,877e94f826bcb270 +3471,b36100e82ea0fa4f +3472,6d0c9828e7ad99c7 +3473,44d5dd4511b8111d +3474,e8b4799949c3462d +3475,1b2611e891faad3e +3476,71eb58f6235ae208 +3477,78b3d1ef5c6bd906 +3478,62ddd83227c49ce5 +3479,4afcd00a92c8a5c1 +3480,437b46f4433c7c89 +3481,bddd28bc172cfa9c +3482,aad2ebf4d6d17add +3483,1df5171c8ddef1b3 +3484,6618b8e239c25433 +3485,c6feff07a84c1aa7 +3486,41130175843354b1 +3487,8d905d5f5fdf3a12 +3488,152de222a8c4e55b +3489,5b577e804a652600 +3490,3083ccd89aea016f +3491,a4f5a0358081e7b0 +3492,0f77edc5ae2954ee +3493,e55a58db9bfdfe51 +3494,15a3ba32eb1960c1 +3495,77b2d43329d8f615 +3496,afdbda171d1001cc +3497,8ffe403d9a12828f +3498,9a3904377d8ffaf2 +3499,c48df1e9427ad666 +3500,71a2772aea89560a +3501,93c953202591fc3a +3502,248a5cf7c2727162 +3503,f5b3f1cfdfbf0692 +3504,9568a662a6c0f542 +3505,e4a2502c39049707 +3506,ab6231d7cf305a0c +3507,6a973f4202382424 +3508,050f812b987f8475 +3509,ce1e6f44e242a67e +3510,9454e0fe9b5c1076 +3511,79ba4bb4224ea568 +3512,bb653b3026d7c21b +3513,3dca6b0d2a040477 +3514,0d83fe40ed6fa861 +3515,e996ea95c1214073 +3516,cee45ab609f22c8b +3517,a56f37044df8e4e1 +3518,b0058c165119edac +3519,30c4cd5483735395 +3520,92872de26276daac +3521,a0230e0f02fad9af +3522,2510531ecc241bf0 +3523,0b99265a109f843f +3524,f24cf45917bf960b +3525,718f4b3f0946b41f +3526,735f4b492be6ba68 +3527,086bea049c01f78a +3528,a92e54674ebb571d +3529,c630f00836c7249f +3530,ff32f340eb53deec +3531,fbb50c3252bbc247 +3532,7aaae2b63111288c +3533,a8515a4c81dbbb9d +3534,32aae5d36f84ecd2 +3535,1342952e7c01f6de +3536,22f8e96316fc89e0 +3537,4a8eda11aeb9b021 +3538,188bd1fcbe6187bb +3539,857b074d865af50a +3540,5870aa62c7a446dc +3541,569b113a77218911 +3542,cf5e1030e5cef6fe +3543,2454818ebff7c320 +3544,94605a5bb5036e37 +3545,ddbdaa02abb5a3f3 +3546,da496d42bf86ff96 +3547,9fc7fe9544ed8d5a +3548,d14836e850546ddc +3549,2abb2cea97869d29 +3550,c349022c00c5afa1 +3551,3cdcead21e6979b0 +3552,f7d8e7cebeced312 +3553,476aa95ac24a2bee +3554,90769be2e48395e3 +3555,64beb75cf95d8f0b +3556,f20019d791902626 +3557,5189fef07f39ee49 +3558,9e4a38b0c1bdb0ca +3559,60ca1818a27a2f56 +3560,a223ae038a46a09f +3561,459812cd4003c90f +3562,f6c1f1ca03f1530a +3563,c8a5aec6ba020a5c +3564,109fdd46f32ffef2 +3565,cee2e12dc13924dd +3566,b3f6e32e0bb726d3 +3567,bab2642d7343c0a0 +3568,1be879daf23760e5 +3569,8f385e4fa83e7459 +3570,a76592bd23c2f3d2 +3571,42103f3653f63d9e +3572,afae423834f44877 +3573,acf1e639bbf491b5 +3574,3a5e3b31ed835b7b +3575,6c470884cd4b43e0 +3576,72f6bbd86f7403a4 +3577,81fb85337925393f +3578,09b2549895973027 +3579,bddd9aaa48c9c356 +3580,7661297ea3dfc30d +3581,d2dd40930ed142c9 +3582,176b6767f74710ba +3583,eb576631562c9062 +3584,48de25984fb13f42 +3585,c18a15fbdc2a975f +3586,ee91623f20546182 +3587,2073554bcbea8f03 +3588,84df1a2fc912dc21 +3589,1de249aed486d437 +3590,f1fffe87cd2a1887 +3591,1caa6638cdc1dfd8 +3592,368bf2792ef66f79 +3593,cba930ce0d2cfdcf +3594,4c7655cc210c9495 +3595,bcd8f90345b48e71 +3596,04dbf84ab0a2722d +3597,9a8838255465df84 +3598,3780d01096b8ae52 +3599,46c5b29dc8dfa700 +3600,b2cd1b3e7900ea65 +3601,b83712311441dcdb +3602,538b5134ad3c0ff0 +3603,92c6638b2ba2187e +3604,de16533ae1ceeaca +3605,406421697a65e958 +3606,72164e79cac9cd1e +3607,1f816a1ef6b276c3 +3608,f9b9ede7250d1604 +3609,5496fe1133200561 +3610,b00bb9f75858ecbd +3611,f6bbb6c3beec31d8 +3612,d24490b468c0de5f +3613,683f30915d388e54 +3614,49de16639489a95a +3615,4f14a9ce514f41bb +3616,667d9ba85e9aed09 +3617,269545965dcacea1 +3618,6a9f13ce943d603b +3619,686cc97a1761afa8 +3620,f940cccecafedf58 +3621,56fcdc50624c1c31 +3622,8597a8eea8163034 +3623,c9df8f872933bd33 +3624,7177a7e04a708233 +3625,b5ebb32c781539c1 +3626,c39f3ca53a4f57d6 +3627,cbe874bdf22ff583 +3628,7acd5e7bc21606f2 +3629,a7a2a65703772557 +3630,d551789ed1f3321a +3631,f34d80647fde6906 +3632,5c49f979bb2c862b +3633,8f774c8b056d76a1 +3634,2a3f150c561540e7 +3635,c089de2710bf5f50 +3636,9421b1711de3debb +3637,be6f0c22deb130a1 +3638,90c674643cfb1420 +3639,44d5b729fdd1d4e1 +3640,1d7a6a75a407ccec +3641,c0bd6ba5bb3731a9 +3642,39cc4bce7117ab4c +3643,bb157329fa17ce6d +3644,c0074f210402b656 +3645,ec1e7621060e2f9c +3646,9b938c40e39c51ce +3647,06623868ecd5fd62 +3648,93eebb5e5938ba70 +3649,7aae33a73fcfd450 +3650,48f2b03e8cbcb4b5 +3651,ecd777ef5a490328 +3652,a738edeb43d6488d +3653,aa9778014b9a0476 +3654,0f04a6f6214db764 +3655,34c348fe6b98f49b +3656,e9530d736f311b69 +3657,424f55ad927ad9ac +3658,37eed059c6525a58 +3659,f0f703f02faff838 +3660,f1e56af3e09fece7 +3661,a465f66e549a8c25 +3662,edbe79d53c0a2a92 +3663,fa5b20575f591e80 +3664,0d75fead32de9e5f +3665,5b55b019facfca15 +3666,681aa991540f9799 +3667,fff3d41d308058d3 +3668,c4c552d75796061d +3669,ed934132ee5b0fb7 +3670,d926c0423f4f44ba +3671,e91aece4066f6498 +3672,5d8ac3baf3dcaa56 +3673,2e3e6120d51c4161 +3674,a9b1400b55686c8e +3675,eefebb0c3e4380b5 +3676,41898db8a1a3fcb5 +3677,c1003e6f0b28c706 +3678,99741aeb2787bf4f +3679,d11b78011893ac70 +3680,a4f5b1bb7fa7a5e3 +3681,9715964f72a9f986 +3682,319ebb34307363f6 +3683,58eacb917a5aac19 +3684,15ad8b5cc5529bb8 +3685,12fa4be0013d98f8 +3686,c583bcfca8378ef5 +3687,d58e44ecaf50341c +3688,fce717fc9333cc5c +3689,18daf8f1b8827ee8 +3690,0eab21c0c88dadbe +3691,362266b56ff6ebf2 +3692,dbbc3dbdb2b80f4f +3693,9d8748172e5374f9 +3694,3b0d3ebde8b3e559 +3695,236cbdeade6b6755 +3696,8dd9ac2b4ade0eed +3697,5471e861c3d3bbab +3698,62f2d56510c9d9c2 +3699,16b8544d5b0d7aac +3700,569a09155b9aea55 +3701,2c5ee7cd970f3c75 +3702,4141ce76f94dc08a +3703,352d206303cac970 +3704,921ff84f281ba377 +3705,21a015e0df43ab0e +3706,76a05b7a35ebeb3d +3707,d617f83a22e261db +3708,84030436d5616970 +3709,dbc7a0278919ebfa +3710,3e80e1badf6317a5 +3711,83aecd96bca455a0 +3712,1221fc13e7ca64e9 +3713,f8cd8626a1b63dfc +3714,2a5af79f1eb55982 +3715,a91c823c174cb952 +3716,56137a46edb065c3 +3717,4993376f99f08ada +3718,a6ec0b1d3e015b88 +3719,941c822a52beab22 +3720,05ffd6791a232bf8 +3721,58fc94cc19893281 +3722,231226fb59de6728 +3723,eb8f67b8a72d5e68 +3724,d058f64ac121c047 +3725,7f97c4e5c6b66065 +3726,e920cc2ff91cb8b1 +3727,91bdcf42676d60f1 +3728,23dfb262c2fa7608 +3729,9f2f8475d46deee1 +3730,8755cbf28f494a5c +3731,de9ed0fca66f5afe +3732,5884e304ef5dd191 +3733,f2c725937c39d784 +3734,d5f8df75ad316aa6 +3735,b3c0fedc197a13c5 +3736,08e55a6995124bd0 +3737,b08d873e658aff22 +3738,d7269ab46e2b812c +3739,ccad012b72b6a34c +3740,710114aa6d2263ea +3741,40fdd7e2c441b137 +3742,ef6cafacc5f50553 +3743,05a5c51fc8f18980 +3744,ff894dc7bf3dd4a0 +3745,a0fe262c2f5ab2fb +3746,50fdf78f1e8f62b3 +3747,dc33cd82b6c91675 +3748,f257786ec8ae9ca1 +3749,b366343408ecfc77 +3750,288c8d28a50a1ede +3751,0d17214d397711b3 +3752,299cb90be088e74f +3753,b72ca8465b5450e5 +3754,73af5ad2ca96701b +3755,857a854bf3683c65 +3756,2ece5fb9b73633df +3757,dbab59661ffc71b4 +3758,a45ae3b96dc845b9 +3759,1db67f334b837b47 +3760,029aa94c15a51980 +3761,c73f76471c61b75d +3762,a1c76be3b9b699e9 +3763,eb0e5b16d5e27f37 +3764,2118989cf52118c0 +3765,64bd7e3717cdbc21 +3766,2f708b21d9bb6efd +3767,2ca8079f535ceca3 +3768,86fde18b9b1bd912 +3769,41172b86b89bba02 +3770,e5155c4d4be13312 +3771,9f1dca20bb1c6920 +3772,78bb6a12fa2b88aa +3773,46ddfd87e11064c0 +3774,a96e6b9a36a2611b +3775,7798b106b703baf0 +3776,0d40d41b1c8040dd +3777,87000fb54f885e02 +3778,2d34a2c0c6ca4499 +3779,1f335ff9040f3889 +3780,e6086dd80d6aa835 +3781,63c01a84006ffc40 +3782,3da2e1a56529e4a8 +3783,e79a0726969775b9 +3784,30a8447be740986b +3785,48609e5ddb241ff3 +3786,d756e35e43d8435f +3787,0eb0bbfabeae8847 +3788,be520384afd970eb +3789,0f002e41bb381485 +3790,2a2b761b2e892d4d +3791,f342412419ade4e9 +3792,c88e6c284fd619a7 +3793,9ef8b5c35a5035d3 +3794,0e58e0d1a6cd0a25 +3795,7b5aaba723642c7d +3796,bedb380a2d0ec269 +3797,d632e6a54e5e5cc7 +3798,ba72b86ef4818c51 +3799,7d36b864573ccea4 +3800,23b2fb2017c66f64 +3801,1cf7177caeb659f9 +3802,85c08a55e33df011 +3803,813be75f720c7495 +3804,525e1ceaf0161835 +3805,acbaccc2e0b1b74e +3806,f434b9575ab85a04 +3807,206664d1d190237a +3808,e25881c48fb3531f +3809,09eaa39691310e96 +3810,8dc3d714075688c3 +3811,c52aa00e23216049 +3812,c3716417e3d4507d +3813,fc6a4152c1f4e9cc +3814,3d0849ddda129921 +3815,248023eff473ab3c +3816,19d3de76c066d241 +3817,c2f80b9f579ad9aa +3818,45aa3329823d91fb +3819,97c7a13853ed8674 +3820,824ad46664431bf7 +3821,f605315c64412667 +3822,ef737d62b9afb2aa +3823,80ba34349773064e +3824,d1289497193ebefe +3825,ffe8d2f1b5e350c9 +3826,98b322c315e7d1fc +3827,5ae568d7f4258d16 +3828,82fd714b3dc96953 +3829,6d49c2479aa800f0 +3830,852278cce7014a1b +3831,15fdb3d840ae9e43 +3832,c4d44a5a82e37503 +3833,107fbb3e8a587584 +3834,89a240989b7db256 +3835,c5f76a2a7e9f30c5 +3836,e1606c337757e3ad +3837,955ec72d4a9eb55d +3838,089beee187215886 +3839,7c39883175ec9b0e +3840,59a28e104a1e839d +3841,c172e0fddc7f2523 +3842,44f17741aa57ef63 +3843,09911a03ec66ec6b +3844,19fad3f9991d1899 +3845,2460f99c496aac54 +3846,36864389a25c6170 +3847,859932e85d710a11 +3848,8b3f76ff08426e51 +3849,bfb5ca48277c857f +3850,e2d5d5501c36079b +3851,87ca40d772d974ee +3852,843ae889066f1ea2 +3853,d8e1cab425d69ca3 +3854,3afe14bd82d88423 +3855,5f9cf1a85d245364 +3856,9df378b192cb5ecc +3857,838717b07f5b20cb +3858,1058e5bfa18a4bb0 +3859,b315ebeaa00f223c +3860,283c95ef0b660ac0 +3861,cbfa77759678841d +3862,b7e5103d14478e85 +3863,af8c03500ffe5cde +3864,aae545e835602da5 +3865,d75712caee5929fd +3866,bb6949b737303970 +3867,86d63df86922552a +3868,7fda75d8ac86727d +3869,a35ef38b71dccdf5 +3870,20485138b3d9c24f +3871,2a1f00fc841b414a +3872,bd57e7bb40218453 +3873,fed6eb7c516bd30f +3874,70aa52b4d4925bb2 +3875,7ed4af9fd55dae90 +3876,046456b1b53b704e +3877,b8c09fcd17b5f025 +3878,6de20e4cd4a7cb83 +3879,f4cd766645d9d8a4 +3880,2332defcdc37e457 +3881,7f43cd10f9a8af16 +3882,5b23707b28e8bdfb +3883,0610eca5f0de7550 +3884,d3b9dd68e51ecf9b +3885,a9e76003365cc248 +3886,f3ec575749ae545f +3887,f7459fa068c2a779 +3888,c7e86e1af2d7a769 +3889,497fe4a500f443f6 +3890,5916bde3e1b3fb75 +3891,21b949ae6a2329d6 +3892,133eb909e26741cc +3893,1f21ef09f5d776f7 +3894,5ec7290beb22bad0 +3895,228d4296c9f70747 +3896,99244070ada90f7d +3897,2f17c1b2dee4a88e +3898,9a548b189cdf9f43 +3899,ac6f25409acd2e85 +3900,5c40688667fb3732 +3901,ad9215bca9bbdcda +3902,c202e6856eb4300b +3903,a6786190d4c25088 +3904,952a631f552eae3a +3905,af8ad24f221d256f +3906,3904f4e8305b3e76 +3907,bd8423aa7ce61d63 +3908,d62a1bd23abb0767 +3909,cb16992f4652e6d1 +3910,86a3fcb595411931 +3911,94a1d3c2c48e2b35 +3912,ddbb950c24c89735 +3913,2880bacd0907bb48 +3914,70290eee5960e3ca +3915,855e0d88a6bdba53 +3916,d70d8dfdda6f11bb +3917,92edebfe496b71ae +3918,a771b9762ba9492b +3919,bf628ad472d0ba2f +3920,ce62e36781bd8b1b +3921,8831baafdae6efb1 +3922,56a2f085cc7d177d +3923,cf73e2b38203b913 +3924,99b0a141452f742a +3925,3195f933243952ef +3926,d4fed43d7c01ae4c +3927,ccf2e772767c6e57 +3928,8f1fe4ab4ed8a895 +3929,a793278796650c4f +3930,53e057c89564fdb0 +3931,f0b5543325dbecc7 +3932,3d7f46333ef1fb63 +3933,042a324f7451de29 +3934,98092ffb29d3aa4d +3935,fee978ef5c7d322b +3936,7f71164abd141db7 +3937,c565d0dec51d3080 +3938,6aeb3e75048a60d0 +3939,49b897dab6b6cbf6 +3940,7655f406fb7d08e7 +3941,ec8ec72dc40ea63e +3942,bae9e42bc48cd031 +3943,c16a377f2133afc5 +3944,28befdce3adc552e +3945,2203477acfe5fd2c +3946,54f1428d4d1b9ec1 +3947,4e398c718fb472ee +3948,f5047884184ea22e +3949,1a249ad0d6f1f37a +3950,4e056fe2b8ad6aa9 +3951,a235fc0112394107 +3952,930d883cc7c1ab57 +3953,7dc9fde874ae08a6 +3954,d31190b7c1bfea37 +3955,c424456349ad31a1 +3956,a97251c5e00bc0ab +3957,603e66addd1710f0 +3958,bd727e28df66fc51 +3959,aea81aab196df4fc +3960,33869a7f1e65da4a +3961,7bc7eff9a2082be7 +3962,285a25bd7553fce6 +3963,7ff6f29d9a4f0307 +3964,8eddf0ae2165f964 +3965,bcb20c5a08bf0e52 +3966,8428eeacf87e56a4 +3967,644b090810ad5841 +3968,a58f070095f70788 +3969,2ccf642d81cf1a92 +3970,0d70dad6752dd792 +3971,3f8355855622a54e +3972,9e22fa35a67eedc3 +3973,a157d2bfc8cf69da +3974,10065122e9ca78b3 +3975,71c7544e63d21db3 +3976,950d266ccf06b6bc +3977,841bda9c4b36e79a +3978,b4becd02fd55229f +3979,80383374ff759dfe +3980,16b069a4197d9ca9 +3981,081d8284d1461ac5 +3982,129f1787bb23ac33 +3983,8315c915352056eb +3984,0e90ebbf7c6d4896 +3985,e50afd966122f35d +3986,fd315bb718fa9682 +3987,e88f5384bee60e8d +3988,6e05ae72ab8521c0 +3989,b893888c9b9eb543 +3990,4fa0ccad4fc6e0e6 +3991,28651c49f7965db6 +3992,699c7ffe6aaa948f +3993,6d602f70b286e973 +3994,2edb297a91478583 +3995,f7cc646382a3b68b +3996,f9868d98c988b7cc +3997,f693c6696e186227 +3998,fd8c8cae5e63c1c9 +3999,8ad94aedc36187b0 +4000,b929e7849d9589e5 +4001,f1c990159951b322 +4002,f249ae286207f161 +4003,8425b6280ec305c0 +4004,07599d28a50ab3a7 +4005,9567cc8db8a42980 +4006,7e1e1fa4098ba2b3 +4007,486ccbc1fe2a624b +4008,2721fbcc7fd7cf09 +4009,6ba70ad031a94794 +4010,a66215cb3d6142bf +4011,7b8b566a0d938387 +4012,f2a5d02f1974e18c +4013,524d817560840151 +4014,27b29ee45c4812d3 +4015,996ab09d885e2edb +4016,bd73af0b16a8d9dd +4017,04dc085f1c6e83c0 +4018,7e05dcc1415e1c92 +4019,d80af2d882e02054 +4020,a1918efcfb301a56 +4021,0dd9e59c0929f906 +4022,1d01ad5d6dd3328b +4023,917c7ef5ff1fd531 +4024,11515e156f3875d9 +4025,a3d00fe95c0ed8b9 +4026,fccdcbe4382a3a45 +4027,a2addd6538d15f78 +4028,1b02126a3e6044a6 +4029,f22c74ec1acef52c +4030,0dee3b8370eb304c +4031,70dca68eddcaeab2 +4032,ca594e783af6cef9 +4033,13653b50e6642a55 +4034,17d5b0a5437cae64 +4035,9c0163746d5a921d +4036,5c4e47e2b7e05748 +4037,0a2458d46a7b4af2 +4038,03a15d4befbf1209 +4039,e59a0c84e668be40 +4040,afbef8ed98778e50 +4041,bbc54ddd1427a77e +4042,14c98898bab1662d +4043,f2d611696d367502 +4044,47bcf92c1845a421 +4045,7ce3b5cd955aaf62 +4046,e5c95979e4144bc1 +4047,2e7367a9a47fe83f +4048,85a85e174d8ec9e2 +4049,7d32f4f667ce95b3 +4050,bc4fad4dde7210e6 +4051,7b274b033cd0b4dd +4052,130212fe493c152f +4053,88c00e177254901c +4054,020ce5b98f9a39b2 +4055,2f514c9168e19f48 +4056,a296a171267be75f +4057,f43a26f949678402 +4058,f5e9666c543a5973 +4059,1960fb9d841dade8 +4060,aa52c65f4e02bb91 +4061,4ea3fe47848af330 +4062,088a9578f6446f9b +4063,0b3fb70e6c527089 +4064,86ac4f78af8b384d +4065,1059f8e1ce42bd15 +4066,de20f50be3aac8b7 +4067,dd011d92c41e0984 +4068,8b765bc21d61a1fd +4069,f6b66411347fa002 +4070,038abf2b5289bfef +4071,505c64dbb013898c +4072,f0746b4655f51304 +4073,2c79fbdf790b767b +4074,b607b1978f87f309 +4075,05c9fa82ceb5360a +4076,24d154b89b8a7d85 +4077,b951959b03a12e25 +4078,9026052512722877 +4079,a4e1f088ef24152a +4080,6f6e2338a4328c8a +4081,a8c642b9a42ec6be +4082,01ea091c231a8328 +4083,2d55d629ef7710cd +4084,45c6e0c8246dfde5 +4085,b9b778e119082fde +4086,8da1c19b1ad37e55 +4087,bd4ac7f563c68bb6 +4088,1ef77d77cc9bda4c +4089,e83fec18f2ceba65 +4090,7c4421968f259f25 +4091,d68a4cd91d6d2871 +4092,adccfa7a35edf44f +4093,293c940822786963 +4094,bb8147ae3e4f0f67 +4095,d4037a4b61dd1b34 +4096,49fce9fbc8fcd630 +4097,2d7fee35b4829c59 +4098,0bcbb2b081fb5035 +4099,683f743d9a30faac +4100,8cb60134b5cac243 +4101,78d106caaa7e7bf7 +4102,621181f6e06c8118 +4103,e0c8d9e302d52c2a +4104,beaed32ea3a2ea15 +4105,7d4be42dbffe4f26 +4106,15f72920eaed96f4 +4107,e7eb7a87233f4039 +4108,036e168165e4202d +4109,2be3faff8411f20b +4110,78a8e10cabcb518d +4111,8799009289058637 +4112,c3935c21fd1b862b +4113,bb797f7555dd9b34 +4114,007349bddce95378 +4115,047af3447b3e6211 +4116,5fd182a9770e73a5 +4117,c329a3103270e741 +4118,76a2eafa8f78ce87 +4119,970010ee106540d4 +4120,e631b15e5a47472d +4121,64a99c5273e65e09 +4122,4caae89bc7ad0f3f +4123,8f95a9a4f66ee673 +4124,21697b722f949188 +4125,4a947c7a2051bafd +4126,ef0e5bf9d5176623 +4127,63db026d9a45aedb +4128,ea2fe807caffafc1 +4129,3a02d195dca6c7e9 +4130,9529d17f1ea46421 +4131,725eff37d72549c1 +4132,944d100a5ae9d6c4 +4133,5542d3102fe108aa +4134,d387b9403b88b29c +4135,fbc7261a79abdd10 +4136,d766f088a7a21a9b +4137,3e9a6ca010c1feba +4138,9be88ed9da80001b +4139,e8334224984422cd +4140,8b12512955468589 +4141,fee02c32774f875f +4142,fb75bdc40ecf748d +4143,307b890433f82118 +4144,4dfd27408a31513d +4145,e98d63569149a956 +4146,03d40a84e41fef8e +4147,bf8f362a73f70751 +4148,bc77a2b6d98a15f0 +4149,2bee23c471e9a53b +4150,6119ca26545d68f0 +4151,85c0d26d44d2dc6e +4152,f6e7faea3073db73 +4153,db9e935999cac044 +4154,e580177ad4d3fb3d +4155,ab49d36a09b42850 +4156,6edb23db7e6e527c +4157,c9e5421815248df9 +4158,5387bd9bcbb8c86b +4159,5851f673b965cc38 +4160,557471e08a5ca1d2 +4161,fcb6086d2152817b +4162,7f63de41e0261158 +4163,3319a18f76f5b9bd +4164,13cc775e1ee4ee6c +4165,d651abd484e8c84d +4166,429fa59ea3e2cad5 +4167,fa651111fae4d343 +4168,48cd47f99e46d53b +4169,ebb722f19df72ed4 +4170,be7b3261f766d0ea +4171,7ebda6ac03200376 +4172,8d517dbe7dc5bb3f +4173,0138b6d3b3e9a9e4 +4174,37d3fd8a3a8331d7 +4175,1eea9839349596db +4176,887a166a23075ff0 +4177,5afe33ef885a97f0 +4178,1e6d51bf47417904 +4179,b225f566244fc438 +4180,fb180f875432d26e +4181,78a1b0d2edba7673 +4182,a4f40f7c3a81e4f4 +4183,8ad922ec81ee3ca3 +4184,2415dc6757843d55 +4185,dfb5c14385d861c8 +4186,d0582fc756a52fb4 +4187,78ef2924c25a22f2 +4188,3824ec177455e760 +4189,7ee3b5ffa56d2cda +4190,73da1be41207ba27 +4191,00579a59ec832647 +4192,a7667fe04b4c2487 +4193,39fb8f6821237537 +4194,928a516eb8024d38 +4195,9dbcb9ce9225b1b4 +4196,17caa37fc7e13e7d +4197,7e255f3996594e14 +4198,b3fb8edf2f65e3d7 +4199,9aa230f217f00509 +4200,2ce72ae81a9f703a +4201,57e45e4d3e59e888 +4202,94c2b42b51572d5c +4203,d0912d9a07ba9728 +4204,2c58495aca8cee65 +4205,a30cb09e84948c10 +4206,63a9da94164c045f +4207,f692c56ae3cd1f4d +4208,f1fe587777ce7b47 +4209,546da752eec30371 +4210,a94d6c5ddf5f1e96 +4211,c7304c87495ae8fa +4212,a9c7a51e0e394947 +4213,8d7b12f74e6dcfbe +4214,aa941ee9aae79a68 +4215,218815802cb498fc +4216,3c364702c6eb4bba +4217,f79ca35270d0aab5 +4218,af3b6b84508a461b +4219,90bdc4baee6a43d0 +4220,51c9f7bc58706b11 +4221,b65ddee453a31f86 +4222,467eecd604a26f41 +4223,77e35bc119d37cba +4224,d9cbc287df5a8d2d +4225,179927fc34d29ba7 +4226,fcbf789fbea4b1f2 +4227,3151f0fee8ab7688 +4228,ce1b341e4e9627ac +4229,5dc50ddaa77934cf +4230,74b1124cd8604a9b +4231,8a73ff382a0a1290 +4232,a0dd61d6bc40e401 +4233,48dba9ed4367a2e4 +4234,6acc236e4b200f81 +4235,8a32bdb87379160d +4236,5d48bc3a729ab87b +4237,3f9382f5c3d8cd2c +4238,774f52fedd1d4828 +4239,2a7c9961a7dd9f35 +4240,c2af61461d284850 +4241,e8ae50e7ccd7aaba +4242,f9d29609b770b1d0 +4243,66e9fa3d87c7c21d +4244,054df2f1de6f3c4f +4245,e5d5863daa093fe1 +4246,943827b5e2911106 +4247,c00e6c1166f236ac +4248,bccb4ed1c868e8a5 +4249,f85a67229b08bc1d +4250,1c2ef49642d50479 +4251,7edf9dd25441b0d5 +4252,155e5e281c629aa4 +4253,842feb790d8b4e84 +4254,abc3b574961d4acd +4255,72e40fe7dfbea8bd +4256,16f84c16485be077 +4257,8e5759fda24490fa +4258,e1f831b45b63f0a3 +4259,0a173e17c16bc89b +4260,f08f81e785423bb7 +4261,cb398bd2b950c06d +4262,678e5ffb1a2495c5 +4263,d3ab6bf9f540fad2 +4264,abe5ee0405c05a57 +4265,9e07b4b2988246db +4266,4b08878fb06494f7 +4267,887666fa64e8d515 +4268,db7ae13690ba4709 +4269,148a2259fef5554b +4270,fd6dd7266d10778e +4271,5bf05fefc773dacf +4272,4aea1a12a3b2038b +4273,fa636c84ec70934a +4274,f33c8d22cd5cc996 +4275,3903803598554b32 +4276,d7d3efd6765b2f33 +4277,1a3fc0afaae7cf7a +4278,e968f1436c0b9006 +4279,b5edfd10ce754494 +4280,3371b29a7158f765 +4281,1977e267edd6c113 +4282,e69ea260c5e04f66 +4283,d8173007427f1b9b +4284,96ccea01b7dc4491 +4285,de528ad5a96632dc +4286,774eb2a7e8d39c9a +4287,c827e1d3910b574d +4288,7fcda432bee82082 +4289,80bc9e4175ac599f +4290,e5f1933e1ccf703b +4291,10d3a1b2ca929d0d +4292,26e270730ce09a0a +4293,cd13dc95a704bf4e +4294,db389fad00acc6e7 +4295,cb3ab0d1c665445e +4296,395007c736cf3fee +4297,a1e3939a7627e34d +4298,d900184cde0a3948 +4299,beeaa93cf8735107 +4300,6c03e8fd6cc85b83 +4301,67e23aba6d135903 +4302,6d552f60628fa3d5 +4303,719da5535f95dc60 +4304,7b6a286fae3225a7 +4305,ebf94800438df6fd +4306,fe6a448105d27931 +4307,19b85ae6df0f3b94 +4308,262e50aac9ca9a54 +4309,5e6cf9b1f49b056f +4310,eb43705ff1da8363 +4311,456844d126eb6ffe +4312,7bb4b91abb13c748 +4313,6cb4e185cba43366 +4314,46b09107886579a0 +4315,295e3d044694ab0e +4316,c1930d35ca6bead2 +4317,f0f73571dd349065 +4318,761ba7dab2115456 +4319,9a11414c44319754 +4320,5e486faa73a7f739 +4321,a2a31b5ab2330c15 +4322,2623025822844497 +4323,906528b960424cb4 +4324,e190ffbd4f5d3d30 +4325,d62ad941068f1020 +4326,e0af2fc3d66b7315 +4327,0ca7df30d6cb6eba +4328,7c379d909812562c +4329,b08b1c6062b627ef +4330,17ed188a0a844b7c +4331,bfcc3ed068be12ee +4332,de9a59949706c1ce +4333,b856dab1964f34ff +4334,8ef6a93a60f6176c +4335,2ddfa23fdda3fce7 +4336,d09ac9e8dedd0f3a +4337,119d1daa3d669c5f +4338,5d21d3781ac099ca +4339,eaf4c565afa37a52 +4340,286b26955a7b159b +4341,242f5803105dbef1 +4342,c4a4bfb1cd597717 +4343,1b9e4612ca865fa4 +4344,865cb4ee7c4cccb8 +4345,56aab1315cd58a10 +4346,553af1febacd9e14 +4347,1ed525e0bbf4d733 +4348,60e6df12a3d7bf2c +4349,fcc28567514187f9 +4350,27333a16a97520fd +4351,29ae5aab0b9695e1 +4352,eefbe8034ac29041 +4353,0ee2ee6cad126f67 +4354,fb5eed25ee88d318 +4355,cab7ce39048723e2 +4356,61aa57d3b40d7b55 +4357,9156b1cf77b861aa +4358,9ad24e6bad15dd34 +4359,ea3dcf35ad79d26f +4360,e8b6321d4c391214 +4361,0a2324506d16df12 +4362,e7162c4aa75034df +4363,748a8dec406e0c3b +4364,1c5fafe3bad4e980 +4365,164e7e956511100b +4366,999ec77332442030 +4367,5a78e91cfe395ec3 +4368,cabfcedd992f458c +4369,e2e33e636dd3ab9a +4370,c8eeaffdc76de688 +4371,6c34db3b28a313f6 +4372,2898951641f28df3 +4373,bcf8a2dc271c09b1 +4374,30a926eedfa9499d +4375,b6f603a7c8b895e0 +4376,1e2e403e9dc5e078 +4377,baec24fcdffab2ca +4378,7f9aff03160c1b2a +4379,6fe94751c0395423 +4380,1a95c00277d28ab1 +4381,949c7c11dfdb6209 +4382,0d04c10f5274df5c +4383,bf4db6fb5486ca13 +4384,f33f5a09737b956e +4385,98235ba470855b18 +4386,35fd1167532d1182 +4387,1a2e83d40c71d6bd +4388,811678b2e23e53fa +4389,169a9e9353e08e46 +4390,97e17b823361afed +4391,5a97b8f25aadf6c3 +4392,73846fbd7220d1e7 +4393,31771dca6e6ed601 +4394,abdd857b1fc05445 +4395,06fb4f7a79623b6b +4396,35349fe9e1a67c5f +4397,69976cc1cef0fe1d +4398,4ce817bbee20af66 +4399,7bee53e925b6774a +4400,f7ef2e35b44fa8b1 +4401,5b1466fd6a28e04e +4402,27e9c68ee7075822 +4403,bc2ebcfd6a94d427 +4404,aa4a7f50a7c60ad6 +4405,28e5898e1c03e2c8 +4406,a75399cff2e3c8ac +4407,b0ff9ce210c13cf3 +4408,ba765be84cf63e13 +4409,a7b63197992b522d +4410,547c98a4baade34b +4411,8310ff52fb91973c +4412,ea0baaaa260d7b59 +4413,727d4c7a6e8fd9a5 +4414,1d6fd821bf4214f7 +4415,0cff8723599eaad2 +4416,4136d946c12ca134 +4417,ffd3add95a320611 +4418,7d6390a57c7012d0 +4419,3be1e8e7e16783ab +4420,3bc5d937a9d9241f +4421,db1fdfec5e64efd8 +4422,f5eed83fdd938003 +4423,a5ed934a2da92491 +4424,95a56ead8b6603d5 +4425,2400358b00e522d0 +4426,4ef26fac04411031 +4427,10b5c7828133fbed +4428,107a60ca2d3ac868 +4429,bb8e4245af97930f +4430,b31d5df8ceac644c +4431,91849b36b8a6607d +4432,a62c971d88d9f7a4 +4433,1b16a61c742dfcf9 +4434,387047580f410c4d +4435,9b01bacf7ef43ef4 +4436,87f6737b59db35bc +4437,9a6b1ff8882a07e6 +4438,b4b15350d4dad38e +4439,bbc601a6c9fc0e89 +4440,23c533df2b82860d +4441,100c1025f02c002f +4442,ecb4a26c9aa6ce75 +4443,7c41d331498d0393 +4444,f8790dd2d28c4a87 +4445,729319965a79a335 +4446,1bf18ba3800c6377 +4447,063bd72583182d5b +4448,a62934591e5f2507 +4449,8171af7f8f6a0f90 +4450,3d1424ced698e547 +4451,3ec7b406a76014c8 +4452,99b029c22448f277 +4453,40a61a0370289588 +4454,7982cdf2f6da1f90 +4455,0b911144699bf710 +4456,c9245e0774643a20 +4457,545395b9baf1c8a3 +4458,05a125a6e9ae3ec0 +4459,50395ff78fca5e71 +4460,dd4c864dce18176f +4461,3f4e1001842f0794 +4462,038f425c6056a52d +4463,46312377dddba038 +4464,d4411e1b271441ae +4465,e85069e3207a430c +4466,54fe712eed3f4435 +4467,ef6223de9a833514 +4468,58fe46728cd5c6b7 +4469,0a88f591c847a1bd +4470,bb48f32788cbc0ac +4471,5a865d7efc91be3c +4472,e1b2e9b3a9cc2a6f +4473,80df38ac21d2e13c +4474,afac4bdfb3ca55ae +4475,5014bc797201de31 +4476,77b233f54fbe1546 +4477,ac4eb8b9d63a2d60 +4478,0ee7947f56baf3f5 +4479,8feaec907c28913e +4480,c048ca22e2ba06b0 +4481,c21e877dd493fd09 +4482,c7133d48c3c2d94f +4483,f84bfd2ee986e046 +4484,bc524195bb60c6f4 +4485,59921f40aad70633 +4486,54adfe8cfe171f8b +4487,6960d7c90d3de79c +4488,66a31aba8c63e574 +4489,86d1a64406d1c6d2 +4490,c05efba4298453d9 +4491,ab6a407675ace771 +4492,e483d661a17b26e0 +4493,c89178bcf15d2fe2 +4494,5e9121f8571d2742 +4495,59ea7a7b48dcab80 +4496,abbd2fe8e565917b +4497,7731fec9b7cfc36f +4498,f763b79d949ed065 +4499,d581783a43e5c358 +4500,cfc7fdebe6cffd9e +4501,4e94ea4064c5cd39 +4502,101e9f71d5c2433a +4503,bcc2e39235c4907f +4504,6cb124eaf9100d71 +4505,f80e8e3560b179fe +4506,e6e28bd4f1c6c62f +4507,e6247927633e5277 +4508,e5a622547a68935e +4509,4a53060be4cdd507 +4510,608669e25cf8a7f1 +4511,f4a14daca7e41411 +4512,ea610f65b38fbfac +4513,9ba83b7a2b780d87 +4514,05946ddbb200a3cb +4515,5c05725e50e2171a +4516,3845124c811cab53 +4517,6e245d256d55ec31 +4518,9e9b5064f52cd59e +4519,dd49ac8bef27c503 +4520,31e0ea23f4fbc19e +4521,a7659c7280656276 +4522,8428dbab6689be90 +4523,187ca0ae5d65fb8b +4524,4e8e24b95c8f81a5 +4525,3e044b6bbebdad17 +4526,cb8cf3bbeaa45c41 +4527,d8c69c03b4fad4ee +4528,86818dceda69e982 +4529,4427025a9d2edd5b +4530,05146eaee912359b +4531,0379812ace3c8b2f +4532,c3aea49154b88ed4 +4533,196e7ab05b6f0846 +4534,2e330f0e6ed43ef9 +4535,c63a1c24ed900e7b +4536,779ecf6c85c993a8 +4537,cf4a3bdf660f27c2 +4538,1a2a2a3c7f05a30b +4539,51b56e1c003134d3 +4540,110c5c2e2bfbdb6c +4541,beb7a39414f8f4bf +4542,a7122d3d69e6c760 +4543,8ac89448160fb334 +4544,3b5994812c78fd8e +4545,1b54552fe5292551 +4546,7688f4bb7a767ca7 +4547,73c7ad853e800482 +4548,125a9a1bc79bc4a6 +4549,1d86628201f7413d +4550,d9a01909fec6a089 +4551,9aa5b306e78a53a2 +4552,f3a4a17d2bd489c7 +4553,ca71ec6a6d6dcd52 +4554,332012cd500b0210 +4555,b8d941fbcbb5ecd2 +4556,0f16cc4fc4c3348d +4557,de0a6197ee91941b +4558,e3bb17a35ed3946b +4559,e3526935c4d97aad +4560,2459839e69010e70 +4561,76f33f21b22b7303 +4562,69be0a6d5f5b3bc9 +4563,fa1d1e308229e8a0 +4564,9a096ca1777e39c0 +4565,04a8958d15abd5f0 +4566,52224293842a35fb +4567,d6db04f533db515f +4568,e7d82d5d71e30f88 +4569,0614432ead6e0f95 +4570,256191c716da2e80 +4571,747f4dac6dce1ed4 +4572,a92710d70f5f7596 +4573,152a9279a85e9d23 +4574,bda90fb9ea73fea0 +4575,82d33b3d47aac885 +4576,9e64431c283e4440 +4577,51a15949fb60a2ac +4578,a8197dafcac4846b +4579,7a04eec081a0eedf +4580,c7e92dfd92e0867b +4581,5901a109a8afeb16 +4582,48cfa8d7451a65c6 +4583,9578214b908894fa +4584,8ffd83b1b7763035 +4585,61faea8fc2ae1625 +4586,2223bdfe79f1d9f3 +4587,fe1303a7f284d6e2 +4588,682ab565fb0f03e8 +4589,5037d01e1053af09 +4590,49676d7b5cc58246 +4591,a50b8b85ad13ed3d +4592,2e5a3f671eb79c5f +4593,5873fcb3730a1db8 +4594,3063409a2359ee02 +4595,2fef5d0b9994d57c +4596,3ec6da5630355a08 +4597,136132b87b5106be +4598,1bbcda582c41ba99 +4599,d3811fbce46b5632 +4600,bdbdfe65ffc73d5a +4601,ec89017a3439fee2 +4602,d96d1a0d7d56c07a +4603,7e3e55ca344b2e27 +4604,356116b00df251dc +4605,880b6529a639a75c +4606,ee58f028bf17e859 +4607,dba1acb77b483de5 +4608,038d2185957ef3de +4609,299b60bc67909f8f +4610,e726912a4f485dc4 +4611,d83f299be8e88dfc +4612,4af9093b724aa896 +4613,681a059ad4536884 +4614,938f1247654f3c21 +4615,e45a7cae89621427 +4616,9bca25acda8cc401 +4617,20c969513d6429f6 +4618,140f380dfe0fa744 +4619,8cabd187f9333ee6 +4620,8522b602361cef92 +4621,30d6aea1233f78a2 +4622,6f053a54ce67b80d +4623,27c6cf7ee217361e +4624,c71d8c49a8828bc3 +4625,a28e591d9e9c5061 +4626,14c74ab7147722d3 +4627,08d41b2cb50d75d8 +4628,e147c188aa322eda +4629,adf32af5aff40ba9 +4630,bb3942bac8d55dd9 +4631,2dc934df4e2f443d +4632,0117d956f7eb058f +4633,b30a9a6b001dca8f +4634,a9c3f3ffb7fd17af +4635,e82e60764e5188e5 +4636,2f9336240b33d365 +4637,c851d662a861bd9d +4638,c3435ac8a2a4426f +4639,6347305148f231d7 +4640,2fe701deba6cb867 +4641,5e5837be783a73b0 +4642,4db8d2101ed5144d +4643,9b5da66c2d4585e9 +4644,e239bae4b7a19760 +4645,538f99c6772a301b +4646,6685baf69e424a00 +4647,a118132c88552cea +4648,c4cbf3cc2100c940 +4649,06511e1dd7365d5c +4650,f8b66ee83818e05d +4651,3eeff11c3b005d90 +4652,851b8db5406dc11e +4653,85b5faec93765a15 +4654,4cc4c6d58bf30346 +4655,a4f552b7413cc9af +4656,3f87b5e35688d29e +4657,a3d022d090d51e36 +4658,8a3a5b904e2abfef +4659,3dae8eb4e7d90e56 +4660,84c00942aa12ab88 +4661,98c95debe66ad1bc +4662,cfd8c6f975ae8602 +4663,dd55d27644baab4f +4664,38872b99b363f502 +4665,6d96a6a7eeff60b3 +4666,22d281424302a2b0 +4667,05ea895d79a02e5e +4668,feccb3927d2ce6c9 +4669,56261cc529e427c4 +4670,df50d582929ca46c +4671,ecf731f0c2f4e3c9 +4672,633f5bd8d7c33a69 +4673,a6dc04ba02cede17 +4674,77d075688048c20b +4675,cbb82a51d4000b4c +4676,175b7db6d6e81b77 +4677,e01f3fe4cbbef02e +4678,84889af50fd2e9bc +4679,b7e95a91f1cfa3aa +4680,88d0611a21be49cf +4681,9af8b351f3d97b6f +4682,601bdec673c89c5f +4683,a5a3e08b512de268 +4684,be181afcf985519c +4685,d7f601a106762463 +4686,50452d518e6232e8 +4687,2f72a4245fdc1f6c +4688,aa167277f1c47fa5 +4689,467a09108e9297ae +4690,a02cca51db733e03 +4691,4a5e9bd930ee0831 +4692,fd19d37faef969ba +4693,b1984059ef36f0f2 +4694,61d329f3d634e02a +4695,75c6ffbb49db64ce +4696,84f47329d3c05101 +4697,eba236f8a52683f1 +4698,9827ca8e421628de +4699,defb88ad98f4d14a +4700,cfdf726ec536fc46 +4701,7bdfdf2474c4f153 +4702,9096351ae6324c2d +4703,d68796ef4a6e25ac +4704,ac975eef1e464577 +4705,5907209c7e8ddf5c +4706,565db2d5c7bb40d3 +4707,e18420f31981ff49 +4708,5bdd0cec9fbbfa10 +4709,20c66e4809212915 +4710,d506382abab91983 +4711,3b8aca5ae42a718f +4712,3a092b9298684ebb +4713,d269df74b746becc +4714,cfe74201e0b17009 +4715,f4fdd646d01b0bc4 +4716,04559b5512238eb1 +4717,16b13ff71f2841c7 +4718,2239ec3dc0461d71 +4719,ef5907f78c820f5f +4720,0e22fac8d2c04179 +4721,8cbfc05422bab10e +4722,564b07d944756553 +4723,7f0bd5cf7bc96e7d +4724,9e9eb0def67cd256 +4725,1befa8c7deb24615 +4726,3accd24fc35ca59d +4727,747677872b05c6cc +4728,cc5d8aab6465fbf3 +4729,2a23ab828307b432 +4730,2d2513fcc823f6ef +4731,b3f2d0857ad25006 +4732,3053676d5cb3bca6 +4733,b4bdcfdac480c6c2 +4734,778fb84bd76d2380 +4735,ec0281fc4d1de3bc +4736,1c876b6470d26136 +4737,b773ee27d308828e +4738,8891986ae439fc7c +4739,174fa82943783c0a +4740,e1205f0c585f354f +4741,2127728c7766f2e1 +4742,560761f2e5f8095e +4743,043da8113f473517 +4744,ebd889c49348255d +4745,6f0baebabaf067d9 +4746,f04a84af53b108d1 +4747,3f5b86affbda681f +4748,37a8c31304529e30 +4749,2e524451916921df +4750,573cfacb6c2ea677 +4751,89b7a707342cd5d7 +4752,7fdbba4ff33f87b8 +4753,f3aa47d4568086d8 +4754,c1ba4e5e180a2583 +4755,6577fc98d42c4fb2 +4756,29ac566b0f9b71fb +4757,e79fb1fa8bd6bfa0 +4758,890404637bac069b +4759,e80587cbdafd22c0 +4760,ba54f067bc81ee49 +4761,9caac07ad481d70c +4762,82b909c8a08c9077 +4763,44063e7e80f1adb9 +4764,88bc49db2ae47893 +4765,5d9afd373bad0365 +4766,c836bc68a81614ac +4767,05a6cce173cfdb6f +4768,05c28584867bc802 +4769,33179457548a0942 +4770,278056a4608f0760 +4771,a0cc8014ee88b117 +4772,d576d148f0f9b418 +4773,239b2c01d97d892f +4774,4608127ab84e4fb0 +4775,8ebb844e0938dff0 +4776,328b6939db24972f +4777,cbe2a6d04079acd0 +4778,08de3b880507a8fb +4779,9712a50bcfe34caa +4780,d1c644c6d3933c3d +4781,219c309a04f0b6ff +4782,8e67a9572f3581b8 +4783,1445ebcdf9ef206b +4784,c8f4fe2ff2357c17 +4785,3b12192d002540b3 +4786,811c52cde463e224 +4787,03d2118e3eabcd7f +4788,0b77249cef1b5ce4 +4789,68f17d3cac2b7cc5 +4790,0833d2c564ff61f7 +4791,e8db2f13f34f6b6d +4792,2cbf1a1029129126 +4793,124f3d510befc017 +4794,2715045a21dd434b +4795,bd62f615792c4ff8 +4796,5759476449c9a4ec +4797,dd833e37319c6d21 +4798,6d5b17f5effc1dcd +4799,5d463a8db7e7551f +4800,f8a9b1b8912dcf1d +4801,bb841db1967101c8 +4802,495d38a95df02157 +4803,637d7ffc53965c61 +4804,404197ba007e57ae +4805,ed496d80d03307a7 +4806,465cb6d83c983683 +4807,9ebf7b0c2e35f660 +4808,266dfc717cbdab76 +4809,3078821cf721d984 +4810,43b44c4f7f32fdc1 +4811,90df52af896c6014 +4812,83143ac30f81f4d8 +4813,1cb4dfa4eab125fb +4814,3806d59707702562 +4815,c82cbe1160a5fb3f +4816,b485e90dbb20809f +4817,206cfc8eef5ffcb7 +4818,c3af15a5302476fe +4819,894958b50bf415b4 +4820,1c997faffeb32f84 +4821,116a629ce9d8265e +4822,057f095601dbac1d +4823,76f6a6b3c54baf28 +4824,fcc3018c6ce125d4 +4825,61d453f728484905 +4826,cfa710bbe6fb2e52 +4827,5bb78f7816d97366 +4828,b52788a6167c24a1 +4829,ae51bf59636e7f7a +4830,17afde9462e2f09b +4831,aaf2011fbe0af47e +4832,ece6768873384f1d +4833,c1d2929afc926ea7 +4834,150bd2c945efe137 +4835,c88f8f531b51d3da +4836,2287efac4c18feab +4837,8c336d30f2a0ba9a +4838,619517f38f50c5fb +4839,ea78eae34d5f4242 +4840,45e2256ca2fb5ebe +4841,88549e29ccdae2c5 +4842,21750f6fc9d636d5 +4843,97ac7447e82b420a +4844,24c9a2a2f93a2531 +4845,1f960470c58da614 +4846,cfecf393f10763c2 +4847,4678aef257c075c2 +4848,c5de6c45da63a8e4 +4849,f7e7a24d024d5fce +4850,5f1f5c266e4aca73 +4851,6d9527bd13fee7a6 +4852,0459743df902ad8c +4853,1a4e844c68a0dab2 +4854,d4217b37cbe2b3e4 +4855,92b0fa89fb746540 +4856,1b035af52b64b309 +4857,d1bd5c656c663d6b +4858,944a03d68adef847 +4859,f59fa9f2b307a3e4 +4860,e997a7b7da310620 +4861,08870a5c34c0c562 +4862,058f630701c14fee +4863,dd0131f691bad05f +4864,bac4a7bab548b198 +4865,8c4055119e123abe +4866,ceb0f63dccb4c0f0 +4867,d5f364f215ec044e +4868,9d9aeabdfaea71c2 +4869,c451daa109b58b01 +4870,72a6ed0c383375d9 +4871,9b4e5978733fceb4 +4872,e4f96b93976663ff +4873,fd8dfbb685c5ccc3 +4874,dfd71576ed178d09 +4875,722925f997d5e292 +4876,4a37d29d28a141f6 +4877,98739441eacabc58 +4878,464b3a1bc8cf6610 +4879,4fc1eb81baae7225 +4880,399eea48a664bc21 +4881,85d42c5bceb3b7d4 +4882,87397a2732ce3bf2 +4883,5da65397130c56a7 +4884,cf13c314de458084 +4885,3b57096b564e4af4 +4886,a225c5f61b662c10 +4887,3936384387cc9ef4 +4888,e09a738c91243a70 +4889,8ee7190c7edb71f9 +4890,7ba96e9051b34998 +4891,70bf09b472d640b1 +4892,c772ad33afc4e4b1 +4893,37cd85ef5cc9f7d7 +4894,42360ff4cb50ccb3 +4895,773f60a4fe4e5d1d +4896,164a206e4ab699db +4897,3e0be0a76312ef19 +4898,857351bdf5891fac +4899,60a19052eacf1133 +4900,2ed43b4090b8a732 +4901,90f274ec5acf2b29 +4902,c50ed2918a90726c +4903,0bc80b6a120e9fed +4904,a51f4c5f64bdaae8 +4905,d4f4d2982722a89d +4906,a6d98ed61e44a33b +4907,bac26c7d1abb35cf +4908,3c6a6f49d269bf63 +4909,cd7dfa7105c0ce81 +4910,0a8940555559441c +4911,4eac00123fe67c45 +4912,f013e8b191e865d3 +4913,5c70f4a53d300d65 +4914,0ce8f16c5e0d4e33 +4915,66495dcaced797a7 +4916,38f85c3a5689c24b +4917,7c1e7790272a5e10 +4918,3f4201e9b63ee6f5 +4919,a7732d22b2783778 +4920,ffed9737fd1e06e2 +4921,8f462ebf75b38e0c +4922,6cc7d4bccc23a61e +4923,2e83d153ad85d421 +4924,ce8dde8301835f08 +4925,7a571f85f790c53b +4926,4741c3d26f928a0a +4927,3c75e2f8cc253b57 +4928,e2a69145bf660b3d +4929,7cc6fa612a3919c9 +4930,96aa4d3bad827357 +4931,bf4b33abf97e635a +4932,c0bd217e40533c0d +4933,cae3accb4eda0ca7 +4934,e45468092f88f240 +4935,309ba23edd931917 +4936,6e77a4d8562a1edf +4937,c8116b6acb52dd14 +4938,a3b3816da7e9b124 +4939,d1e506deb023f93f +4940,cdba31f02cc71678 +4941,c2f91bf5097a91b3 +4942,2a6e537025f37b4a +4943,83a20b5d659ac532 +4944,556ed93e3673ff34 +4945,51ba120a2c5d82db +4946,cacf988e4be0c520 +4947,490090366044bf27 +4948,3bc510d510729787 +4949,7231d7aa42a0921d +4950,599b7833eba9caf4 +4951,9e52170671ca3c03 +4952,793eb8ba7f7d926c +4953,801252ef26d0a0fc +4954,1b91a38e239d0594 +4955,eb9e5668f4383557 +4956,264cf3f542571cfe +4957,49e568d387179784 +4958,45d765c2555e1c31 +4959,9a520e5ce7100b52 +4960,913cf67ad88d9615 +4961,5f1fff9cbb806ed2 +4962,f1f4b50fba9b5cbf +4963,0285aa7f896cff60 +4964,d2fc2bf8c8c8a178 +4965,e9a9edf1a1b72135 +4966,d03492e9f363b6e0 +4967,802b6d0c161cabd3 +4968,a9001e3cf6fdd6e2 +4969,95666fb40da6e1ef +4970,ac45a4720ee3b0e6 +4971,060cddde7586bbdb +4972,03a889bbcbe65c6b +4973,06e4857ab33bb6c9 +4974,108e15f5ec43e3a3 +4975,c00e5b8a5ce57184 +4976,1b86f38aff083b61 +4977,c083362b6e4d991b +4978,5c721fb59bf1e48f +4979,c0703f1ad870c4dd +4980,62d0bc4f910d2029 +4981,c0473070f8fe79a5 +4982,f1a4e5d304d4a77c +4983,3383dcdf12a555ca +4984,42b74ab375653f73 +4985,dc522dae38a8c0fb +4986,1dbc0ca9bd9af6ca +4987,2f3710f89d39953d +4988,55190b1b513626ca +4989,871b9de781d203f1 +4990,f5211699b060c5b7 +4991,27e3d43da5ff92e4 +4992,161aa24bfae0afc0 +4993,52969caf20097a35 +4994,ca3012d32264d922 +4995,b2c050a0bba3b464 +4996,0206717bb8f878ed +4997,ef1fe6831a92e678 +4998,5921b28b4df6e28b +4999,5f186b577be1b515 +5000,bdb35da0dd6fbbbc +5001,1bdd7ab832980822 +5002,531897fe53c399b2 +5003,120df8acdc52e5ec +5004,fbb09cf353b99ad8 +5005,a1f4a6d329573a87 +5006,6130c68b745d56c9 +5007,1a00f53939e857bc +5008,a539bdd52a0a52f9 +5009,fa97f200b2b57cb9 +5010,d123cf66b57d5dba +5011,44d94ce7631f601e +5012,3a71661f49db0d78 +5013,0abb5cbd6e7c6362 +5014,4d60f44297142874 +5015,9ca551eadaaa8518 +5016,81dc2c5e380944b8 +5017,e349c1c8d3b73805 +5018,3745f412cc0c3796 +5019,c04b03bf99348703 +5020,07a79b93b80ae6f5 +5021,48e39c7402ab2790 +5022,e085291b3c994d77 +5023,ce52026ceb68335d +5024,effb802c4001afd9 +5025,a90bc507dbaeb190 +5026,06e611d60f46a29e +5027,b563a0178ac22f5b +5028,40da86f336678803 +5029,de52cd790a52a2c0 +5030,13fc90f46ecfdfd0 +5031,4867f1e175eda3ae +5032,3e7e1568be8bab7c +5033,4c9c0be0dc217ea8 +5034,e8a143d93f9f6260 +5035,d4c1952f855cde72 +5036,efad04ebb3dbd34e +5037,d639766197a296a1 +5038,36449278adaa4d28 +5039,3516f7df3853baa3 +5040,a1e8958aff435115 +5041,84a9d9b75e272a84 +5042,3461e8c6fcc89b67 +5043,65399a0bbfa14a68 +5044,13c22bb1308c3984 +5045,2ca8ae56656ddd8c +5046,d35c0b37868cac61 +5047,2199b1d3ca1c8831 +5048,cb5abcc06faf7fa9 +5049,9e3304bbd92dd07b +5050,06aa729737d738a4 +5051,ab13900fb3e4abcb +5052,bbddf9930ec89966 +5053,9f6f0203e4a9f96b +5054,ea4b6c8fa06cf402 +5055,54437f553ce5e327 +5056,9672fd58195239e6 +5057,c67a073997247d5e +5058,a0b1b645b58fe41f +5059,b49a5ca2330e0395 +5060,d9850bf350fa7350 +5061,57635488296517fb +5062,0d42c6d4cadd671e +5063,f7ca045418238add +5064,9f675c10834ec3b2 +5065,1eebe195062275df +5066,07decbb69b69ad4e +5067,2104a57116309741 +5068,ca2434155fda2a85 +5069,fe21ee664a29291d +5070,bf62e0562fee1137 +5071,3d68b7fb66a72e87 +5072,5b18bd30dc7d2f82 +5073,7ce7064ddd8ff787 +5074,e8fa5f282f420710 +5075,af5f5e56466f045b +5076,b9c97d96d46a457b +5077,4a1d0de3b70a27a8 +5078,43e04189cfb29598 +5079,cc0e18d8c3a02593 +5080,e19e059d4138f867 +5081,96e9b01c6325d0d0 +5082,8760f0ab1de24bff +5083,30bc8b7120193a7a +5084,9f9b56b76bf964ca +5085,55aa8389bf117838 +5086,fb9796f12158236c +5087,937dbb8f13e5b591 +5088,1a5ddb7860fb1231 +5089,e1b6f6b6cb5f223b +5090,8e09fd11b3dca866 +5091,8d2e44f62a09d615 +5092,4a367867e2f38b5e +5093,e288c4932aaff1c7 +5094,c34eaa89b8dd794c +5095,a61e534a30e7d01d +5096,061184acb92d9e9d +5097,84e5c75648bd8396 +5098,f5e5b914ac415e30 +5099,30b5076e3d804aee +5100,971d039482dcad05 +5101,1ee5e290083c957d +5102,d007821bb16e696d +5103,ea4c6d0440f1c27d +5104,475af88e6069ecec +5105,4ca6b874eefb6a04 +5106,7674bb9d228a6194 +5107,a9f5cdf544bde705 +5108,89e2a8242dff4865 +5109,821315ff63064b38 +5110,6d6e0ef579f1621e +5111,701ebed6c3730c45 +5112,2ad5a4c894de0b44 +5113,9dd48437d17242f9 +5114,6dc03efe1b904fd2 +5115,77a8e149666db946 +5116,a690b4863ce2c79a +5117,4742d6348318b3eb +5118,e718b2261b3958fc +5119,55977c78a938f8a6 +5120,6702743b5975f3cc +5121,fd8e88ff16a3c3ff +5122,5ad77f3ae58b7414 +5123,2077dc4278e079f1 +5124,93df99d4ad50aefb +5125,29f2065d5048e180 +5126,31551b4ea309e24b +5127,65be291c4513a581 +5128,067f67d3538ff27e +5129,ab872d4aa6e0cd16 +5130,55864f1d05b44702 +5131,a17ec20d740b2b51 +5132,ee95663bb7170446 +5133,9f9496d6a7cd2e0f +5134,a2a7cb0c237784e2 +5135,f9746241aa34816b +5136,70b5616289ff0e8a +5137,2af833e1e040736c +5138,dc69b5209cf8dfa6 +5139,098611e4fe37f1d1 +5140,d39bc8a093f0dfdb +5141,979b89d94fe0adcf +5142,4419afcf7934abcd +5143,11fb99d4f025e1dc +5144,381fb4da0bbc84da +5145,d2b9c1268bde7d8b +5146,efac8b20cc953e6a +5147,0237105c0f6b332b +5148,b89375408a90cade +5149,f73f2a147b01eca7 +5150,766e7595af55ce11 +5151,a1ab2588d58d9492 +5152,6c912a27af5eb51c +5153,d24f7d632e76bb1b +5154,41d23ea531fdd6d3 +5155,f4064b5f03bfe436 +5156,fd46c0b779a1e14c +5157,28b942d1620a2c9e +5158,f49ddb47f59a70a6 +5159,61a8feac369accf6 +5160,2b452112ef08ead8 +5161,593bcba41c73032d +5162,bbc7fff9228fd829 +5163,bbfd6007df271099 +5164,f376621efced2197 +5165,f5593cf10fafbe66 +5166,e39379d0f433d2bf +5167,74aca913a47538d0 +5168,1285ae1cc70a9b27 +5169,9142f9c97b3573f4 +5170,568496b5104c76c2 +5171,52cfef46b473e3b8 +5172,dd3ddf8d59107e34 +5173,06266d8b27ae3652 +5174,4abbcdf9697ec0c8 +5175,b81dc3086f2e2b64 +5176,a22c6fa9a588cf77 +5177,d161e50a0cff5864 +5178,cbead0cc8d0a62fe +5179,6873508d34158ab0 +5180,e83fd6aab7035a10 +5181,7e038bce8741c594 +5182,f301c979ed80eaa6 +5183,bf3d24abe8732861 +5184,7e828a8ab578b4e0 +5185,47c82d4060806600 +5186,916d1686929f4f18 +5187,b1ab1a97b2935a4e +5188,814b2600597b7755 +5189,7379e61cee946ce7 +5190,de0ae38c42526a41 +5191,123499c5e71e8323 +5192,d60703a3d35b0de1 +5193,e02a48c69a6b0ef3 +5194,da560aa5c202ab15 +5195,e1ae39d9f50dd440 +5196,e4ae9a1f9ababeda +5197,c9ac879a0b4098cc +5198,9a84af0416cb7d65 +5199,839de83afce60235 +5200,4e96f2c4522d841e +5201,6c2cb25bcd697b62 +5202,1c2763d7661e19ed +5203,c5d1f456b9701c4c +5204,f0ebb4c503ca3724 +5205,96bcb21b76f4efc0 +5206,42f57611eb0d3939 +5207,c1e7babd1af421d8 +5208,ac009d9e4d334f4c +5209,27ae962044172c4b +5210,206400ffc2db7f45 +5211,3482ab2ec4b582fd +5212,94466378f91aef02 +5213,dafbcf489ce5eab5 +5214,3ef4350969143507 +5215,887a063140f9c9ba +5216,48bcfe8ffa80ba32 +5217,81c8f3c395b8155f +5218,f7cad406b2ab44e0 +5219,bd0ab95164fbd5dd +5220,994684bdd3e8f210 +5221,803cf2c7eb5e541d +5222,a33acf3dfef1acdd +5223,1fa1f91d43ce2c0b +5224,768f71f3235e6dbd +5225,c9f43867b6859e8b +5226,aea2761a381c1b3f +5227,7b868410a36a0f2e +5228,7cd6d7905660d71b +5229,52f1ec3ddcaf2c9d +5230,a41cad19bceb3fde +5231,b9067aeaf813f787 +5232,385b8a6ed0198c4a +5233,fce276243484a83f +5234,bc05841cd58148e9 +5235,ea4033e2d8f5f46e +5236,6172ffd08df48982 +5237,dbc87943b63f9bd5 +5238,919077c7e1eb4cdb +5239,93cfcb0bc73c2619 +5240,de4152c7a408e72a +5241,3640f18381d04a16 +5242,6fb8c6ca9805a750 +5243,b3a4e7ca24026e5c +5244,75310ea1222a17c8 +5245,2b25faa4316288d5 +5246,c666bb4119eba77a +5247,12b8f06c0fbb670f +5248,f8c0b457f48b5e58 +5249,c82a464a512f21ee +5250,406c7b92bc7ac048 +5251,5a84e53fbebdf457 +5252,390b9f8b3de3e7a5 +5253,e6686f82369dacc1 +5254,251f4cb72f3918a2 +5255,2eb4e212837f8a04 +5256,31b063d3b2380a2f +5257,ef637584f0951b48 +5258,169d972277eec83b +5259,f029ace7779176ab +5260,776e2e0757015a64 +5261,35b0ceb9efc427b5 +5262,de930edfc2e5c8c3 +5263,b5b8f0e6be1ec02e +5264,cb89a7dba45dc8a7 +5265,1831369b308c56d4 +5266,416091ef0bda506b +5267,1650490aca9788d3 +5268,62b2001d84f5efd4 +5269,f5da0113dc93081c +5270,33ce83585599d33a +5271,61919046f06e57f1 +5272,2283b2d810f88b91 +5273,b5acdba2aff3d3ad +5274,61a28b611476ada1 +5275,cb50112bf6a90fb4 +5276,e4965f3d3c334b3c +5277,bc49943dc16504bb +5278,4ff2cb4ca4d9ea78 +5279,c91e39ce82f60db2 +5280,cacc6362b182427c +5281,78b82b4dd10ed690 +5282,daa66bc7c2708d2f +5283,7777b644344dd769 +5284,5f9a4cbec6619ee7 +5285,249e801268f785d9 +5286,b409452c6809b61c +5287,96c1d52535429931 +5288,330237e804b8692e +5289,5358885de86659b7 +5290,6b24d47a861504c6 +5291,6a86a0fd0ae768bf +5292,f1b8dc8ae6bdd593 +5293,ea840d88beeb9764 +5294,80f6f3a7f131e123 +5295,b03ab725c302bc3e +5296,1b26ae80f900758d +5297,0b6cdf8fa690fcc6 +5298,c1673e66b8cac753 +5299,989e728716e3f232 +5300,606e8be8f35633b7 +5301,fa5df1abf612063d +5302,ce41a6701cf06f11 +5303,accf3a5918527b22 +5304,4fdb1a88f8b73cf6 +5305,b17d65badef7adb7 +5306,513194620b1049cc +5307,7e8950a6e6935437 +5308,91699e35c841da20 +5309,dd150ef743bab63c +5310,c2b96924153cee76 +5311,e5ccf31a43c25fe2 +5312,727ef092d28f4cef +5313,b8ef4b8f25bf7c04 +5314,6ceb6075f18e21fa +5315,149d4b39d7c73f4e +5316,524f2f767f15762d +5317,70925ce7f622f4fc +5318,22124a26a488302b +5319,da5e364987ea0bef +5320,73ad30c49923a270 +5321,9a96fb4c8ddf7e61 +5322,5113e34fe8cab1b5 +5323,e751a37bbb9fb80b +5324,231e46b36c0e0931 +5325,ce3fe564b8e3a096 +5326,d3ba93a2d6c9c9cd +5327,0390508320234bf4 +5328,dbb2ede337c65658 +5329,110fec9a2cf47175 +5330,860eef67e930c7af +5331,6b88ceba52d01329 +5332,4de1e2f329ec9821 +5333,dc1ed7783765c07f +5334,4c8efd01f59bf119 +5335,e26fd2b168802e97 +5336,e665b7e1a3ad33f0 +5337,54a4feff9f2c1d7a +5338,0dccbc99c0c29e76 +5339,9e7538eaac3cb0af +5340,4eb818ed60c5fa61 +5341,749f38977d5eb1f7 +5342,5fa10088cfc763c9 +5343,c73c82183546719a +5344,38902aec31c35c92 +5345,d951b5ad65bb753b +5346,362f59e80c6068d2 +5347,ce5c2107d3221052 +5348,5daa2377c8121fb2 +5349,da96158da242d5c3 +5350,bfd1be81d1be2eb2 +5351,eb0d0b529f25ef69 +5352,efc5240865f10a23 +5353,56317f20e5395068 +5354,79f8cce5fcf62d0c +5355,3630ac4197d8c7b8 +5356,db264c3615c8c46a +5357,1bf045096dcbce1e +5358,6ce23da49270dd82 +5359,6c98c26f87f4015b +5360,342d0bd4b3a5b131 +5361,49011a9ec9ae318e +5362,36dd64afebdcb8f0 +5363,baa4e36a058311b1 +5364,bd75f18890a5def2 +5365,b053067f9c9f457d +5366,72de31bfc752f282 +5367,e308fe90caa536cc +5368,13bd1b73f204696c +5369,9887ba3aef02c500 +5370,a93de9475770328b +5371,49dfadde0c5603da +5372,7b1b238b3e34e4e5 +5373,429b07ebd8b3e75b +5374,0af1429d5edddefb +5375,01f2abdbc250ce45 +5376,906926c19ebe350a +5377,bc6748fa785a9215 +5378,8cf0483bfb5a85d5 +5379,de7b1d4f0842e642 +5380,4ec776eceb4e6e7e +5381,0e0e1f5b84c73faa +5382,138d652880e88a48 +5383,52bd49730978e5be +5384,6dc00af184d17c60 +5385,44809cb8facce3b2 +5386,b1eb6dcb2ee9610e +5387,566690268b41128d +5388,163381aadedde076 +5389,284e41e1716e7eed +5390,6f08f8e8003c11d6 +5391,186641f1509edecb +5392,77cbf458244cc8ff +5393,7352e20de2a61ce9 +5394,ef62dfbb8632127d +5395,e570bec3fe1f6bab +5396,a00c1c8659397ca2 +5397,5213185f51efd69a +5398,28a261f3ecc07d4e +5399,42393866c116dbe9 +5400,7bd2cd3840ed3ba7 +5401,67fa6b0e3716cd60 +5402,53a63c8ed717a534 +5403,49a57379f4a983b8 +5404,0634d6241a210f77 +5405,2d06a95d62819ce0 +5406,c453392fdeadb166 +5407,8f883f247446903f +5408,57d0dc640a07d79e +5409,75c7d41c0c0c07c9 +5410,59f43443daf65ca3 +5411,4808d06729bc142b +5412,f71e70f8b12ae6f2 +5413,281f6c823384df8d +5414,8402ddc6d8d8c2de +5415,d2b700904ee9d6cf +5416,6a5cd59a996d4bfd +5417,d5a982894e6b5653 +5418,753d31a9286b9bfc +5419,1e070569822d812f +5420,c4747d8c20066a56 +5421,26b23b236bf3e750 +5422,0c7e3b6d9eb5f9e2 +5423,751dcb21df2c1c63 +5424,97119d59c36d4afe +5425,04fa38c420df769d +5426,d4af864ca6f98c8e +5427,1f80ce06836827c8 +5428,e6afe90017fd5ef6 +5429,5f2505cac55e9539 +5430,9b80b9a5d3d8a85b +5431,d0f13f1b6c1bc41a +5432,61df78b9f098578d +5433,14b8e2b0ef9873bc +5434,b7ee8dfee70c6145 +5435,779705937405a1fa +5436,77d5ea46c9faa6de +5437,726e25f9a2b08ded +5438,6355b9ad06640513 +5439,78ea2a082a61011d +5440,6286815c5f05efd3 +5441,dd02563e082b3f4f +5442,e2724a5051f8af44 +5443,5d1ac8918c32373a +5444,ce21224ec3d3ee4e +5445,58e328f7ee63d84c +5446,41e7ccbb1294bbcc +5447,4dcfd2474f9204ef +5448,ac9515d963d6d5c9 +5449,e920e08dee24f792 +5450,cb7818d7ba68371b +5451,f4b605648849d2aa +5452,43823b7e46ccd7ea +5453,dd2a2ad301598b55 +5454,df746b1b7e2c559a +5455,85841956ec53ae64 +5456,afdd8f15a1507012 +5457,8d651399b83800e3 +5458,4d15e7c145bdda1d +5459,a7286f2a99f9d326 +5460,1b30b8ff6fefe2ef +5461,060603a7be3c2c36 +5462,c8dfc8c80b4e8a75 +5463,6d398c43e72af2b4 +5464,7683ca3818a05412 +5465,989df5fbcce8de22 +5466,26514fdb464d9d44 +5467,39ed09554e20f3aa +5468,efbd269d9ac2a2a4 +5469,05bc3ad81d427d92 +5470,eb80249a365b8ba2 +5471,3877cea26f114300 +5472,d541ae6eaa401d7b +5473,cb653e147cd2e087 +5474,4554aaa90778071a +5475,41bd3d279a121559 +5476,9986b90d6c0b333a +5477,2c586dfd7723c59b +5478,7d6d48e1729a7738 +5479,16a9bfd2d3c15e81 +5480,43e12c9bc590ab64 +5481,e21eb7cf55c45c2f +5482,f749c08c147149e8 +5483,b09ae0f01de09e8c +5484,111da1856aadf31c +5485,582d95a0518a3375 +5486,d698269bef65d2c3 +5487,b9a00e3379b8b508 +5488,7d297f232c9aad46 +5489,e28790cc650df7e8 +5490,59ff9a5f74f41c92 +5491,e82402002c00ded9 +5492,41345f04b10b5ef0 +5493,0123a5ff632de046 +5494,05b23e349369c6ae +5495,d0cfb202a5b0404c +5496,1801b9425b63b9ae +5497,746dd553c9b3540c +5498,4266c6daf19f0afd +5499,38b08a5dac3b24e8 +5500,ffe2994c14d70bc4 +5501,f15a14d023eb28d0 +5502,f307c79ea133268c +5503,adf83fb1a54d75a0 +5504,bbd510c8ff0b2781 +5505,e3fcb1f8ea89626b +5506,76b9c8d6bed8607a +5507,26407af35bce6634 +5508,86721808d8b9b2cb +5509,bde5115cda82aec4 +5510,42d98e92585330a0 +5511,cb89f18869736cd0 +5512,4c43b5011824dd9b +5513,9ca43815b06eeb63 +5514,553fc7be99d69a27 +5515,dd8ebdc9fe21c331 +5516,b1f68e77ada24777 +5517,d003228c34949f4c +5518,f29c7fe3cd45574b +5519,3e839169dec77bd5 +5520,0a21ab7d8028dec4 +5521,59e9b5e5f95191f3 +5522,3a6053146294cf3e +5523,a7aee4b04a3f629f +5524,4d6beb8b40178fdc +5525,1d24bca40de65e2e +5526,18cfc45168bac1f0 +5527,0c3a8977c13d6fd7 +5528,86d0cfca342cfc83 +5529,3958497975305df6 +5530,1e4cb57596275e5a +5531,9029d75241034aa7 +5532,5046f0956287ba98 +5533,78a6c9b62ac9d73b +5534,851871b5f2defbc2 +5535,c8befaa4f318bd90 +5536,8dac5a628a169e99 +5537,93cc5e0b1f74bfb6 +5538,96398092bb4f2b47 +5539,a375926a44b73a23 +5540,27bc9d69c78a185f +5541,3bcf7a5cf2720bc0 +5542,a7cd5b7775585a14 +5543,474ff633559b2ae7 +5544,6e091c5c1ee2165a +5545,5e81e2fd8f19aee6 +5546,8cd40f8fcf17e4f1 +5547,c46b5f32ae6e3291 +5548,6967244b07864887 +5549,fab9e3bb26dc0363 +5550,b74df91751e0d893 +5551,8c0822d40c39bfe8 +5552,b7939823f09b70fb +5553,48b8026ad1f9aad4 +5554,220b25257d3f1fce +5555,3a7e0b1e52d3651f +5556,a708ec41508d3aab +5557,7e2f0d7c041ded06 +5558,b2e038e12a229630 +5559,98465ca671cb3908 +5560,fd24e69e53604151 +5561,aeb9c1a91e1cfb3b +5562,c52fb0cc49f38c03 +5563,5c1eea603231e47e +5564,b5ab4443d5030f81 +5565,7c5095803a52a36f +5566,93a1807891dd66cc +5567,011174da4c61f90b +5568,839f69ba52b69711 +5569,9e6ce90014a4c765 +5570,0184358b5b722c5d +5571,05280d65d90b817d +5572,8735a2da7c002c5d +5573,e41a4ca9852a82ab +5574,aed3141a156f6c71 +5575,fab95a93ebd2ac3b +5576,0d7d62ebe050dae9 +5577,096601998adc887c +5578,030df43a3324f97d +5579,3dfd97a62f1d3a61 +5580,325c2915cfd8b66f +5581,3e7c68ed265476c1 +5582,267e6f5604c8cf69 +5583,1fd6f6789b454aa2 +5584,6106e25a9afd0b7d +5585,186d38927b76a93c +5586,b372f5f9516fc9af +5587,15d7c6b199d937ab +5588,77eae4d3d6784a8a +5589,41eb811c05c88848 +5590,70438cabc686aa6c +5591,2ff10cb8d290a1fc +5592,410658bd63788c1f +5593,2c30b99c324bbb66 +5594,71528562dc9cbffa +5595,1a9fad8aa180251c +5596,9c950b750ab05011 +5597,5b0c7396a4229d79 +5598,e28ec061dbeddaec +5599,89e54cbe8e06fe89 +5600,66a1612b67941e64 +5601,bfa0c91529f31716 +5602,9c3649e107f0fc97 +5603,4fdf4391eab25cd3 +5604,a7fa6ddeafc7dbe5 +5605,11b1064b86eb8670 +5606,7fdf304c2e582f25 +5607,4ba75fc0cc771446 +5608,9dcfba9bb4464c2b +5609,2b9e947eae567aa9 +5610,3e990967a43602fb +5611,9187c1f250d7e6bf +5612,27928b197f20f300 +5613,a5ab26a404ffedda +5614,1b39e5fb538750f8 +5615,78bbc47efa54450e +5616,f34205a6ecd6ea2a +5617,50128588f5d69688 +5618,517ca1ff4ad13134 +5619,cf182f5433ca94bf +5620,8c737cc21a9b2d8e +5621,563e442734b3a919 +5622,952b2083720e8607 +5623,a81facec9c714209 +5624,24de2c6bceff231a +5625,9d2719be83739f00 +5626,c284553b77852cdb +5627,2492b04e9ae11067 +5628,79267e7441423128 +5629,dd3c54b5a90c9088 +5630,05abec51f302dad4 +5631,7ebbfa48075cf333 +5632,c292e21c919e0889 +5633,c6525090afec8314 +5634,0a1d25767c25c782 +5635,de093edab4e8fd40 +5636,6c61ba4aa96b7ede +5637,8302d8b2c6822b42 +5638,3d5a33d5cdcc02c5 +5639,f8b8de5f3da2ace5 +5640,7acf38606989c12c +5641,cd453e060c181f07 +5642,d9972641ebd971aa +5643,1df7406396bdd54e +5644,e12294fd1e015088 +5645,feee0a0cc5c89fda +5646,5e45dc507c55e277 +5647,77df9e18739ab59b +5648,af7e1a675c9780a0 +5649,530c1a7e102e7c2d +5650,d8ee7670770a39f9 +5651,b99de9bc7c5d2088 +5652,40d682dacaa9fbf1 +5653,181919423d0f762c +5654,175bb98d64740e4e +5655,f2c3f9305f6a1d5e +5656,48e283c96b753aff +5657,666b5481f4463de2 +5658,d7f0207de4a4b79e +5659,fb03d55f72023d83 +5660,5304ca8a474edaa8 +5661,da9733bb85e2964d +5662,6087127be6a4d1bc +5663,f111e0a4d8d1e569 +5664,1d2966bd41f599c0 +5665,54a096f031b30c97 +5666,3541c16880777e0f +5667,8b4b1e1c73cd687a +5668,f9c37f1ff65e6486 +5669,b3ab0a02da5fccdf +5670,b88572fc5dc91224 +5671,d85ea7639bf79011 +5672,7d5ba52fac140c9f +5673,2f53c83a79a92453 +5674,775213c2db15c2bc +5675,2d9ecaf629e352f5 +5676,b04f3712b42a44ff +5677,0dec222401cecdef +5678,278e009994e90578 +5679,7a19c1ee3f85dca7 +5680,d9ddc349418f3745 +5681,f2e3d6618e431853 +5682,c3c0fad46060f190 +5683,d74862945ad4d763 +5684,08073ad7b34cab4e +5685,e2f68ef75381cc18 +5686,5a26e770e3e93d2d +5687,de43bb46f0c20938 +5688,dd39d783abcc84c0 +5689,493f57dc01f417e8 +5690,1589f92eb016c428 +5691,b1882e2346df3e7a +5692,d01f5de572c55399 +5693,2d96ab85a94bcb75 +5694,315ff3d7d5296f8e +5695,224e6d651882ceb6 +5696,906d55979105cddf +5697,a4d5ae767d9d653b +5698,b80e6a2304e189af +5699,9652c66bb7a4ac78 +5700,7ef965c85bd9938b +5701,2d678d7dbc1ad17d +5702,8a8a23d2eec35b79 +5703,16b17ffbcf2a1c29 +5704,0cf7dfd695328127 +5705,4298836c333a4e52 +5706,f2dfa59630666317 +5707,9f97c04b6f0084dd +5708,14a2b056c62d118d +5709,6470f4a5a075ae03 +5710,d1e90211564eeecf +5711,9d090c3f853c2301 +5712,122368222aa034e9 +5713,4fa4157c84873059 +5714,685ae5169e2963f1 +5715,1ebf42a699742a54 +5716,f886bff8994e5f74 +5717,f27a24a505ec4409 +5718,a7b5c6dcdf28bb41 +5719,f80c3796accb0c33 +5720,3487919be34ee1d9 +5721,930c6e879065e6a3 +5722,38c39c79191f5085 +5723,8fa7b6cd758604b6 +5724,4ff55677e45ff917 +5725,8a64729cbe1c14b6 +5726,ff74d81a036e1512 +5727,c79170fd281d7b26 +5728,e5e7144aff2f28b2 +5729,c07e62e2bf61d7d3 +5730,b8193c1352872c3b +5731,f4f6590c0e8eb9d9 +5732,630204a5906eac0f +5733,bd572b7b67f83284 +5734,f4b3eb1c77932e8f +5735,63d9234ac12de2c6 +5736,37e0131a930bb43a +5737,a88b45ade9bfe768 +5738,51537e98b783e13b +5739,f009f7358a5fbc57 +5740,3387ce434ba532b1 +5741,5824dce21a82a189 +5742,252c22890ace03e0 +5743,7922ff75f7c42f18 +5744,40d5223ae025e858 +5745,fdbc2143f626667d +5746,b4fd5d1e679586ba +5747,6f208fba2a9ee240 +5748,364d6d752fe58776 +5749,d9d17e925d5c1dde +5750,8236f44af568fcaf +5751,ab58a69f58d36ea9 +5752,609ef7808b39f6b9 +5753,2f2e7321b2c5bf05 +5754,edb6f77af6044218 +5755,d1c8eea9cf0c01b6 +5756,19a978062de89470 +5757,377b3282f4caba53 +5758,910a9d8742120eeb +5759,7612788b687d0581 +5760,76191a88891bc70e +5761,24a5c26902fd826f +5762,65e4103737c4cec4 +5763,bb0f4909e9b5d878 +5764,dc4c798950f99e7f +5765,8941b4d8673211c2 +5766,621241088e00a392 +5767,e49f4f99cf7837a9 +5768,c22b7972ab58d77c +5769,a33b9a17fbdaf9c3 +5770,079b1f63cb49c1e4 +5771,dd58a47dfb1be470 +5772,db08890fd05abed5 +5773,64838662fc7a1328 +5774,197daf0f9aec7884 +5775,7d30a9e6efabd8c5 +5776,a0c88e2f74af66d0 +5777,93e3a083415f52c7 +5778,c54baed619f8a217 +5779,450fe8ac597dce79 +5780,5511ede3300c59f9 +5781,6e3e30a2dafccbc0 +5782,dfc5f61dc03c6555 +5783,f2b1d00027e55499 +5784,124766b72c867786 +5785,03031052112e9118 +5786,b6c6315648e2f2bd +5787,ea062f8ac17cd5b2 +5788,d2b08d780b5e3d05 +5789,59476519ea9786d4 +5790,f0c3a60967a47a75 +5791,7ec90b75d6b22e5d +5792,248a40f590088952 +5793,8ea6b7de93ad3fd7 +5794,5872d29764e4c6a5 +5795,25638ff0c7638ee6 +5796,da8271bd984942bd +5797,6253520f027c67f7 +5798,2fd9db5ecc93eec7 +5799,a143d8bcbeac7a11 +5800,f373b8d0a730ddda +5801,f0040204be0fbf10 +5802,99cd61a733ec951e +5803,7a470ac966e8bb27 +5804,55563c9d08d577ef +5805,2693188851198873 +5806,5a033a754025caa8 +5807,900daa7e5eac7823 +5808,43da2f54e124b7e8 +5809,741dbd55474dae37 +5810,290e44bb277d41ca +5811,18c67924b1e8c1a2 +5812,f2e8d104c9e6757f +5813,e92cbe72787ee253 +5814,e0752421a027a319 +5815,d48ecfabf99d133d +5816,3b8790aedcd1e6a5 +5817,c58f7c58d1f47576 +5818,64f9b9f8a2410639 +5819,ed78a4d58299304f +5820,4089b45b0ec6c2d3 +5821,80f75c67c494118c +5822,e936791e9b02806c +5823,a6eedafc5b130090 +5824,ed76e998762d1a21 +5825,109f6be937ba72dd +5826,80ecb1f54a09ac5e +5827,698b810c14df8808 +5828,44c1923e04225652 +5829,567b8ae861a38a78 +5830,fc14485ef99c74c7 +5831,8f2267356ce8ea37 +5832,509f7867e92ee054 +5833,0d770d266e0dcc0c +5834,9a05a841bb0160d5 +5835,1022419d51445507 +5836,1dccbe9e59249aa0 +5837,d839615a0c280a1a +5838,eeb7c101a88e4041 +5839,58e0da89cf49004b +5840,78197ae86eb7cb58 +5841,85b27cb2fc0b4756 +5842,029fb36d5e08469c +5843,7c2d97eea2e8f80f +5844,c8a83fb20de987a4 +5845,26ff92d34f69f7ab +5846,7625708a6ba29004 +5847,a98af9938c93e32b +5848,f016697a34c0dda3 +5849,3bd9a1cdebb46836 +5850,1b5615e1e720bce3 +5851,c8d8c420719674c6 +5852,c393641746caa11d +5853,256ef625da898428 +5854,ae11a95722fefb33 +5855,491edb3b231349ce +5856,c5d53477d868bd2e +5857,852cef1d6e6d9e90 +5858,1f90075510d214f7 +5859,48159fe3d230d9c1 +5860,b3a8e0c8c4b1561f +5861,7027f5279f93da6d +5862,32871a7a39df3d51 +5863,06c698700c1eae10 +5864,38e28048c34594cd +5865,1c7c3c3a00fd5ecd +5866,45f4a38b37dee1a4 +5867,227b9f2f11036261 +5868,4bdbb23af1f5a980 +5869,081c9d9bbbe8ff2c +5870,f618b8789fda2329 +5871,8b8662752a31e0eb +5872,ff6189ac6e3ca0bd +5873,287de020fdd65e07 +5874,5916b494aa25c767 +5875,4507876b60cb5f6b +5876,0846f6872d25deb4 +5877,d0db62d2b371150c +5878,c14fcd05908a2cc4 +5879,d41783087c087307 +5880,3609794f54eaf49a +5881,08a3e09f87f2d478 +5882,a60e353d9cd84c9f +5883,e7615cfd8a38ff40 +5884,29986e6c5fdda537 +5885,64aea65707113b61 +5886,202e1f63e7bc7e5e +5887,0d5c5c3c498e0132 +5888,8043e0d3bc461ee3 +5889,bbcd27bd30fbb384 +5890,c42123f11775ce05 +5891,654857d62d7088fb +5892,40748b8ef8dd9c6a +5893,62c5dcbbc5cfe5e5 +5894,27a8fdf76ccfde0e +5895,f511f6771ea6657a +5896,8fb3ac3f70df2c7f +5897,72b6aea5ad3b3131 +5898,95aaea69dc25456c +5899,0be1cc679bd89a34 +5900,8d5357727ec00b5b +5901,b776c33b214b4af9 +5902,8951be453c538dd1 +5903,1d415a52f3361c62 +5904,aeb0cf169284e93a +5905,c71f8059e41ab28f +5906,a2d5fd62f6234cbd +5907,699d31f7fd91567e +5908,809cc04b6e8a0031 +5909,49a2848bdbe3112f +5910,cc40e767b9dc9ff3 +5911,1a142ffdea73af09 +5912,3cf7029fa53759a8 +5913,a1d6f73998e77796 +5914,46d3082489473b19 +5915,4a32c86f2bcdfd20 +5916,d1ab4573ab224331 +5917,44d7fea8c9dfdde7 +5918,971673378bff8f80 +5919,b95b2b14737697c5 +5920,b6f5202ee0f54bd7 +5921,a384e982e5a71043 +5922,47c06314a076850d +5923,b44436364d03f384 +5924,6c968c2c68fa30c3 +5925,7c3d1e36937368f1 +5926,9b921cbc1989ceda +5927,fc35f75113a6a0ee +5928,9a5bb44864622a71 +5929,85693f1898983afc +5930,0fe935ab099c9eea +5931,a62d3545f458b1ad +5932,80ba15d130917941 +5933,f73ed27da5722902 +5934,bedb60d45c353721 +5935,a43de4ebc80003f6 +5936,0a581f7a82a7ba69 +5937,46cf7d9496aa1fc0 +5938,3e062df0e28a6ca9 +5939,9f66f57aed7cbe9a +5940,8572a42389953183 +5941,8f44ca1679b3c3f2 +5942,49598a8588798d22 +5943,d3078322c909ec2b +5944,0d0c6ba3db2bee6a +5945,a640b5f0fec66a95 +5946,e1aa0c44a58aaddd +5947,186e72d477563959 +5948,c24e975bd5e4d524 +5949,270dc2b0b2dec23a +5950,2e73b69a34e6215a +5951,a1299564628e1916 +5952,a798001dcdf81e59 +5953,6f56ecf568ae9ffc +5954,0a40c3a117882b9f +5955,3309d8dd76815c15 +5956,7ab6e941ec15d6fb +5957,0ca86e4959363a71 +5958,85a0d16b1e359785 +5959,5c9f76dcce75190b +5960,c016326ce7183eef +5961,0c0a22bebda076dd +5962,ef1f7851dc0fb6bb +5963,2215cc2421aa3866 +5964,34d3175f740857b1 +5965,deab20e7644589cd +5966,2198ed1c4c8664db +5967,df1321baa8799142 +5968,440f1e055f0a416d +5969,890841c15592cb4a +5970,c41af1726c35245a +5971,2c2895575d4d08e3 +5972,c6a68e8c2451168e +5973,0b499cec8dc2e37e +5974,3e718a9989b4b316 +5975,260a3a5efb43a908 +5976,e648ecba20035dab +5977,e94da559eb44323b +5978,87fb1c3dcb6ec571 +5979,7758dc87aa484df3 +5980,f5325486e81b88e5 +5981,740240f6b939073d +5982,69e74f646d581e8b +5983,7164d8752c242da1 +5984,68cf3917d6ed142a +5985,6e8fdb15d3b0bab3 +5986,a02a8e90345eff6b +5987,c5423c8d37498b84 +5988,d489900756e947d5 +5989,01d18d3f774265a0 +5990,6c9c6c24e1f49afe +5991,e3f8c0f5a40c3429 +5992,6104ba23a240eca2 +5993,33dcfede6ffc0336 +5994,47d9087ebb689601 +5995,b5345734905beea1 +5996,6227ec7e6ea948fc +5997,b647fed6ad837123 +5998,86c166c3fb33e0cf +5999,c45c17414ea02bb5 +6000,415afbfae7931004 +6001,de62fd8623eee30b +6002,e461a89d0fe899dd +6003,fc4354ff138e85d3 +6004,92dc1c0dafacc35a +6005,f09d94090b759d2b +6006,5ae7c2b1310798ec +6007,74c9ba3ab7d4fa18 +6008,ab5f96e44ae05677 +6009,8273511746669c37 +6010,e1769ed38c451dda +6011,ea365584f7dbed25 +6012,f91a26c712d1a39c +6013,a055b660dea468e3 +6014,89a8282ff77f9ddb +6015,1afebc136a50bfe1 +6016,58a7c1c8c806d34f +6017,8f1c2091c4820c24 +6018,9bf75330c2aead16 +6019,0f9cb2229ba0e59b +6020,a455d31de51dd45e +6021,65b2ee581a03d9eb +6022,06cac9b122d0dffe +6023,de01137f29ec3338 +6024,9252964f0d7cfd78 +6025,023dc58c470f80c0 +6026,c6be73585c52c1c9 +6027,5e64414e940a72b1 +6028,f02250f248b169ff +6029,cc6a280681150cfe +6030,9e4b3e56d9b4c1b0 +6031,1885df4954fc831a +6032,042faa992b75856e +6033,2a37d7fe5fcce041 +6034,f96a94188cd57d86 +6035,5338226a67f33e9c +6036,5904286967c3a291 +6037,5b045252d6b69895 +6038,dc7fb663c961ea90 +6039,984a6145442f5208 +6040,d9b6574bcd7ad7ea +6041,537a73ca120ea23b +6042,1b989b3d7ea25ac7 +6043,4c09b47bf7f9c807 +6044,e3b840b5a20ffabf +6045,89088c84d83847b5 +6046,9cf675d52c8ad9c0 +6047,86124313a1e1a558 +6048,a3cf2b09a66ccacc +6049,6968f9635ad3e147 +6050,6b45a6a5a9dd147b +6051,2a9d199942787d5b +6052,7ea0c415440290b2 +6053,c4f02698c1217713 +6054,44fa2d3d6369be12 +6055,9f3ddccf91d58a00 +6056,ecbb58cd2395a4fe +6057,d92577959e78f548 +6058,194d09f4fb83d128 +6059,3760922a563cc857 +6060,089af1533515ff63 +6061,6b820f8d94ac7a1e +6062,8ac8f02661360eb0 +6063,95041145d538fbfe +6064,8882e70dd9f93ae4 +6065,d60e433397fe1acf +6066,ef2aca08ab42fad2 +6067,4245585711664c1b +6068,6dec77b5149b56f7 +6069,09c1e8fef9213d12 +6070,efd31325886b3c06 +6071,b5342f127a2f85ab +6072,465560e00ce4a538 +6073,0e7bae6d760f339d +6074,173ba8ea09dcd929 +6075,1d1cd8e23e06daa5 +6076,fae1ae6a01ba26e8 +6077,ef7007a9909782a0 +6078,69e1afc730ccd938 +6079,2d9cbf39814e8126 +6080,bd7f573f2a3ed798 +6081,54932f6a57421fa3 +6082,f85fa1809fec79dc +6083,e61ece8ca2f31c87 +6084,922c483ba027845a +6085,36d20547f59bcbb9 +6086,af0862a91b56595a +6087,3583f1d6e942dcbb +6088,4efc8b88497d47a5 +6089,a0cdb84befb62bd1 +6090,bf64fb34a5c3ce36 +6091,f830ea527aafb0c0 +6092,ff1d928d7421c15c +6093,aee4000ba844ce5e +6094,63a52074edda4db6 +6095,1e6c011815d5b081 +6096,b7b9a7196b3bb4f0 +6097,91fc51a355218aec +6098,8c0030b612d0814a +6099,7d90b4e6a638fca7 +6100,35afab0f26a6a2f8 +6101,29390acb4d460b1c +6102,8f930d1e1b3eab33 +6103,3b7c956080a9f325 +6104,31cc11eb0ebc9652 +6105,31828c726fa7777b +6106,7b0dbbfbcca75770 +6107,e711c7026c167ab9 +6108,7e93c38290b3686c +6109,20b1b3819b9fda80 +6110,9215a65bb6d08d4b +6111,7621b95053a04afd +6112,5f85f5c7f60980a5 +6113,e5ffb5eaf99e4a77 +6114,5c6874c01f3175fc +6115,5f385a58b3fe5f20 +6116,32c170a4aef4a6f5 +6117,5eacbd44a401d1fa +6118,4d3590402c554e97 +6119,8c6834ca5c539044 +6120,cc4d597160bf170c +6121,d44e54bdbfe981dd +6122,02903c555a61db23 +6123,0851ec93963f601b +6124,d67851f1d2190faa +6125,b58ea477e9c749b4 +6126,5e00967fc7c56fb2 +6127,e7475c6d6354dcd4 +6128,f84d87e3a8c40e2c +6129,8b1c828eb9bb05ce +6130,7e031086fe08f83b +6131,cae679689ba6b14a +6132,539909ca896e95e2 +6133,7c28094c73832342 +6134,21a6df8386fd95b7 +6135,e1899ed28955553d +6136,4dc89669dcf0948f +6137,b85f22dd4ea9f658 +6138,220dde476c5dd99b +6139,dfa16a1ecc979a3a +6140,ebe80858b3bd3c0c +6141,88fdcdff7e4f5afc +6142,cc293a3ca8bc8a85 +6143,cf4bfc181acaf631 +6144,31f23947290e6404 +6145,0474bbf9e0981b4e +6146,5685883a81a31840 +6147,3c0ffb2c8f2db30c +6148,82a7bbeabe947a9a +6149,2198addd767dff81 +6150,25635b6f164d2008 +6151,723dbf2ba527bcfc +6152,c5e79420fce5c5a3 +6153,7c2534dc11253b53 +6154,b1a232f23061e6c0 +6155,d2c0b2ee25955bd7 +6156,c2a7d187776d8c69 +6157,b0b02d927299b8ba +6158,a4cac35af29d1fa5 +6159,1e4d8c3af4c3d96c +6160,2958d529905be205 +6161,bbf3142d338efa26 +6162,727f18aca5935111 +6163,5505677171ce7693 +6164,2597cd074a2d92fe +6165,66748c685655da2b +6166,bd70faf9536a3876 +6167,cb4d030cc82336e5 +6168,d7a065226a668dbb +6169,c7b9ca2ca951ce8c +6170,563a45653619cd6e +6171,6a95d4f5695fc316 +6172,6adcd41582b1d10a +6173,207bb0415f99f29b +6174,53a901cb36c32228 +6175,a53663c08a6c4e02 +6176,ac6875fdd5dea501 +6177,5a6daf407fa61878 +6178,8f49bcb95abe0516 +6179,2f2536a95e5b3cfa +6180,eac0f3b9f7d05238 +6181,9455f18de493e354 +6182,b8dd0dd8238eae78 +6183,32f8a05178f1f2df +6184,68b572d4ddb375bc +6185,43573823780140ea +6186,4c3d846481ff6d11 +6187,f83a7dfe4ed868b2 +6188,005ff93618446efe +6189,6a9368ba5edeaecc +6190,593c8d8f4b1460ff +6191,e0e26e679a84f8ef +6192,c43e3450bf2f2c26 +6193,5db52bb3157db1ff +6194,77cf733b9dcc13ee +6195,c4193dffdf9cadf8 +6196,9d857d35b2eda599 +6197,5a024da6b04d0204 +6198,d88980beb0077e5b +6199,9dfbb9dc47e93cd0 +6200,84305ee3b5701de3 +6201,c3f2eed2d806ce2c +6202,23330930752ad13c +6203,6f0d8c980c92e652 +6204,40ad9da33ccc76dd +6205,eebd9048cda85663 +6206,f5ef096adc4111b6 +6207,ea285d9ca912e370 +6208,78b6318e03bd6aa9 +6209,531fa66ef97b022b +6210,21c662c36fb7632d +6211,5d9ba9504b59c9b7 +6212,7551ff20490bf133 +6213,5f39b600fd8e6523 +6214,b81fcdf39564fb05 +6215,01275ff885e8e2fe +6216,fffeedf39c6f3732 +6217,c5e21a0605dec764 +6218,afed2a26ba9b8529 +6219,0d450744cc8cb525 +6220,9a0afd3cc54b2f15 +6221,9715acf60e651796 +6222,74dc276895faa299 +6223,0c7b57642a6096eb +6224,b68867b55e625ac4 +6225,2929198471d46cf9 +6226,af605871f9d8da5b +6227,8193f9b0e3681a3b +6228,270624604ba2b303 +6229,0f0ff28f2ac83269 +6230,3889888ca25f1da8 +6231,c8a658328a1edc5b +6232,6183eaa056cd29b5 +6233,125ef44e24b60e84 +6234,138bb82d4423ba74 +6235,1ba1a56dfd1e7e42 +6236,9949b5f54caa1e15 +6237,813f9e4ea44e8002 +6238,37894cbba901fd80 +6239,63d854638d7b9adc +6240,92571820b7d71ec2 +6241,c7a29c6d68f78f12 +6242,df1769d0fb89f532 +6243,d88ce6a0ae2cd794 +6244,85670a7def0dec1a +6245,fab65128aa6838c9 +6246,6a7c885b02b239d4 +6247,effd77ad8190b446 +6248,9d56a95b30e6b761 +6249,1363869f8b4336a2 +6250,58d283015888136d +6251,d028e0c304a4a812 +6252,6fdf83d547a59c50 +6253,6fb41b6e62685dc2 +6254,4729bc8acdf91d2a +6255,8718e9595f72a48d +6256,b65fb7540f3b45fc +6257,3473b24a6c518115 +6258,1afc1278170cae30 +6259,61a8a43d8718ed25 +6260,ec8a818e1d2f7c8d +6261,6603e67160da432d +6262,647e765b1db94654 +6263,ce839d3e833d0f9f +6264,97d691717da7b3ee +6265,be41365108754931 +6266,0bb1d764a5988fdc +6267,09cc23c2125b191f +6268,a99be02435e95edd +6269,1f026e56898b2585 +6270,7358f5800c33c748 +6271,10e9ac9f10da6dd0 +6272,28e518337daaf89e +6273,23d6abfdc1b63db5 +6274,01b79db51e016656 +6275,ec7ed3aa1f02cc26 +6276,ea225da97155e097 +6277,f468b4049ed0e5cd +6278,c6a1a0fe07986fad +6279,b3539f509d69b015 +6280,1c3d075ea4a77117 +6281,a3e58fdb86871aa5 +6282,e47a1de3c2e00f6c +6283,0fa16d69e5e6a6a0 +6284,e0e52b5f71e3e0bf +6285,54b9226d6e5e457f +6286,c3addb1d3e3a5e24 +6287,b88021c146353b23 +6288,1bab1e0bca23d11d +6289,c6a4f2f38bf84101 +6290,1093cff7a763232a +6291,79e90bf8512d6b8c +6292,5d2bca15445b2a82 +6293,766b71b506e0906a +6294,9cf73104c17c8195 +6295,6ff87587ed757540 +6296,bb0dc3d5355d3a9a +6297,e5c2588142133119 +6298,d3e51692c178dd3e +6299,23be033e01f8be8f +6300,2d75ddb36c9e214e +6301,6574d687098e75e2 +6302,0360e32f2382fec4 +6303,95de8d6180c53b44 +6304,c11e94f0f8319548 +6305,3eea21b27a3f3517 +6306,85c148d1f4118fe5 +6307,b8fe4244e0b20c4e +6308,c8039aebfb140531 +6309,c9958f0a04c98814 +6310,84afbb874b1f79cc +6311,17dbbed639f179dc +6312,4efeeaeaa1cb76a5 +6313,8c61ed2ea192a1d2 +6314,84b935a45e0d5ee1 +6315,77198e531aced8bc +6316,9ab4a54b428b3eed +6317,77ef14dc78113332 +6318,dcbd5285c00715d1 +6319,7cde31becf43760b +6320,0130b7f4f664ee5d +6321,9739a18ae184d3c8 +6322,9f9d1c51d8eeb47c +6323,8387c6eb3bbd6a36 +6324,21038b8e308e628a +6325,bbdacb4b8f7394ba +6326,0d514ef15ae67fc3 +6327,ef7da17f2f76d6b0 +6328,e62321ee225878ab +6329,f71001a95068dbe5 +6330,781f9f5cc0fbdd3d +6331,626171bff3e00aaf +6332,319451193e23f33e +6333,c991400b5a54b9d8 +6334,0e3813b5d6dadb18 +6335,331d47b79265b58e +6336,c463f724c627cd78 +6337,fe6a6217dc60907d +6338,130dd966376119f6 +6339,ec8456d6eae0f811 +6340,cf8376a528f511a1 +6341,3c15a4e61299d34f +6342,58946decd07838cf +6343,ebdf1b42cf15fdb6 +6344,b11ad92580c3299f +6345,0ed2cd0e83e03e4b +6346,a8e5545ae258f960 +6347,1da7b8e9893b78f4 +6348,32cbe8a4dc70029c +6349,d094aa2b172fb7db +6350,522301faec9e15e3 +6351,0d44eef14d2cbbac +6352,60ac0ac803772197 +6353,e01533ca963a8446 +6354,5296b9c9325a184b +6355,524ab60a9bb78af5 +6356,65725e6af60ac47d +6357,7c68442512c0344f +6358,7cb9233460a1c632 +6359,b76271e76a7f7d39 +6360,d3a0f4db12c34ad9 +6361,62e611d60f600549 +6362,4741856cfb7410b9 +6363,88fff86bd69385fa +6364,a1f2cb9242c306dc +6365,1e66dff68ca7be2d +6366,a65808f5031eed5c +6367,7711204481333bbd +6368,125315667def736a +6369,1fec29db3710ec46 +6370,73a50b3f6e74f0b7 +6371,2513b2cea3aed721 +6372,ff60f216231c875f +6373,77b36bf8a5b61c38 +6374,4b68938fd6a8bfdc +6375,078649175d830f75 +6376,19dc474f553916f0 +6377,6f58bef4a8c66a80 +6378,d237ffc5ece61bf6 +6379,531a1080f4847c29 +6380,f53d19e19eec2fdf +6381,e0b791bc39d446b4 +6382,46114d084f8da74f +6383,808bbe07455ae918 +6384,ba7110dc67a87342 +6385,02b1b914489b8fb8 +6386,153784d92bbd12f1 +6387,4980ddb61c6118a7 +6388,600b631b5eef431d +6389,b4e855409ec96027 +6390,b71529e9df00b8cc +6391,a6bfe8d7af624515 +6392,a7199160acfd8e76 +6393,65762c3ba3326223 +6394,dba3dad5716d534c +6395,95a868b3763b99de +6396,1adda617d389457b +6397,55b24fed96101962 +6398,aef8db432ee9385c +6399,c412f002157184c0 +6400,73d9b32d20bfafeb +6401,14c5c979a50838c3 +6402,e3eb17a5c6474d3e +6403,8a290cdf58863b80 +6404,6baeb265f2e19533 +6405,ba8a7daa62dcb551 +6406,699552c5e3b5ed99 +6407,65358f411da26c7c +6408,174a0c98e780e478 +6409,e30d921c52832e75 +6410,f561c9318e674fc7 +6411,828279e87966619e +6412,5fe39edc6862ffca +6413,e854105dd2f8b8b6 +6414,5ae86eadca6db916 +6415,8b501ec50da849cd +6416,6759e01ed047f556 +6417,ba8f7bb1283a8993 +6418,e66d0b60001978b2 +6419,bf1a7c0f847bd251 +6420,fce355a52776cc01 +6421,d200bd02e2ed8ece +6422,2404d428891f5dcc +6423,d27ffb2df8c5908f +6424,0de3b07f6201ffd5 +6425,7953d156b03f5976 +6426,5fb61d7088a9af38 +6427,65cc8c384cf6f4de +6428,64b79ce2d2106049 +6429,7608c53a826345ce +6430,6d4c8783e0c1f358 +6431,230ba0ac51e1e988 +6432,7830661bda66e641 +6433,d3a1a7bb4995103d +6434,b0a6b2fbe94c7f44 +6435,aa6bc42df95049ea +6436,df1ea8ee3745bad8 +6437,ac4c912d144da9b2 +6438,1b094052f771cca5 +6439,52221b603b9650a9 +6440,64c9610eafc1fdf2 +6441,76a8e8ac5e595523 +6442,4ed71af37ef779b0 +6443,7cf16e6ce83b00b9 +6444,60bd417cc86a3631 +6445,e4f31d8cac8dde20 +6446,e8de3a5faf5c104e +6447,e0f5866d6914e4df +6448,94370f24e8761c73 +6449,bae4daf72235ab84 +6450,1da40f7df6dfc110 +6451,b62433362868298f +6452,c567d4cce54870eb +6453,07f81a43f4af0f7d +6454,26c3c598c9399ebe +6455,4bd350c3d62655cd +6456,22c850b795b12cb0 +6457,7f261f9e53016d01 +6458,761756fb040b7127 +6459,e7340ce0b7ad3b8d +6460,f4e05397ec1a3539 +6461,799d0a5c67d7fd99 +6462,71edbaa1e6c8a048 +6463,007591c3b5a6ce10 +6464,312f9a0b15188dae +6465,4f881589d248d9fe +6466,68b3ec3e2dd7975b +6467,6a18c1424ac31607 +6468,9338c0ca90f889ed +6469,ae9f65d4318c8033 +6470,9aff100e1818839d +6471,e7a613d9d5806243 +6472,a305e52437dcf8d4 +6473,cdd047c33e6dd6fc +6474,2e082123f81e406c +6475,739e27b72c6f26d1 +6476,2da9ac12c9563284 +6477,3854689d37c4d4dd +6478,0ee65f240ab4c752 +6479,bb4da39535233eef +6480,8b677aefb7391eba +6481,8f200a90cccb924a +6482,ea24516638b01656 +6483,7b902a7824e9fd5c +6484,38138d53a56b8a2b +6485,1b070e9ac20e7633 +6486,0087626c97b77eb6 +6487,2eed8e9574ec20b7 +6488,80da8e2b9a29b333 +6489,71c7b528672d32f0 +6490,3c8d55a32e9a971d +6491,2d3470191d772bbd +6492,43459f0eda195836 +6493,3b1d40349fc32534 +6494,0c1a3e9e4f9e1f22 +6495,9501ba1d48e8edc5 +6496,104ab009b3b1a556 +6497,c913509c247310f3 +6498,f3c4ae4812538ab5 +6499,39974bf332d93554 +6500,5df2733eb1f7a715 +6501,bb201f1ebda4f651 +6502,0f4055bc07e4fd45 +6503,7cd2a706eb1bc979 +6504,181a6a143ba79b39 +6505,92f79d9615ad0c9e +6506,83ac6ec4621e1638 +6507,3087d5b8d17c5e64 +6508,256951c73d99c3e2 +6509,3b2bfaab3e8bf453 +6510,2905257f64847b2a +6511,347d7871727b9490 +6512,1bdbaf88037caae3 +6513,0d8085d840d6d37e +6514,bc8dd9d58b0b4b09 +6515,6c416025965c2390 +6516,f2a3079e6625f864 +6517,63c2156d592e3bb2 +6518,08a5c4f17e66e9fa +6519,d220ad7f9d07f4f5 +6520,681e39e791fb1986 +6521,89ef7f07b38dbab5 +6522,d50a478f813140d1 +6523,5aad7397fc1aca4f +6524,9dda7125b8a5434b +6525,7aae717bf45983d8 +6526,ab8d9f57d6d26f7b +6527,515d31e35f9103e2 +6528,b5d46e4d2081316d +6529,7c978722a8072f56 +6530,6cc1730ed3c95803 +6531,d663538a96af4350 +6532,eddf872e21f12a0d +6533,56e279b1c7b22e7a +6534,1a616cb06ca8d364 +6535,b8085c988cb424b5 +6536,9916d2203c974c62 +6537,0d3916f2626f8793 +6538,d13474e117d9ecb1 +6539,67a997dbc5528c96 +6540,14e63afc14db070a +6541,5d0bb29dd9543204 +6542,30d3a8ee647097b9 +6543,0e68036c7642b52d +6544,4442dcfaef9fa1dc +6545,406208c4bd4fd662 +6546,1a7a29d044561733 +6547,96e1ff0d7acf876b +6548,28db5952e2530f84 +6549,9c8d9a86064f63e5 +6550,3d382b170ae45701 +6551,9d23cf60b5a5a543 +6552,4eefb3a3e1868d26 +6553,c2106fdf6003adf4 +6554,2ec113d3dd45c3d1 +6555,7ee0605cfd961fca +6556,435c422a04cd0768 +6557,fda8e4ff4fbb9fc0 +6558,961344f79919a0a2 +6559,627109301f91e9b8 +6560,89813cd8c76716b6 +6561,ce27437b5a8161ce +6562,cf7a22103c7dbf48 +6563,81348bb4bd9eb5c8 +6564,10f9a1e754967ced +6565,fe7994628088402f +6566,810e1c5082b10284 +6567,492083fda78aef36 +6568,9e501e0ecc26a44a +6569,d9f0704b386b8a34 +6570,84501407a6bf46e8 +6571,a90563e1e5acc813 +6572,ffc7554aae2cda29 +6573,0d61c16ad57ee431 +6574,cea38fecf53c5f19 +6575,ad003db5d5aabdc8 +6576,334d252a70b86ad3 +6577,5be5227daaddd04b +6578,bfe3518d0ec76a1d +6579,119b93c60204b440 +6580,172ce6f983d63673 +6581,e951d7b56ef2f884 +6582,1fd6047228def728 +6583,2160eb21bac4fbdb +6584,2f1fc9c5952f13cb +6585,7a1c677374259ea9 +6586,ce857962ea41bcf2 +6587,c4c862c66776769d +6588,258aaa5e32ae9dac +6589,6d1df0ed96019b26 +6590,3eed6fed54d52b10 +6591,ff5d9f12178c7e54 +6592,916519df6ccd7f0d +6593,a1eb9c6faa949c32 +6594,519bccbcd596cddb +6595,e57821ae8bedd7b1 +6596,3da5266d452f351a +6597,8ecf76a41be0fde3 +6598,ac2af37c86de65a3 +6599,0f2d2e67a823d883 +6600,c2b951425998c6f2 +6601,ff9b9c4a5fb581a6 +6602,df55ff3a7f8d658d +6603,2223c43a65c64a5a +6604,dccdcfe94647a1f9 +6605,6b1e117b8d8bea7c +6606,dc0dd83d7e7e4ff9 +6607,1daa93da5d50ed2b +6608,692db6ac40b1370d +6609,42bf52d0c1111d66 +6610,0a4108f918379d90 +6611,ca8a0e9350f78783 +6612,3d8e52b358521358 +6613,3105b716308404d4 +6614,464bf78f7a3aa11d +6615,e7de40b44a7c56e0 +6616,8215a7d63e833159 +6617,8c025aac50d0dbe6 +6618,7e39f376e739cdac +6619,02a9af2648191812 +6620,0cd572068030aa6e +6621,47f659543f3b407b +6622,9bfc535236b1806f +6623,06c296d217a8a17b +6624,09c65a260188a8a3 +6625,f8abfd95dcb1cdf9 +6626,2ed4a4e955f3098e +6627,5aa9dd239d1c552b +6628,5fa000e97d62c5d4 +6629,3192ad3a38ecc842 +6630,48fd22b3fd0a8945 +6631,4bee62cb82382939 +6632,26675b4d798d8e4a +6633,c8b054b31bea957a +6634,77673e5f70f512b9 +6635,6ec0f558e450585d +6636,05df8b1282ae84f0 +6637,6204c973bdb47f7d +6638,cbf48e46055b6d57 +6639,634bb538bb1ad8aa +6640,14dfa3575654b1b7 +6641,50e009766e8d7545 +6642,aea4d3cc5af8be7b +6643,0a83fb24cbb30bb1 +6644,dba03019b877ec5c +6645,99581f3dfe4d7d84 +6646,fefe8dac087b606f +6647,ef3a8b361acd2615 +6648,84bc318af62d4e7c +6649,113c05715545827d +6650,dcb6642b069d5189 +6651,117f8058e0143740 +6652,2fd952260f38969b +6653,3e1da0088d286d56 +6654,ab281938d424da59 +6655,f9e980d50d9c1e8d +6656,b5f1543658c85afc +6657,7cf560dc5fefa3a2 +6658,e5a7fc2668c2cbe7 +6659,22a325d679c40892 +6660,0f885461e8356eb3 +6661,891628c2306a2d75 +6662,3298b1006ba665d9 +6663,7802c8424bf812f3 +6664,2732e7b802230bc5 +6665,6773f2a3366cdc8f +6666,9222b34d7837b449 +6667,b328116e7d11bb4d +6668,0a051a9658d413f2 +6669,e985c809124af73a +6670,a854d8600bde80d4 +6671,009acc2827f29ddb +6672,669d072a60c8cd14 +6673,669359f77d982577 +6674,17427c7a62671d8a +6675,d69249ec25002110 +6676,94e1148aeaf0f587 +6677,44c03f903ca820f5 +6678,ddb33e8a3700e089 +6679,f8f66e682081a195 +6680,d6734cba76d6ffa0 +6681,fab88c44df624134 +6682,9821c47bede063e5 +6683,480f0d441dc28953 +6684,07094d8cc0f1ae11 +6685,d0b10fc1b6a712d0 +6686,560ebabedfec0554 +6687,365065eea2b59f1c +6688,04e4139fc777217c +6689,6d1bcf4da8ff6e31 +6690,578811a0458a810e +6691,f98bed031b3f4a4b +6692,c69d26b136767201 +6693,56ee63f9adb42acd +6694,d41566bcf969a97a +6695,b34c3b9355c0aab1 +6696,0713aaa20b8b94ad +6697,b3f4c22ea49f4e0b +6698,2e5b0aef1c71533c +6699,075fa8e512b7195d +6700,2083175f17ef29fd +6701,11dae5c2a0fdf5a2 +6702,3c72fb0712012e99 +6703,e0d5ade3ae93e516 +6704,bab9b015361c8e14 +6705,26931cbfa5341329 +6706,4998c3c076e4aead +6707,e3ae90fbd3804948 +6708,425cba0656788947 +6709,48f3847791652b39 +6710,0b8a88b084c1d172 +6711,a151450e4d2ab101 +6712,81ce1932f8fb2a69 +6713,40a4a11535852ce4 +6714,38bd364dfdfedf02 +6715,867dfaefdff8e7fe +6716,57401a59ba478be3 +6717,b1cf36fb5dc1b137 +6718,e91154eef11f2afd +6719,eac3c7eb8410583c +6720,a8a377501f15aef9 +6721,26c720b6dc22c25a +6722,302134ca52b27aeb +6723,195deff137c6e726 +6724,32d4ffd46b3ece51 +6725,8367a5a72d1f76df +6726,842eda8d42df3305 +6727,95493696c4da947f +6728,e11b475cd51468ed +6729,37ab75460a37f9f8 +6730,ffe7f3830d75f144 +6731,8dd33596fa6aee2d +6732,5e2cd1896582c224 +6733,5ece391779d5f2f5 +6734,6a8027d9d616fa1a +6735,efdfa37665977257 +6736,ceae9e808d222893 +6737,eeb33e52bd563f61 +6738,32cf5447db9d2e5a +6739,e833e4c299d284db +6740,c762531ef480c369 +6741,c14a00c1e9e39c91 +6742,dd519bcea92dc74c +6743,f93d1a221dcfd39c +6744,64c21c7c143b82c3 +6745,814549d93da245b0 +6746,b8d160a1da3d7f57 +6747,f2067b2b97569b18 +6748,f449f0897b1074a6 +6749,c45b7c5ca80d0a6b +6750,4f99160d79d5059e +6751,7a7cbacb0daf1dc6 +6752,6d124796cda98eb4 +6753,eb38668786ed48a4 +6754,c3752d280d025bf5 +6755,00d415e10c844c0f +6756,68901b0495ac887b +6757,352a284f8f0d44ad +6758,bb55a09e8812e4c4 +6759,d299321a0803137a +6760,7d6d0d7eaabc605c +6761,4e8ab98e37532ef5 +6762,911b4898b811cc6f +6763,293ad6ae8426e4b1 +6764,401f373a06d3cec9 +6765,85575194fce636df +6766,e1c5c37b71596bbc +6767,42a5af661f7ecb4c +6768,a629e61ab0a4ce6d +6769,b5a892970c5a4d18 +6770,ab22511b10ef3205 +6771,4ae09ab6a51633f8 +6772,61cb32678707e3f5 +6773,38058b04b7befd16 +6774,54002c9b7271de35 +6775,c30ca573615cc940 +6776,fc543e0236a707b6 +6777,fcd4f7f8cf8c3914 +6778,081fd6fb78a05ad1 +6779,0f727d56a768ced4 +6780,95df43e294b7fc86 +6781,dbc895ef0bb164de +6782,e39004326d1adb58 +6783,58f49fe71d5f8255 +6784,8050b9a6f63209d2 +6785,1f8a5efcef347333 +6786,77bc1d13babaaed8 +6787,d0b04d7bc638974b +6788,34f07c90f70ff253 +6789,cd02c91cea7135b9 +6790,9241156d1dad3343 +6791,42cf8dfcc5928677 +6792,1f425f4a5a1f9829 +6793,86f53aef4f19d71a +6794,e091e37c710afda3 +6795,157e77648143f180 +6796,907acf549d9ff88c +6797,26a68c7a299a1407 +6798,c0df5eb23de471e6 +6799,1ef5ad876e9d2980 +6800,f4d5b5ef393e56f1 +6801,94511ca7fc2ef8bc +6802,71e8c74073dc64db +6803,29a4cf5a237b413d +6804,c70b8a69843d4176 +6805,6efdc6c1321f0eae +6806,05e9b302d8907e65 +6807,012c2e1df0c73a6e +6808,7688a7b12001f37e +6809,1136a5d57469d85b +6810,50fc508611a5fc1c +6811,38ae21f833d5f383 +6812,1dd81487c5916cb4 +6813,b2b0ac8778e55476 +6814,f0a6a13b1df73dcb +6815,c1c52a37a23fbb0f +6816,623ce7353e1d6329 +6817,040fb450c0f1b2b2 +6818,c750d82f4a81a3d7 +6819,36a7bd1f6369e57a +6820,6080d76024f9f2d9 +6821,c46ffc908c7d1b96 +6822,c220a7479de9da83 +6823,98d718d2f5b662e9 +6824,3774d1a84f49e4cf +6825,78407331c147d20a +6826,5a94d6f9d25b3164 +6827,468dce434922a76a +6828,b52bb33e4dd61b46 +6829,fd8a1ffd4dce3739 +6830,39d0a26c2d8fdfc2 +6831,bb6003484a5560cc +6832,792480f55e845ff0 +6833,fa824b1c3e53e0b7 +6834,1f59dfa0a773359b +6835,e02f4f21e03aa976 +6836,e73145e504a2f638 +6837,8451111467ec694e +6838,acd0e968f13bbae8 +6839,cea1fdf3843d3c81 +6840,f14e527321c05435 +6841,6a000ad8fc8b0646 +6842,a41ceac04e0d360e +6843,020149d082e34ad7 +6844,7649e335a58d3e7e +6845,32254b317097966a +6846,ee38b43af21443f0 +6847,3f6033f2a6b8ca4a +6848,dc06bcd41038a2aa +6849,b0b1ea77bdbc77bf +6850,bcb0745185b43c20 +6851,344f8319d89d1e11 +6852,4ae3e4185c0fa902 +6853,2456f81a7945d005 +6854,b57570c061d42bd2 +6855,11041e84af233d19 +6856,965c7ea06dd50662 +6857,3e99863df924b22b +6858,23bddc6ac341009c +6859,71930c1b4dd878b1 +6860,aa046ccd648811a6 +6861,a7e37098741d8e57 +6862,5526fcf3e6f5f0df +6863,afdb449f34aa6b83 +6864,886a3a0a1ec3a155 +6865,22f1e1b139bb88c1 +6866,08e19626950500fa +6867,57817a7fd8093437 +6868,7d4c4234bd6318f2 +6869,a5f0fb485e05a351 +6870,1cd898fa02fc9d1a +6871,cd34ddb34c226a7f +6872,f900e02f6cb965ea +6873,16ac4395b915e5cb +6874,a58566ed208d1e60 +6875,bcb3e95dc48d7841 +6876,3c53ba43b04fcf6b +6877,4c085c5d4a920c98 +6878,21d1e553ac3c00cc +6879,93ffb8a5ddcfb9d3 +6880,c4b179054fcdd1f2 +6881,6d2b08c9786ff1e2 +6882,7904dc9ba4d5443d +6883,ff7b72988d3d695d +6884,3620cdbdc3151394 +6885,605a6a75fc7c4b73 +6886,df3c68e62b6376ee +6887,10bfac8747d13607 +6888,d5ecfc4c336c784f +6889,4d9870112f2516aa +6890,7d69f780b603c887 +6891,6a21269633c36b2b +6892,cb2d87f83dee457b +6893,0feae8b2369a89b1 +6894,18e7112ceea06daf +6895,d235cf09cae56ecb +6896,fdeefa146a98c147 +6897,ee653663c2e62009 +6898,8736b2d12f901df6 +6899,aa0f7b4324974e24 +6900,cd4c096a8dd64176 +6901,eb35756b88ba47d3 +6902,30188054e0960f81 +6903,27a78a2bb0f73012 +6904,0a1967ca2a624c79 +6905,958f6d73dcd99518 +6906,a8ab60f84084acb4 +6907,fc1f78152cff316f +6908,38160b7e5fc55486 +6909,121632a45a26a531 +6910,ee62ec3c3b52598f +6911,52f22513f25acda4 +6912,5f0936ef0d4fef0a +6913,e2b43703ca005164 +6914,516d43f7c12dc296 +6915,e18b2635a82288d3 +6916,14dbd65e66e26f05 +6917,d9b1a5c8e9b18886 +6918,caf7c2c543604594 +6919,a760baea5645813d +6920,7e3b3be89a600ff7 +6921,9907dd113cf3c66e +6922,7345a6e5909a1983 +6923,1728e0d61e9f9455 +6924,b9af618ca4ea3d79 +6925,987d366a59659ee5 +6926,3038cd4bb5992114 +6927,8b5c1e98995f41ad +6928,be66752a0d2d7a85 +6929,f285673ad87d03b7 +6930,6a29fa923d13b998 +6931,37c55b250160f2e9 +6932,8de85690705fe589 +6933,b6f9963f681623fe +6934,8a454ff37d6a0f3b +6935,4da1d1142fb59bce +6936,29979c44e80ca00a +6937,57bf75c91d5ad134 +6938,b96d9d71ce8e5485 +6939,9b394366a1cb6c60 +6940,d763d7d5022acc3e +6941,d9413f2fae7b25ea +6942,62a55789fc8357c1 +6943,05daf874cfdb488f +6944,8ad92c30f8782ced +6945,8b1a4178df099ee6 +6946,6123599fc4d07755 +6947,df8a72e8d4bc46bc +6948,132373d9ed5a5bb7 +6949,a37f846fb17033f8 +6950,fb8945037826be25 +6951,22216496c2c61ce9 +6952,23ca4cd85d71b839 +6953,5df7fdc6a0f9b291 +6954,b03903dfc6bce66b +6955,26b781afd490ccbc +6956,aa24d0f1b7a5ba31 +6957,7088f5ac465b1d42 +6958,33653c3fd81d36fd +6959,5b040280b27a66b8 +6960,34fec69e56ea411d +6961,53566110c8abd8d4 +6962,d820728f424987ff +6963,a66a10f0a3a56046 +6964,814376bd5139eb38 +6965,9db2b9af04454473 +6966,4c87c8cd807dbde3 +6967,c01914bc72aecde0 +6968,b26e3855e501e156 +6969,8cdb95637e14d5ed +6970,c3131c78ec513880 +6971,889b8137de5b83ad +6972,793e57b29033a0f9 +6973,6023cecd4c8b73d6 +6974,b1434d378d46b3b4 +6975,3c25153be2447097 +6976,7f0e7222b1850014 +6977,af79308e688d25f1 +6978,6d0540e600829626 +6979,6920f514e8b871c4 +6980,724307e85510a5dc +6981,0607dc9ba557132d +6982,1ee4d71478c3e163 +6983,8df10d629c4a7ddf +6984,a93311bd038cc81d +6985,24f617445014d210 +6986,2e37b5be8e3a223e +6987,d04c9de19b9b8210 +6988,e90dbf2b6a68429a +6989,5a68e83cdbbdc354 +6990,cf48ca148c87f8d0 +6991,3819651a7499c25f +6992,331f3cb49c3edbe3 +6993,86b07fc8c823ef59 +6994,52e592166e4ce6e2 +6995,0dfa7f1a4d4300a4 +6996,51b25c10be8811f4 +6997,0c19cbd9a0a164cb +6998,092193797872ddc4 +6999,74e5343566c980bf +7000,db4bae097fb50990 +7001,d17620815d7735d8 +7002,470fe65d6da6128c +7003,25269a037f307da8 +7004,483e05c21d15bf2c +7005,e15950c532e251be +7006,3577b06df07915f9 +7007,7c55bba9c2c5373b +7008,092faa552095fd24 +7009,2edeaff52b788a23 +7010,d593a4d64bd804f3 +7011,767b7a017917d9b8 +7012,fd64017c2d301bc7 +7013,0e79aa4a112a385f +7014,a067f08b6eae532a +7015,47121f4110eb71cf +7016,aada1ce9cdce2525 +7017,252dd71ee6ff156f +7018,8f3b890afac84615 +7019,c7fccde202563884 +7020,e0572f21aec3c195 +7021,7669104787a6a00e +7022,4c20ed177964ac86 +7023,0732fcd8cfd4dbea +7024,1991161139b90573 +7025,d633b5eac0e33cb3 +7026,0c4950feb3cc990f +7027,44310465b6b37d97 +7028,83bd3359fc8872b5 +7029,ff7dcbdaf68e5119 +7030,14a1d5ff46539f1e +7031,d4409f0902cdc3ff +7032,c8f490d35bf2f17b +7033,7e819f050750a6c5 +7034,b25dfcf6e7eaf656 +7035,a470e2ea6199588e +7036,a12ade032ae0879c +7037,85b747756704f100 +7038,46730c1f24696c43 +7039,f3abe3c799f3d98b +7040,ad98f0e61285fd43 +7041,ac98b3813054dcfa +7042,dc38835748df4469 +7043,4cf20788a42f3074 +7044,4d7b7c778e175ad3 +7045,e9cc218617494028 +7046,e80aeecabda01e81 +7047,48a8fa292881d381 +7048,0629744009e42090 +7049,862ca7fabe702d15 +7050,95e5270fbec00b79 +7051,8a7e49b9657ee351 +7052,f72db914db7d899a +7053,168fc9465d8003c5 +7054,042f2e350b5e18db +7055,8c9f82a45c531191 +7056,9611e83f314beffa +7057,bee4a617b541bdd1 +7058,73d459b1307649c0 +7059,7a950f31aa18d5e6 +7060,6cdb2a065c452fa4 +7061,067ec98dec792cb0 +7062,5e92cfb96c805ab7 +7063,239a56eec3b75beb +7064,be4843248bbfdbc6 +7065,3998497a6ceb4eee +7066,8b849972dd68eed2 +7067,23635e2ab22f7af9 +7068,b78f348a60450a43 +7069,fe9b5d5587a4c04c +7070,ac38e5d752c5b887 +7071,abac0fcdbe126f78 +7072,1faa2420bf0f889b +7073,9021a8df08e46be2 +7074,30fd8c393b7e085d +7075,48105eebbfc7fb66 +7076,5c84f61e7f1b09f8 +7077,ab8a2bf54fb925a7 +7078,561580cd46f8c32f +7079,21124a2347f037e1 +7080,dcc05c6a28752c60 +7081,71f09023ad951515 +7082,93414c009abb5ecf +7083,fb8f50534683223c +7084,8830102a7341323a +7085,28aa56100a6de4eb +7086,400874dbd317def3 +7087,fe43515b190f6b01 +7088,450abd6565ae55db +7089,382c17f6634cf57f +7090,e0f20816ae589529 +7091,c965a995458b7902 +7092,caffb7e93556f9c3 +7093,0a4a57c1e1bee541 +7094,aa044bdbe86edef7 +7095,e2ff3659bff648e6 +7096,f5c6d23561346b75 +7097,e249b3836f0addc2 +7098,a14c1da7c656ce8b +7099,3617c05a05fd35a8 +7100,51a54e757a70e27f +7101,d3b07cad4132ba93 +7102,27e6152fffccefa3 +7103,0856a45ce6918e9a +7104,8900bcbdc17ac869 +7105,e6134db276bed0c1 +7106,f7d93a5c55f0e71e +7107,1bd77e0c01dc1d4e +7108,7c6cc13e1ff91d40 +7109,80d0274003ce778e +7110,d9ab7c454380371f +7111,22e987ed95f67b13 +7112,b534f032f4665014 +7113,a6c8c896cf47d6af +7114,cd12bddbc12e11d0 +7115,a08e9daeda186838 +7116,07d9a45f1c196821 +7117,ea268636db5f3034 +7118,44f9f495633cbb27 +7119,df9cd9c719bcd821 +7120,a36a1e1365ad1dfe +7121,24f885b7d48fdc46 +7122,70b878c89f023de8 +7123,4f3677cab5e487f2 +7124,a761cb3f8b035d88 +7125,787d493ed804973d +7126,0e47271c4bc3314a +7127,0e3562f104837b34 +7128,b485051762dbe29f +7129,beac7aed0710a5dc +7130,d232a5e66b943ed5 +7131,e2afa389e9b90077 +7132,130f997bf3e7dd5d +7133,5a212dbd72294365 +7134,4dd322e0fce40387 +7135,a3bd93a6b2dc01a1 +7136,13f8ca010561d9b7 +7137,7b759a2f0375cd29 +7138,eb88decae8ab64ef +7139,c8fcfc9712a6e42e +7140,fe71848ff5bb4670 +7141,f4f98b87aba0b758 +7142,de52902302514ac4 +7143,9e32d87b85beb737 +7144,0ed0f2f59fad1de6 +7145,f5727201e4f21bd2 +7146,ec88b074320c0dc8 +7147,ab94f06adba49bfd +7148,fc3dcd3ae402f4de +7149,b8f9ec3b5171ea2e +7150,8a04517ce049ce80 +7151,b23119a88a86639f +7152,a43a9829019e347e +7153,8ef6c6b6731b19ea +7154,8686593b0cebd823 +7155,fd11e0fcdf042f08 +7156,21373bfb248ffc54 +7157,65ea5ed1dd233fc1 +7158,a3a622bc5a101f30 +7159,d2fbd8f8ee4ee714 +7160,c49e95fca2c718bf +7161,d19584179b00d89f +7162,66a5bb7a95980720 +7163,f36d941bcdacfa51 +7164,b419daf00d06e32b +7165,f24df25d664e666e +7166,7208d0d216564c4a +7167,52d4bcde85a8aaca +7168,d927232251856bf4 +7169,4bbdb490288ce4ec +7170,28d1e101f9f4b4ff +7171,17e27b98876e7914 +7172,348dfc53b3cf7739 +7173,8342cc5ffac989fd +7174,6fedbc1d67728e33 +7175,5faf42e189aada8e +7176,6ea8787aa1542803 +7177,7f308b16141d4dfd +7178,e1fd0050f6dd0d99 +7179,f9bf8d950d4980a1 +7180,b0e5afa6820cc60b +7181,43df72128ccc26fe +7182,667fa00ff29c2645 +7183,ae9a396615eee181 +7184,af90233d823d5abb +7185,45d460e3e4b2c7d0 +7186,0fa9e7ec2a4cb515 +7187,dde27b54f4f4c426 +7188,778447d084990995 +7189,526fbc3939837114 +7190,48a6c2612d7aeb6e +7191,0955e5e26011b4e4 +7192,081d3ac80ad37813 +7193,89d45f0b8bf09cf5 +7194,d288bef708f75c79 +7195,0f4e64d5274af2e0 +7196,1a894e623abbfce3 +7197,acf491b6c99de789 +7198,f021d6018c1e37ce +7199,02a0040a2c67fe3c +7200,27e51d54a4222576 +7201,323072b43be10108 +7202,a9073800ea2119eb +7203,5de658dd6c94c038 +7204,0dd2af09212ccbfd +7205,9ffd3890666786e5 +7206,31c36d1b3639df46 +7207,65d1aeeff938236c +7208,1f98d53b09f8ce30 +7209,33a104ab6ff38312 +7210,d172dcc7db3a2589 +7211,33e2257a45f81eaf +7212,e860edc79f417ce4 +7213,7da496f645757996 +7214,ec1c68ff7b844ff0 +7215,293afa93dc957ae1 +7216,c3f7137227de19f1 +7217,593bb2c283ae431b +7218,59578f8699273638 +7219,f74801bc788cb0f5 +7220,c8040c8aa73e48d3 +7221,c7489b83abf73906 +7222,bb1572cb42d6fd2d +7223,5526d817c6902a26 +7224,a2b8a0861ce956d4 +7225,77555edede1f522e +7226,f984d021f2c0244d +7227,70abc162fc87d72c +7228,542654490b6d54ca +7229,6dc17fecbd25cf97 +7230,273987d47aba3d6e +7231,35f2518c828cef7b +7232,a9361c3c98484919 +7233,fe90ff30544b120d +7234,5c0597ff1f587f9a +7235,d0ef5353fba85ead +7236,b3b2006c57f644ce +7237,5ad548fed5573438 +7238,1ef34c701689aa2a +7239,c179f58c9008f13f +7240,e77d02162015673a +7241,7629984af916ad1e +7242,097f3d7517c16abd +7243,2709c08de6c316c3 +7244,f0250b0a72363423 +7245,f1be64a3c0907bfe +7246,cc5f124522c17c5c +7247,a82b2ad921eac195 +7248,fcdb1bc08bc7519b +7249,2f1522a44dc0ed2c +7250,0be0fb9b7db4fef8 +7251,8173c6f06795ede6 +7252,9de7182eb30ae4b2 +7253,f148125e5677c442 +7254,dd9864ae0c646292 +7255,68c6327b279402a1 +7256,81c419e760ef98b0 +7257,906dea1bec997201 +7258,3967cc13106a2f31 +7259,4d7c54387ef02c2e +7260,a1c3cfc06797934c +7261,fc1c3194c808bc32 +7262,300d0baef5ca3dff +7263,d0e2803f52306c4c +7264,708b9882b81be2c9 +7265,d557d410d336633a +7266,7640a0ebd4b4fda1 +7267,c0103f3e3b7ac6af +7268,f3a691e9149fda5e +7269,d9f353289eee8987 +7270,c92818276febfe1e +7271,9fa0a79adb26582a +7272,f8f380b7b6fc99ff +7273,6c28318c4d5148bc +7274,ae5bfbcd6b54263b +7275,1f6611266cdbc2ca +7276,d565311349c463d3 +7277,2c09343084e561cb +7278,7ceace882925ec9a +7279,71f4ccb7f527d281 +7280,2ff8d2d90025a8bf +7281,b01fb62a26d4f873 +7282,87cdbf8be6200518 +7283,63ec2725af2b0005 +7284,18dece8f350ee174 +7285,e10de4200a18a1ad +7286,b85114057fc654a9 +7287,4c1794e74225856c +7288,efe10bad301d6abd +7289,c0957d7a0f8f43c5 +7290,5129f590f825b273 +7291,3ad90acee0b3cc93 +7292,6053b57289543533 +7293,d4b6242abc7e06d3 +7294,5f535cefc307b037 +7295,0890789acdc1bea5 +7296,cd0f5dad1556e53e +7297,2d9aefc9990832c2 +7298,b4d9328d64ba127e +7299,10b1a22d59db226d +7300,479d8e8b213cabdc +7301,59f005685938cbd3 +7302,076c4cec73e10bef +7303,358ce8b126c6a1c2 +7304,ac6cee77baa90625 +7305,2a9075dff144d409 +7306,67aee7516f166c50 +7307,d227b03ac1c43109 +7308,b9fdfa8e4689442f +7309,a356c115bf868868 +7310,c5a7c13a13d17e31 +7311,6394c88301184003 +7312,b2d73260dad45041 +7313,b81f8fb0c6daf56c +7314,68758e2a571a5f55 +7315,fe7657343120bc3f +7316,73c7e867c6283ee4 +7317,c49cd765b5178bf9 +7318,72f767826a13db3a +7319,fc92a28aa72af46e +7320,8c55e7443a68332f +7321,5719c58c6a7a77c7 +7322,1b1af4c96ff64cee +7323,4ec48d0be959d553 +7324,7e9ca797410f68ef +7325,ecc0d1d0b35aab84 +7326,befb6e64147126de +7327,63cd57087171d7e7 +7328,d106b15eeebf4c2e +7329,bcac9ec8c92b4ba1 +7330,8c7c2f5e16fbcaf0 +7331,d195e84152d49508 +7332,ec43264f21e465a3 +7333,cc4d9e338d5b4ddf +7334,d872dfde7101d25a +7335,82a713943b0092c9 +7336,a7dfd4a729c663cc +7337,7f7071b9e9e607be +7338,431c0a62b942c0ab +7339,f391f92072740935 +7340,6bf62acdd1c3a0af +7341,b59513885269c4ad +7342,d6c76cc96a8a61fa +7343,586763fd07304076 +7344,fcc7c284aea89b77 +7345,9740ae8d391cc5ab +7346,d0a575e5537b2ad4 +7347,db85f004d56ed636 +7348,48de175805f0cb9c +7349,0d4bce75d5c8b60a +7350,a72b03849d231ee3 +7351,f4b34ba708613496 +7352,49efa1af4d3ec7e7 +7353,2ea6e3a375f9e913 +7354,81cccf07cf1dcd27 +7355,28a16d71cb377ff0 +7356,baf117259d8055bf +7357,69fb0fa738001e13 +7358,9c8035f1c95ad339 +7359,875365da309a268d +7360,2e986f9f9a7baf59 +7361,01bca24cf1db20e9 +7362,50913249b6ca9008 +7363,ff5d281ccfb00db1 +7364,824006e9ed582b8b +7365,22ae318eec4daf54 +7366,7bf391aa6c12d58d +7367,72f39d8c2c3ce3b5 +7368,bb04129ea34c2aed +7369,99b7c99828017daa +7370,42a85623697d0129 +7371,863857ad8c272dce +7372,c43133ae7e9e115b +7373,f128fb7705da7118 +7374,e4df8b23f490536b +7375,26c87eaac25d58f2 +7376,b67f4b9b4f83165b +7377,648ce147052a5018 +7378,6b80eccb213e90c2 +7379,d1cd3a57dbf3fd4d +7380,101d42723034290b +7381,ad96333855c67fc7 +7382,332a0299810765a4 +7383,f9eca80f2d98a73f +7384,009b8f7e11b528a9 +7385,9d17aa148bca3950 +7386,3ab235ccf53c9bbd +7387,2d7e2a18edf15b95 +7388,4dba60047a16271f +7389,da99d16084d3db52 +7390,33064a65a86882bc +7391,79c723b2878b8891 +7392,e070d81dc8315b04 +7393,2a39df25c7c447b1 +7394,05cfc41a07c3c5d3 +7395,c2efa07458705c57 +7396,aa7a0f169aabd274 +7397,59af977ba50b39de +7398,2221bc7f1b5e679e +7399,05f6af45bfa66544 +7400,b8e4c7c00bdbe88c +7401,98d39845df1afca2 +7402,23a3824300cc9a6f +7403,42d2af8a189a9042 +7404,377debde18d79867 +7405,41f5cbbb40698580 +7406,e3315f09112d464a +7407,f41015fdbed11c5e +7408,90e9ccf2a9df4a75 +7409,251bcdc1d10b3139 +7410,cf0b165ad5d3e515 +7411,3f1a95b7b572a189 +7412,40af058d898db852 +7413,11c6211f12ef5081 +7414,db55288748e6024a +7415,0223d72fce07d279 +7416,7e6430f6dae7f669 +7417,4829b22b6002d597 +7418,0807acc34c36c289 +7419,5339841f6b06b92b +7420,cac2f84098ec8f27 +7421,3281e7ef8a445367 +7422,e284e38ef6600bd0 +7423,6f079ccf30885da3 +7424,4c160e1fd8f15f29 +7425,15e6cca8e256f248 +7426,57cbb0f157b5cbcd +7427,8f1ae49de5c6c707 +7428,c61996ee1f47957f +7429,ac1167baaf38e14b +7430,635158d2a65d7c9f +7431,3af6d9c802462b33 +7432,5180fba4fa8c9270 +7433,f1ff60aa4051074b +7434,32a95bf65ac4c80e +7435,1a646d8ecd45725a +7436,a374349791b0475c +7437,5b945e2966508e48 +7438,a64c57cd775c2377 +7439,4aeec3a1ab71a3e5 +7440,fc3bfa18cb0ee866 +7441,73349b8d56bb727b +7442,da12f0097bdb6289 +7443,205f2aac5ce22a8d +7444,d22177dd5547dd73 +7445,1f2f0bd5167efaf9 +7446,6492606090bede0b +7447,54adb50ce38cf89e +7448,33564a7e2ebacb2e +7449,be44a042f604c9d7 +7450,d2ba9d8d0537eb40 +7451,dcbf1b34cff95e0a +7452,2faa7dde7d839f74 +7453,4ffff91abaccefcd +7454,b185970e9490dfdf +7455,73319e2444e89b51 +7456,378bfd1c8b19a236 +7457,e0f2cd3f570cc7aa +7458,1b9a78923ddc7caa +7459,7f0442507440372f +7460,c9163295531ab856 +7461,366b6934ade2a2ce +7462,4b9ae85ccaedf4a0 +7463,d5b13bc9bf224f02 +7464,59daa35ca36be12b +7465,23bff3d8837a6f07 +7466,cda02f2224984158 +7467,84bbe1fcfa35ee86 +7468,bb6917c6adbacd9d +7469,d6ec655a84491180 +7470,667640311fd01346 +7471,66baa1beec2bbcb3 +7472,15a38ec137fc0d1a +7473,d6c463215b90511a +7474,9c9015137e70b0a4 +7475,58871b3e5fdf84fd +7476,b9b88e4eb8266927 +7477,25db6e00d8fb66fe +7478,810cdde6c36ae198 +7479,392e362ff87302b5 +7480,f7543ce97f5879d8 +7481,6d5a12b611db27f4 +7482,8d9fb75a394d4550 +7483,ee2c0a78c676530f +7484,bda9ca71809d2020 +7485,3de09dc31d6812c2 +7486,16c5f29bf73b8919 +7487,93abd4cba2b9f0e3 +7488,a9f8fd6e492a818b +7489,7f9e77191e4558e5 +7490,508d86a10a8e4a93 +7491,4b32a0cd984cef58 +7492,0a47262836c4b134 +7493,50ec6f793e61d02d +7494,d75d2ed09ba7b883 +7495,c7833454c1f73325 +7496,bf7f512b0e090e0b +7497,1b0b7b1a1deb531d +7498,af0013d76f913ca1 +7499,1b55f33ac9d624c3 +7500,77136f4f48d82878 +7501,243930be438656e0 +7502,62edaff911a29e76 +7503,fe4ca0ee7ee4d383 +7504,0b9cbcf57c7c98de +7505,cd1d39ccc6fea25a +7506,137bd960b941780e +7507,ccb8650dc1e40b48 +7508,edb18ca744588b23 +7509,67f54452c15fa43d +7510,b1563297addb7a10 +7511,f1ce5c0eeafda572 +7512,bd6dee80a92906f3 +7513,a04fb3d422c52b6b +7514,41e7d83ef99981f0 +7515,082ce32c0e5f0d8c +7516,65bfbeff7e9878e5 +7517,36bba00bd14c9893 +7518,c913ad7054f07188 +7519,ab11d76ac0b435fc +7520,7fc1290c44b272af +7521,cd79d16367e5c4ec +7522,b0e6ba3b890e9a10 +7523,0cb5fcda040e166b +7524,526b1dc4130594ad +7525,73fc0b5c3aee29eb +7526,d08950f60fdabcee +7527,4ce7b893666a8f5a +7528,53b38662a9bf3d58 +7529,662fa121f3f7c4f9 +7530,4d31ecb51424724d +7531,c7f52b26094469b0 +7532,99a9c93bd37a9673 +7533,3050b519a8bbda66 +7534,e8683e4849d6c251 +7535,a8e046f5e43186de +7536,e6b0f27a2cc53d21 +7537,22edb81897829707 +7538,fabe02e2f7925614 +7539,4a5231fd403301b5 +7540,aa294568a74fcebb +7541,85ac718b0f2a3b92 +7542,010df7d02cf31465 +7543,15a528f3b2aa7608 +7544,525fa708f661a0c4 +7545,e2cebadcef397080 +7546,da86a4606008cd96 +7547,472f709d8d6f30a6 +7548,8a658b5fbadb1230 +7549,6a063d5826c44735 +7550,bc59ef88cc18e0fd +7551,060c753c22fd07e8 +7552,6803a57fb240b1ba +7553,1c378ecd29cb885d +7554,3a1227bde5e2035c +7555,61039794b9f90205 +7556,fce41e376c57a9b7 +7557,727d80fcc690f7f1 +7558,8d884c7fa23333f4 +7559,a7aeb25f7d62b4a0 +7560,07821bffcb17800e +7561,9fe99cf6dc705ec4 +7562,0034e6dc9eca7488 +7563,0b9b7873448ffa8a +7564,2e974564e855cb0c +7565,08507ca1e1d94090 +7566,65daaa215403c411 +7567,88ea892179eff7de +7568,e183538938e5b05d +7569,1c766841cda74501 +7570,1e634a53e17c96e2 +7571,cb871e17f38c7f07 +7572,85c61a0d767bfb3f +7573,d2c9bf179da35c9d +7574,bad2e388c32e9812 +7575,fab24ad376ac6296 +7576,1aeabe28975a575f +7577,50fbe1c8b89df20d +7578,b835624177f07ac1 +7579,51abeb526193b2e0 +7580,5376eb4891e04d06 +7581,8cfc815a62cadc7a +7582,188f38114dea42f8 +7583,d8b6de012a4e4b6e +7584,59948295537a2139 +7585,71140d3d905b2d12 +7586,93f0f28f54ed4828 +7587,c9bc4226df60879c +7588,a6e055f935984dd3 +7589,3a2f8e2a7b42be2f +7590,56430d64e62a40b9 +7591,5a6875591fb8a034 +7592,c7cf90ca51d23135 +7593,9dce74accd262350 +7594,7423cc49e5d38831 +7595,dbeaff5477b4e206 +7596,3597859700cd1cc3 +7597,15657ce6e8d13726 +7598,c9f3a533a59887c9 +7599,265dc88b2c522bdd +7600,c3536b7bcb72fc44 +7601,b396cbf03a59e36d +7602,823e575caada04e3 +7603,0ab11f29053a1a43 +7604,a568eed360a80010 +7605,fa94bd58e1765047 +7606,4113723a7f337bbb +7607,d9096a01577e54bf +7608,7a7ce1ce5bade54c +7609,dd8a2eed16d51644 +7610,caee5a51f0930bac +7611,934a8a46634392cb +7612,fa0ea737cd1e4b07 +7613,4d31fc39d1b2b96e +7614,31fcfca4a6f0a709 +7615,d8e5a308a473d173 +7616,e177bc2ec152f551 +7617,7cf7366298f9de95 +7618,fd9ed9718c329071 +7619,58f89aac2ab7ea5c +7620,ced79144ba018128 +7621,d595fc6f53b5cc5c +7622,8ac28fdd13476fec +7623,356d331b48e24823 +7624,920f5180cad9c6ec +7625,17a7c388af196eb9 +7626,28219a01908390ad +7627,019a6d0a5703c1dd +7628,a73b7f826788ef79 +7629,b736665ef23b16a5 +7630,9f6a6b51fb02e74c +7631,2508e0faef0878cc +7632,5e3e17f409d32d6f +7633,ceb9d5ef6e2af32b +7634,8304d5a0fb402a7e +7635,243d6988dae57e60 +7636,265c7893bffb0ed0 +7637,1fe7a64fbdb3fa11 +7638,b5392f4ae26cb72d +7639,a54d5c8cfce66156 +7640,025c63d7420ebaa3 +7641,3c2cd9beb0236e50 +7642,02a4179708cbe84c +7643,661a6c3fd207676b +7644,94e96f190187506b +7645,4db95824bad4ebe7 +7646,7cfe779e680095d5 +7647,e2db99032e125703 +7648,8640e75acd92085d +7649,79db72a4ac7487d7 +7650,2fb577ac67c56085 +7651,869eeef8b38b080a +7652,8a83d2338ff3b089 +7653,51ca65fbd8f73160 +7654,c30268c2d321cc96 +7655,cf586dc47cce7028 +7656,d01198fbe7123edb +7657,7d4e2cfca7c19382 +7658,3a013048a972bd91 +7659,74487468dacdf775 +7660,44f00e334296ba60 +7661,f684d4112b7ec0a4 +7662,33478c9c3fc04a2f +7663,6b144cdad65b16e8 +7664,bb6b31cdd27aa00a +7665,ec103f265a414596 +7666,b2819b68242149f3 +7667,ec1923783b1236b7 +7668,fefc4c59bcba05b9 +7669,ea923126bcbf8f26 +7670,305ab089715b98ad +7671,55b261e8c8b4e3e6 +7672,e9bebcbf674be2ee +7673,3ddf5aab930c247f +7674,6d85b6c73ded80f2 +7675,4913d0823c452d34 +7676,7d800a78bcdcbf28 +7677,9ac71313e7177325 +7678,611db462f7ab85fd +7679,e27310a82861b6c5 +7680,12d3e6060ab2ee26 +7681,9022bffe32ed348b +7682,b6bb1b7a7c2f23d7 +7683,953740c3e2569931 +7684,8c7ed86fb4d67dd2 +7685,e9e328a7bb9090aa +7686,9fd35d82aea5498e +7687,323690a7783ccd91 +7688,b4db21be5ddae965 +7689,2b6a52025f971173 +7690,419c0218c3941ae2 +7691,ebfd272413018f9f +7692,b6f7a9ecddc06e2c +7693,6bbebb34e93c9ef4 +7694,5abc38df08dcc89e +7695,2f389ec03b2cca0d +7696,a1a50bc7a3f8e0a8 +7697,a83abd8d181449ca +7698,bffbaf673eca6462 +7699,4ddc943798656505 +7700,a3dec9fb26da2d10 +7701,1ebff7def5c72fbc +7702,cc9cc19647013b9b +7703,9a19ed258d071ea4 +7704,2ae155ce6315f124 +7705,f914820e5b735228 +7706,d1d5e943d9b597de +7707,7658cb0760651772 +7708,9d033b07e0d0a147 +7709,33d38f18ddf50349 +7710,fc9ed9d031a88c22 +7711,839c9426bbfffca5 +7712,c01e107e05854e6d +7713,b9b38a2e7b958497 +7714,7ac77fe56e504ba9 +7715,ffef7df6aed41248 +7716,c724b147682536bc +7717,ebdfb132635fcc61 +7718,1b41e2652bbd1090 +7719,d36edaf567c89a93 +7720,b0cfa1f406ed7691 +7721,c657f2559bee10fb +7722,2490b68920b445d3 +7723,3d2df56718c8ad43 +7724,12802806d2b591e9 +7725,1dc34210f398df9b +7726,9b05525fbf16083a +7727,59b94b50ac3a6c4b +7728,7a1c74a8f0993cef +7729,1ee82d535ba04e25 +7730,7caf805baadc32ff +7731,a4dfc703932b2fda +7732,4c49d833bb6a53a6 +7733,033c341c78cd2cb4 +7734,6f9f3695a75817f7 +7735,fa134ea63d24d92b +7736,e93e43ffa2aaa4ae +7737,27a21ae56a28c76c +7738,1b86ecb2624357c2 +7739,556fded5dad717e0 +7740,8e11e469de1d6b00 +7741,a964ea922d4b6424 +7742,3bc80fc74a4de735 +7743,31e7b9fb49d174cd +7744,4fa4b58a2e8f4347 +7745,11a998300428b89e +7746,8f7ba0bac5e6bf55 +7747,d2f3eabfff3525e9 +7748,81f6af28e6781e33 +7749,b0eb36b72f6292e9 +7750,b283755031b9161e +7751,3cdaa3c774db92dd +7752,f14b6ac0fac01090 +7753,32e1059a68e1e0b2 +7754,d4871ff969730503 +7755,ff3df61cfb5f0720 +7756,b8549b27d62ee0b5 +7757,f3886e197a789122 +7758,0d1eef5fa9831944 +7759,095abc220189622d +7760,1397cf63b26aaac5 +7761,abd0bb9b98eb90ae +7762,7fbe32ef41b793fb +7763,800b535de493f425 +7764,0038996d9bf04541 +7765,8445226e11d5995f +7766,1f330b3efe692c4a +7767,a1d7abae8912ec51 +7768,c17f4da9a3516110 +7769,3551ccc8d4eae56d +7770,b152958bb0a6a156 +7771,94365b1070b2d5d3 +7772,6be087f55f172703 +7773,6a319e2297a2a35f +7774,3f0fc770c98a31ec +7775,42c1d28f9425a781 +7776,609e5a83c31c7dec +7777,e35a8145408635b5 +7778,4658e8adb7d6e82b +7779,2c987c6bdfaa6bd5 +7780,63c00e87daf6cad3 +7781,0357b18e4dcce36c +7782,eea863d37bd654c2 +7783,998508f0a1eea437 +7784,278dcba227dd69cc +7785,8492ca03e2369b88 +7786,bb4e2190f4b899da +7787,1e045cfa925e2a08 +7788,f681cd157663d0b6 +7789,e4189c7a591f580e +7790,f3bc39fd791875c7 +7791,4fa14c3d3ae1040e +7792,31fdbbc633bb405d +7793,22959148e1b738ef +7794,34007adff12f5c69 +7795,fcb32ed97de9eb6e +7796,95b7b1e6a940dedb +7797,2acec991c7f58692 +7798,887f3ea28c08c1b3 +7799,43e4a0b4503adbb9 +7800,4127fbe331e72416 +7801,0df1aef892caf3b2 +7802,a7e0752173b30894 +7803,130e54dd0eb5b8f1 +7804,de8fdb1ad2fddc69 +7805,271eedd454bd21fb +7806,2ec35d3005bc1fdd +7807,5aeda447ac85e2ad +7808,7ed30994519ead66 +7809,bfe55dbe64f32970 +7810,f3011e621c83ee9e +7811,9e5ba1462a758206 +7812,f81b2b1d426b8727 +7813,fd58fbf385d720a3 +7814,0c596c41fcfae56b +7815,7ad0ee39656d1d91 +7816,a43e80225a2c7f20 +7817,28b81c99a396d889 +7818,4406408d1a170ff4 +7819,2603389bb989c585 +7820,90abed2bbf0af6b9 +7821,58137f3b47c57774 +7822,dfc403fd5a982865 +7823,b87e3ebe8e785b79 +7824,2386b03c99af98d4 +7825,7c4d016eacf215d1 +7826,e0c986d5f61b7b4a +7827,8a1bee5daa2ead4b +7828,d0da80de0fa4811c +7829,1498300b9f9dc5ef +7830,443f8a4e8bb12cdc +7831,9e728faa592ea286 +7832,2e156264e6fd2735 +7833,15aa63560680e192 +7834,42f4914977f55001 +7835,c269f4f3d639a247 +7836,d64022aa8050c7f3 +7837,0067e43f09a7d1e5 +7838,0dd64a0ed791591f +7839,4652f77fad96b6fd +7840,1f139ab17fff41c5 +7841,633968df477907ac +7842,248e2334688c35ff +7843,f66c00537c6704b6 +7844,6bd2bc74ab1e1e1b +7845,f6fca5ea20823b43 +7846,5992e13c2aa77f22 +7847,68c8c1703385a9f3 +7848,0cc422a567b8c9f5 +7849,021e675e65221215 +7850,ca24f822e073a109 +7851,874e2e5ca4b3cea3 +7852,51ff19c8da79c706 +7853,65945b9e9acdfe36 +7854,6acdb8861e74aa37 +7855,07c295e897797bb4 +7856,041c2a9ad1f3179b +7857,1c05446f2179a13c +7858,0d1a720d871ea5fa +7859,eb66179bfc3adef6 +7860,e06badf36dac0402 +7861,1a3a96385c8cd26d +7862,90ef389f6c7f8028 +7863,6dd59b4c56b37cda +7864,18e458b4211ac18e +7865,c1cc1cc6e0a0e4f9 +7866,2db93ac96897f01a +7867,2fa85d302e9f81fd +7868,fd03c18e575ef490 +7869,c36a7f208876f510 +7870,0fc601c8afa25a55 +7871,17a7aae8b17990d2 +7872,ab0e15a29b65d9b7 +7873,cd2dde05573356f7 +7874,549154c51f0cb866 +7875,0dd6c720db659dbe +7876,263433a83d52fdca +7877,7d7516fb3802c00f +7878,07cf328c7802e492 +7879,75f18ced975e6b04 +7880,0f316bcb07cf5f86 +7881,2c8ce4c09f3eb8ba +7882,bbb3712a118db1e6 +7883,32296a9296a49b7b +7884,c3f8c6805c0dbde1 +7885,bce4077d2b0ed646 +7886,3057dd2dd3fb858f +7887,32f711fcfac71d58 +7888,872fa6af0f27e71b +7889,b9df5f54384df75f +7890,d1d265b43bc6d305 +7891,a15f737a872ea8b2 +7892,59a56ef2f877184a +7893,285d127f0ca20a94 +7894,0b288ff67aa8a61d +7895,a44da973cf7af322 +7896,7b4d43752b6f336a +7897,d0f7742f82feb1db +7898,487399d49b0381f6 +7899,acd2ef0ad4a82f2f +7900,5c1ea8e3e9dd1fc7 +7901,dd91970a391928c3 +7902,b253f4aa390e0367 +7903,4742a2eb91910ae6 +7904,4b2bf78c99199bc0 +7905,2d9a99f3f18819bf +7906,3a39e7c1d9378c6e +7907,7098c54b425a9d11 +7908,0381dfd77d7f4266 +7909,746bca7e06197b3b +7910,14a46b4a8147833d +7911,09ef69c14d1cb81f +7912,4938385fa1cf646a +7913,dcd9e0c678df988c +7914,dd25ed014e2d188a +7915,e4b9edee8025d2fc +7916,b39053d70e93a8ed +7917,ea6a7f155f21a5ee +7918,1b98f2dbb68ce624 +7919,03f9bb49b2fc8223 +7920,a930e89eda2e3bd3 +7921,d0a5b55515f3cf5d +7922,f9b90f39c86bdeee +7923,08b1fabaffc164d2 +7924,ff6791da73d0e213 +7925,35fef9cf516b6e6a +7926,d11d01fba232c043 +7927,7784df17ba064bdd +7928,f61b013f0e753dec +7929,e65c84279b6d41f1 +7930,65217b750a6e0346 +7931,4e36deb250e52440 +7932,aaf91e34cda8b706 +7933,2b40657ac8ad9fd9 +7934,0f0a016b1926cca9 +7935,f0133215dee86f85 +7936,dd78d4443705f35b +7937,62d94d58270153fe +7938,aa8f71157c3ca2d3 +7939,a3ecb3a7f83cfe9b +7940,9c867832b44afe52 +7941,9b8f5a51c21118ad +7942,1adeeea4ef4c95ca +7943,b09022a7a1da540f +7944,1d1697531797992b +7945,8c00877415038a45 +7946,f02b1b02830c513e +7947,a0633469463bab04 +7948,72400b18a8ce34be +7949,7633949ae7af510e +7950,aa20ff0b646d5430 +7951,3bf0735eaecd8c09 +7952,2d08e82a58a5c51a +7953,6b09ea74d5c933fe +7954,8affd564dc410989 +7955,3f56e894c4817553 +7956,82277c5adc0cf18c +7957,6c03aadeeea313ac +7958,b2984d4c479c292a +7959,d7a63147b901e58c +7960,b1556581d0a021e0 +7961,29d3f383345ef9e1 +7962,39c406e7b020ddf6 +7963,9d5d943d9b482724 +7964,17bbc142d7d3f7ab +7965,040fc9c133abe23f +7966,e45a3a937f4ce23f +7967,c6744c6d2f6b3347 +7968,8ca0978281d7fa8f +7969,9a9f19dfc1e07228 +7970,dbbde7b4a5c4a34b +7971,0c52944e3cc62961 +7972,443d2bed9153364a +7973,1d24a4d38e8cbfdc +7974,f4cc55b5172df08c +7975,6d0224109a9ee715 +7976,b2d2af3103961ed6 +7977,c591b6cebb472b5c +7978,fe1e55b5f7b22db6 +7979,9c5edf92c667954b +7980,cf863619552dc3b4 +7981,f3a4ea6da34c959f +7982,bf0d88d3ed96a0ce +7983,5ef6cc9bb4065446 +7984,7d027be401b7a04a +7985,42d125fe1725fd4d +7986,8647be1fd6be0b21 +7987,6617b5119fd639ff +7988,32737ea9d1130f49 +7989,a91781432a2e5181 +7990,23784ad9dd021ba8 +7991,0274940be2ee3c41 +7992,23dfe305b38d0bcd +7993,04656b513b47060a +7994,ddc74ac148f915a7 +7995,55df71ec91270481 +7996,230dde296d538672 +7997,c45c5e2a433788db +7998,50104b52a6b16cf8 +7999,c315b8c462e1cb61 +8000,93f804dce1d65638 +8001,43958fc31c0e45d8 +8002,5921d6cea8b1ad28 +8003,bd25f78bfd46651b +8004,8137bd23f0db88f7 +8005,69dd1e291290228d +8006,9f838c66bd56fc14 +8007,18554dcff4dae951 +8008,3a4e6a8390b0f7e8 +8009,8546d556e5b4df47 +8010,189d5e7e3c90e365 +8011,673aa83caa70414b +8012,2315540aa9af471d +8013,bc3984275655aa73 +8014,96f8bbef81a88fe4 +8015,2296144dc1b9cb5f +8016,fc4cfa7f6a47516a +8017,f9e443baffbccda8 +8018,278004ca97cdf0a4 +8019,9ffc28763fcca17f +8020,9277b21cd86d30dd +8021,dff1ad4af24e6a54 +8022,dac873b463cc5718 +8023,4bb27c922d15933b +8024,aa2758902a1de15b +8025,ff613f39591fed86 +8026,0e0c1a756bbb890b +8027,6df23076b29d39c6 +8028,2100e203babe40b7 +8029,e861d0c4a047a581 +8030,02aa639951603b20 +8031,0512970224c61930 +8032,9c138607fc66ad30 +8033,d329556b1df3d045 +8034,e0ff48b344d025ec +8035,2e2f434a212ce6c9 +8036,9a3662eb344256e4 +8037,58016cc04177d9d1 +8038,dfab5d640f627436 +8039,f1c7806a317db4f1 +8040,98c4242321fdb8c5 +8041,1ce0cfe1d35328d0 +8042,b11fa7253cef66c2 +8043,5c2869fde0416fa0 +8044,8a472a0ddc8fd4fd +8045,4429bf287470d8cb +8046,29517ef955c56bfd +8047,8d5e16807d0531e6 +8048,756c8d217e014c59 +8049,af403bed1582908e +8050,38878c8adeede552 +8051,f5cd0d5c24e96354 +8052,3621f8c36aa7df5a +8053,6574a49d0d34ef1f +8054,d8c79e10a92d91e3 +8055,d4b98b43a3a3d60e +8056,cd7128204b9b30a0 +8057,2424a84ed92367b3 +8058,fb013e2172a8ebfb +8059,1c3c7d84443c87bb +8060,d71b8d9314e2fbf7 +8061,ec19f78bebd4e2ea +8062,fb39c20b8fd06e27 +8063,a2dc63b7d31cc2ab +8064,0292b35f68bccbaf +8065,8c791d39581c04f4 +8066,c9b2704f50eb608a +8067,365981bd4627f400 +8068,4853586b032f3011 +8069,f3b53f8ce87851e5 +8070,64c668fef638944c +8071,11ac92b77bd103d7 +8072,6512efe528041fe9 +8073,97e7ba7498e23b33 +8074,00c5d088969789e5 +8075,acb364cce7196d8b +8076,ff6458e4c1e4c236 +8077,2308b5431e8ed481 +8078,0f6f4ce81b701c72 +8079,4a97b33ff881d2db +8080,300205ad6571d27c +8081,5053dda885e05669 +8082,cc0485cec44acf1d +8083,578fb02a07edf530 +8084,d273ab7b66a0be21 +8085,779d4a2b5717148d +8086,c37e463c9821d497 +8087,88cb5a40c2242a4f +8088,2f0da3626f0cf89a +8089,c5df6133289db165 +8090,7cca4f83e7bdf8bf +8091,88b1eb5caac862e8 +8092,4018a7c7157f486d +8093,88563fae56f5ad46 +8094,a8985fc1e8b21a71 +8095,79739e8018f12d63 +8096,da9fd461a246ec76 +8097,92972244ddbe3493 +8098,38d3ad38a61f0486 +8099,2bc26c2d8f453f7f +8100,aa27191fa7d0c5ab +8101,db0bda42e399c9f1 +8102,a9a6396c1eb70083 +8103,048de87c3f1e7af5 +8104,95adfaeaab7f88ec +8105,14f43a4d20137015 +8106,4a1a2a29d1e7ad7f +8107,96212f5332cbd226 +8108,dff66e4562e97d1c +8109,56bc2ee795511a3d +8110,0ae39c39ee66d912 +8111,8ad1970c328c2152 +8112,96ef37ecff569813 +8113,67c16a2733942b01 +8114,8e4d1e53edec3516 +8115,5a8f3cbe29111e99 +8116,a92c58f4d8bc8d2c +8117,cf20b8ca92a16eb2 +8118,b511806cf2d27188 +8119,36ebd69d12a18c3e +8120,b5a99bea52065e96 +8121,b7b7a4d8701daca2 +8122,c83da2fb25482d27 +8123,0171b73d2347056a +8124,56954165d9a090ac +8125,ad376e7afc92c647 +8126,b2fef6ab79cd0ad2 +8127,db60ff6937a4affb +8128,42e7e93c0f064eed +8129,9d433619cd52a089 +8130,50fa338aef9d20f1 +8131,829d0f0b5b8fb26a +8132,de22b2991d9f8aa4 +8133,e4b9de111f61c1ca +8134,9808b126ef3a650f +8135,bbe61bacc477c970 +8136,6e71210b4ea0ebc3 +8137,44266bd954cbd553 +8138,d12509805099dd52 +8139,1f129ff825e2ea12 +8140,dc555517438a3747 +8141,a812515efc02d8ec +8142,5693166dc22af846 +8143,5bb607630d28051d +8144,5cdd1c9d2e3630f8 +8145,379d25eb09dd45ca +8146,7e0960686a2c3618 +8147,895688948b832b50 +8148,8094da95ac96b1ee +8149,0f6c200174a70460 +8150,225dfff27fe72784 +8151,a704a91680051365 +8152,7653ea505cfbb311 +8153,bf19605c6f72b78c +8154,057a248faf43d43f +8155,6e316e86e48de245 +8156,297051a5899f47c7 +8157,308c218defbe26d8 +8158,c2a4fc08ccbd55ce +8159,1152120213fa0895 +8160,7b8244d0b9d83094 +8161,be409dd0d2da0892 +8162,0c8d40e7f7df08b6 +8163,5f50a307c4bc6a4d +8164,70476953e36dafa3 +8165,01b4638b9b4f02eb +8166,1a0a62eee89838fb +8167,e6171df498b2d1f4 +8168,9188fbb668700289 +8169,13c0904a18d16f58 +8170,d46880aaba2a0b75 +8171,300652b0824c69cd +8172,c8dac44078aca5e2 +8173,c07c66b410f7ea24 +8174,1672add9ee30da87 +8175,14b403eb6b697c00 +8176,c1ee33fd47d6f11a +8177,0187aa2b9d2b07b6 +8178,d611a2fb64888d38 +8179,a16974b9449a8f90 +8180,e3cf4d4add657f0f +8181,940cf18ba8fd4d75 +8182,536abc13e576a277 +8183,16c6136d325bde34 +8184,eab43bab01bdeed2 +8185,120a9f139232be83 +8186,95077320d1d133c6 +8187,6ca73459318ecf0c +8188,65ad6ff99a00d389 +8189,e617d2d8be4971a7 +8190,c417e2c75a3e1deb +8191,b6b6bb9084302d2d +8192,c8ea0129688558ca +8193,b304dee059f6111a +8194,ad1f815b84795766 +8195,ac665402549257a7 +8196,600783a2b296b193 +8197,932e35894041b9f1 +8198,062ab0567955ed19 +8199,d3ee2f69cc1aede4 +8200,65307a5e573dc638 +8201,d737536f8f28c4fa +8202,a5d2280a7fba4468 +8203,768758cfebea62a5 +8204,23c119f5e668e8b8 +8205,260c0701fd9cd213 +8206,576e14b344d8ba96 +8207,be94a39aee8c7f3e +8208,3bcf90e1a8bb80a9 +8209,31d0bb14d3a857f4 +8210,de69341f96314134 +8211,13bb47e16c63726a +8212,760a57b9a5598081 +8213,d66e306f586046fe +8214,2835cbad695fde38 +8215,9b7d804ac83e56c7 +8216,dd8532ccb620ba50 +8217,ea673212423212f0 +8218,6d94224e44bfee1e +8219,11cb88d9bf775ee6 +8220,096567757693ac26 +8221,0a542b48d80e0d38 +8222,e4f5594c905eb5da +8223,f15a9177be486db1 +8224,8be167134687442d +8225,b05205361abed2cf +8226,cb3952761c20cc61 +8227,7419738a9254a0c7 +8228,5fe5d971629e2980 +8229,a7733bcafcfdff07 +8230,66f1faf1f2fd372e +8231,6f12e9f4ca20fadb +8232,96bc702552e7607e +8233,2c92866aa566c966 +8234,c68a0e0f73449d93 +8235,55b59ac17fcc997a +8236,41e6f34bf84e9a23 +8237,179ab61e506e55af +8238,28536403ad0a4802 +8239,8afe3892550af1e3 +8240,fc06111d51ce21d7 +8241,24b586029f9c1845 +8242,ecc5d1075ea23dc7 +8243,7e4f7f0cd9173386 +8244,af2eb17fd6740a26 +8245,6abc370a1838cfc9 +8246,2a23a9e4f2eb0673 +8247,c30339e424cb658f +8248,8378357353da7f45 +8249,f0df2ffce2dfc4c7 +8250,0ea7e9166ad163b6 +8251,c69ca6ba2b4a3d49 +8252,d36498ca9bf6eefe +8253,e1edb717175219a6 +8254,578f0bd95139b71f +8255,1e6011b795ebc688 +8256,1ebb906c7c9d3d51 +8257,91bd3fe416aa79ad +8258,ad0f2ea3d52ba8bc +8259,d94f7085b406814a +8260,d11a25b40bef15a7 +8261,4dd9ea7feaa77b52 +8262,37cc7c323be96696 +8263,adcdf42d3508267c +8264,dff18a7ca9b8067d +8265,2cab68afdbdc4678 +8266,9746d3f1463f360b +8267,95deef2d3f7684a7 +8268,31b413cb618f96bd +8269,1dd680beacbf8f02 +8270,63007c51061ad3d7 +8271,33438eba8ea9ea89 +8272,fd866e13f2bb258f +8273,844996e2e5db021f +8274,e62d2cc772ea07a1 +8275,7bbc051fbe438e54 +8276,01afeb6a36f2cfca +8277,4341e4354bdbe932 +8278,5117939fd094e4d2 +8279,aa55eb4087a99b0e +8280,c2d77f1eb029280a +8281,8b988adfa3f4d628 +8282,3e4cee1660871941 +8283,5c820ebd85eb4990 +8284,a0a6d1e221c03f39 +8285,e89bd79be5325e5d +8286,9caed69a5dc022a0 +8287,3e157ceb3602fb6f +8288,55a7bbd59875a5ea +8289,7a0f6f3608026c17 +8290,e9df23175bd79d24 +8291,fb63ae8666a0e17a +8292,0b61511b9635b011 +8293,b1d6cf04447d925a +8294,82927a919d0aae50 +8295,8a84cf42c09b55d4 +8296,96953af4437d10f8 +8297,55c6ac93eb590167 +8298,e635d37151b3fd1e +8299,e619af48cef8a961 +8300,996458a0aa6a042a +8301,5b5354957c8eb1c7 +8302,218ec743ceb39ced +8303,133ab9b07c1df81e +8304,87f1ff301b6e4ba1 +8305,cc4d1571feb99aa8 +8306,79e490f6c3a14be0 +8307,aa6a28644d4c4083 +8308,554ecdcb5d8ee530 +8309,bbf1e11cb14549c6 +8310,031a094faa76d26f +8311,15a56b32a1279486 +8312,f7b68db6d7cbd293 +8313,f044eb5c508f70ad +8314,05c5f6b74ae868aa +8315,c4b4baaa9072f7d1 +8316,231571734fd6c5dd +8317,bd89605d1127c93c +8318,eb67a3e2c41f98a0 +8319,ebd674e51c948fd5 +8320,c34ac3b95a47cd89 +8321,5eaeb2e142d271eb +8322,3171756d8483f21e +8323,816332ac1f31deff +8324,453e6ff3bac1480e +8325,885cbab5198d853d +8326,22614f45a441d7a5 +8327,759a0ff93a41c12e +8328,e4373ad8c3c8d765 +8329,7aea8cdfdb28965d +8330,2fe1f1a40218a82e +8331,873ab9bcae790f5e +8332,92335dea5d66bb4d +8333,9afd16d3bfd08b74 +8334,54c2574703265ed6 +8335,c241e1c74e227047 +8336,14f9c3d99d69a354 +8337,8da49150cee5f231 +8338,c04e1a5f73378ffe +8339,4183f86ef6b1b1fe +8340,f1159c04c5c10d13 +8341,bc8af90c27d5e353 +8342,755fdbf01590e6d7 +8343,dc27dea6fd0c1b0c +8344,72fea0af95e96603 +8345,40746c3fe99ea362 +8346,f8b1bc3553e61935 +8347,dc5df07634f68f1a +8348,2b55b245c579176a +8349,e1af3fbe0cf43027 +8350,63b50cf1b2e238ab +8351,d6bc2b71bf45cb6c +8352,3b548fd022e8076c +8353,e4fdec9c2dba30fd +8354,0ef27c8d9ce9bdee +8355,622ea0b2618b2cb5 +8356,9b537386d18799fc +8357,061b8f64cd01e9d4 +8358,6fac6e1f8df6f480 +8359,292e66119b82f1d7 +8360,baf45ab377d2bfc8 +8361,0dff72e3e15312ab +8362,db5e3231baaea2e6 +8363,95e98694c288f7e2 +8364,3aa866d66de1f435 +8365,4139373e5cba420a +8366,9b662eec41226adb +8367,d2e3f22a6e14a874 +8368,3f91020b27c5e0ad +8369,413b84ac93210911 +8370,bf0b748a774ca5d2 +8371,569de77434291920 +8372,131f1efd68cd4178 +8373,4bf0203ef21bfa51 +8374,bc8dc982e90d767c +8375,4053449c16b258d6 +8376,f1fe446a5023bee8 +8377,d8cf4225b6c0d498 +8378,38d975b8cfeca587 +8379,a07157c0949cb9f5 +8380,3b7c0cc0b37081de +8381,dee4dd8f608a4f50 +8382,07d030ae4c9dbc1a +8383,4784b5d54dca4da1 +8384,3826145621e350a7 +8385,68ae299cc31b16a5 +8386,d5f0670540fba124 +8387,1395ec2fc8a69a12 +8388,f818772f41e0ea70 +8389,40cdde07de00e16c +8390,43ef81a55377025a +8391,9e7771d103e5a07f +8392,c9aba04b09861efb +8393,f156e7af01287715 +8394,decb60c2b6a239c1 +8395,87c573892c0376a0 +8396,62e8e9548c4862fb +8397,c54c668da19b1356 +8398,a6c507e11caebb45 +8399,e4a7f7e470d99269 +8400,0a560d708ef03df9 +8401,e2b0838c6f860648 +8402,39c70c59c3dfc160 +8403,ca246550b205f7c0 +8404,6ee946acf5ede1ec +8405,8a8dd6a398ee5cc4 +8406,8f6156df66533bf1 +8407,e13da0ac03d6c8e8 +8408,6f942a1d5aefd04c +8409,331d76da22d3c7ad +8410,3800b5bb0f153e50 +8411,e49e1e2ca9a51b2c +8412,aa9b2729d95be7e4 +8413,20bf4627fbd0b43b +8414,f8431e4a2ff7679e +8415,035f5c1ab205af10 +8416,0eb4bc75b3c8c021 +8417,9b1a84d14cc0ee2f +8418,ffeb1a18d03bce6f +8419,a4e6c73a09cda8fd +8420,3500cafc66c7b277 +8421,5021e3f070898bcc +8422,8f74dda9f576ee37 +8423,27cf10511fe04502 +8424,6fea1172ca008861 +8425,8fffb75790e7cc90 +8426,88aa64e29eb7175a +8427,871b4c03a22d3d51 +8428,a50ee5a1dbfa42c8 +8429,e4a135e9e0565ff2 +8430,0feb7798e6f5a528 +8431,707cb558e124c086 +8432,81150b19e64ee5fd +8433,461386ac230a5087 +8434,8019028d9d01ed60 +8435,0e011ad9241cff21 +8436,dbea7ff3ede8700d +8437,41fadce8aff24b32 +8438,683d5b3a4630c63e +8439,9501b34f1a2142ae +8440,6182ef96644f1971 +8441,1129f70b4336fa03 +8442,5cb5e3227cf349bf +8443,0ebaf519527b4f9f +8444,67c22f2d38d4ea09 +8445,e319f0342b6f40fa +8446,3672f47b06e2b54b +8447,52e491c58d49acca +8448,bfa3439fb3d98425 +8449,eecb64560cff1c11 +8450,e9cf93db55ce61c5 +8451,feb6e544aec4ed56 +8452,3ddf266ea7d570e4 +8453,805a082110666cd0 +8454,63c158dffc37c42d +8455,16872594199a1be4 +8456,30bac6f33ad1bb45 +8457,8ed572aa306600ab +8458,c164dc5c2a04338b +8459,d097dd48145b4bd5 +8460,8720bd02c0548e74 +8461,35023c589b4b31d3 +8462,2687d56be29b4a43 +8463,4f0ff85bd70d9fd8 +8464,b3cc1c0ceb53e1ff +8465,4f69bc7634ecdcd6 +8466,2218836651324879 +8467,e12654763c1c3276 +8468,c64cf6d2a3a6833d +8469,d94321fbbe9b7be6 +8470,8d8ee961195904b2 +8471,0d27e767e3fb9466 +8472,2bb09b9942a86162 +8473,19bf8f3fb64a9744 +8474,cfceb603c46b2fd8 +8475,27a5ee54c894c305 +8476,93f2a5f691ee7c26 +8477,67b9776cd9502c61 +8478,ca75b60dc9f2e9b9 +8479,1e485f5181910013 +8480,54a436cb70a6b22a +8481,104ac076aad4bd6f +8482,3c0599eb16b80392 +8483,bc77b608424fa36c +8484,cf3b28c4064f2df1 +8485,763d5b8c4becc470 +8486,e435d245a8beb3f3 +8487,c6c60e83b18f33ff +8488,f85d744f1f6dc1ad +8489,11d7ac1615783f7a +8490,68ef627871a13cd9 +8491,0180e672f556a4a4 +8492,af5b26a2705b38c5 +8493,bee336a047ae144c +8494,4b4836c3dea925cb +8495,09bf0dab7a0ae192 +8496,17490d5619a94486 +8497,1fdfa3a53e95afa4 +8498,8347900dc4482a1b +8499,fecb12e94164d5ea +8500,8364ec598fd9d79d +8501,4fad1907ede46531 +8502,91888e168581523c +8503,c2480a42f5e3172e +8504,5f6860f207525660 +8505,f9298d516449a561 +8506,99bd5d200faaa738 +8507,60395ab73f6aac92 +8508,bd56eef84e7127ba +8509,3a255dc823b7c220 +8510,b166e0e1cf58dc50 +8511,24e2fa1af71e2dfe +8512,6e02c3836fdc3cad +8513,f8d8efbaa4fdddf9 +8514,e8a88281563d2380 +8515,68fd5454dc379f46 +8516,974ce534e0de6ad9 +8517,8f41eb8d3d2146ba +8518,fcc992429b8a4e4e +8519,6e3d0210e1c13d51 +8520,3835ab97ee3c8bb8 +8521,13fafcc6dcb1492e +8522,ceddc2fa0c367b5f +8523,ae5f595c7d0ab05e +8524,f67faefa10c1d3b3 +8525,fae92ab05237c611 +8526,8ed5ca2a976c6004 +8527,8cdcc5d709837b45 +8528,91dea660ef7bf7b8 +8529,4cab6dd78bf821c2 +8530,2aff01a906d4b408 +8531,8439a672ccfb5af3 +8532,4d13fc7541ac8eba +8533,e2d45d200ed1a7ae +8534,22f7ee9627f36a82 +8535,f4845e9ea05874c1 +8536,8a8f1ac3a46514e4 +8537,826e0a5181a1d320 +8538,eadf9f5ab6392136 +8539,07e888adf88476c6 +8540,d8304b6652c422f9 +8541,6a9c6615498d6e1b +8542,dd5872d6d76ceffd +8543,0b102b9c8f5d04cc +8544,598724ac6fe15fb4 +8545,da15e553cc046e0f +8546,bc2bad5e57c64070 +8547,2cb673aaa2de40f3 +8548,76a420f52e00fefb +8549,ec60154399401755 +8550,9aba29a101ba3a7f +8551,aa1e10a63f1ee8d6 +8552,bb0bb6a005ed74de +8553,8c76ae40062e1c33 +8554,96a5cd8bb0b0c10f +8555,362fed371ba47aa8 +8556,7d5718522d011a01 +8557,57cdbbd05470a415 +8558,297277a2352806d6 +8559,c0a78e8e6beb3f3c +8560,18366fa067d9e79d +8561,af096ed39bd8f7a2 +8562,175c529f49b4f508 +8563,84d9496ec547bdb5 +8564,b565ad4f81f331be +8565,5915f4f3521097e4 +8566,16a0dde638c3075f +8567,6af52841dbdfdffb +8568,a4af52608254761b +8569,2f8cbd00acd931a4 +8570,6bc6bf905dd225bd +8571,5d139968ede90009 +8572,f3d908f912b3de88 +8573,db30c533445528b3 +8574,9c7f9604f0ac8615 +8575,fa2f0fec04a9880f +8576,b66bce816a86bdcf +8577,9927189009c257f7 +8578,eade37f75c1defc8 +8579,798713e267198178 +8580,b965f53f54255c05 +8581,6f1c8fc2fd17df48 +8582,5d8b5e4808accf7d +8583,e3499fd670371b61 +8584,49307fc5576d272b +8585,1b6ffc62e28278c9 +8586,b08a50e03beea34a +8587,aa5f76631d55b564 +8588,2a931a9ca435628e +8589,8318de932ca562d7 +8590,67aa2348a39287ca +8591,05f8a48886505e49 +8592,b7033d4d665177bc +8593,1695241b8eb190fe +8594,9f077aebb6944d64 +8595,2409263628252103 +8596,307d7ed94e3b162c +8597,a9fb5f7c26868f83 +8598,b8b9235594f9d4b2 +8599,262ba9fb6898978f +8600,172716250fbdfe32 +8601,dc84dd182ea542ac +8602,ca803575b26c90d0 +8603,50ad3094ab75a4e5 +8604,ddc5f09356934e35 +8605,4d1753aac45c9ad2 +8606,fc6211783d49323e +8607,abf2a1d294b1d78c +8608,e91d67373a3277ff +8609,b86e9e2ff1f5a142 +8610,6e9da693ea9a61fd +8611,720282e42036e345 +8612,aaa6984163b1c510 +8613,0214fe318b669ee2 +8614,86bea6e8418c76f1 +8615,9dcb9c4ab2467104 +8616,be9aca6469430354 +8617,d3e39ea226ece47f +8618,1d8ec2a8c0e5f10b +8619,711f25ea5616f565 +8620,c8dba0536e0847e7 +8621,90831d4c0b08c53a +8622,c2dd8400021920c2 +8623,c514895f9c14f03f +8624,4950c56e76ae257d +8625,6cb461c16644b39b +8626,bd54e758c48bf072 +8627,68f0b0968d6868c5 +8628,f294a92800d9650b +8629,bbc8f3800e26f4b5 +8630,a29a13d5a86b55cb +8631,67431d7eafac46b3 +8632,38351923ddcf5e4f +8633,1a197bfd6d6676aa +8634,17efac9a26a070a1 +8635,1ce425f4498d93d9 +8636,86a5c4469d5a0484 +8637,6a2b4a222a9cc5b7 +8638,a3d05ec2e252db1b +8639,558cd76535f9194a +8640,62d7178c1d3d7996 +8641,f95b9b822ba8aed8 +8642,ddef0055d8127b69 +8643,4ea23e42e963179d +8644,0d7c8f4fcda885f7 +8645,2f1278b470387e89 +8646,b97afa2f50a967d9 +8647,5935a1df86fcb63b +8648,61dee9b12198489f +8649,99011b3f5fa4d7db +8650,60b1083d726c698d +8651,6fe294de9465ed52 +8652,8ff93d59f1868e62 +8653,bacee019944424f4 +8654,ae88b4f497af56aa +8655,872a2541c2dd28ff +8656,54773d5a2f7ebf36 +8657,b94afe061fc14ac7 +8658,056f2fd6169e9df9 +8659,ca2b41a6ac3a802a +8660,f757a9c9d03e0fcb +8661,b93beddadd569aaf +8662,a4db83a507b2cf3b +8663,782dd93e4160e05d +8664,2542edc212dfb6a3 +8665,615e6f3c9366cf1a +8666,ad92d6775bb12ba8 +8667,ad371c57b9c1dd88 +8668,8a72b4fee6bd5b71 +8669,6abe816078de53b5 +8670,e97fda741a2da213 +8671,35182530798a3886 +8672,78717e4221ed2320 +8673,61e343bb25db3328 +8674,b166afff885aa818 +8675,1e5fdb70ecd915e5 +8676,6d39d875b96b8846 +8677,0b5cb40706fc3dd1 +8678,654a2a5705f32d56 +8679,451913cd563c8005 +8680,10435fb2e3f44e2c +8681,9c6f6a3e81e03448 +8682,44d339e8da0241be +8683,5bd13b19417bcc59 +8684,895000f8e53026c0 +8685,10f7bf436108e00d +8686,3dbc7f6ea1404e84 +8687,4dfe2ef2aa890756 +8688,8a060c9993af9984 +8689,4b43bbe9e0433331 +8690,193cd42797e79618 +8691,2b8da4efb6d521b0 +8692,a870850257a84cd0 +8693,f7188f3444d46bf7 +8694,e056e08ad1517af3 +8695,fed372521733d50f +8696,60a6d40c1bf74e86 +8697,334d5850677d1f73 +8698,62f7f1ae4fe298b1 +8699,bb5a3032eaa2e393 +8700,0006507b066c2680 +8701,bd9f328f9cfa4654 +8702,14d04274bcc0dc04 +8703,14b6917c55fe7475 +8704,266a73646faf22b0 +8705,bd92d40daee9ad9a +8706,63fd1176eb791d54 +8707,18f9007de8e2bf89 +8708,153ac1242fb4bcf7 +8709,fa7e1420b6941f6e +8710,6b28308695882697 +8711,5e0f99a650756aba +8712,40cef4a0ba80dbc1 +8713,1a3b32b468b897a3 +8714,d757d05d1d6c54b1 +8715,2e720d37df33e1d6 +8716,f2838d29877d8741 +8717,d836e940771db5bb +8718,0a87d78aabcf419f +8719,d3563d2a95da544d +8720,51b7adb994dc8439 +8721,059639812e016adf +8722,cfa6893646944e65 +8723,f6f2bf05c712eb36 +8724,b2b48396730203ca +8725,45b1e9724abeae6a +8726,3acc7025c0096445 +8727,1aa9f6c3e1880c67 +8728,364465ba03c1c671 +8729,afc11c4f8e8bba50 +8730,180519bf49256cfe +8731,761003afeaf82a20 +8732,bb7ca26565659aff +8733,e7591ca17fcb4d55 +8734,74c83828f5eb9c23 +8735,eae80dea7ec47378 +8736,824abba6768925db +8737,01c7e60e79cdc2bf +8738,d46c60ffc7e65b4a +8739,459d5b905593efd4 +8740,dbb848adf6371306 +8741,711e249afd808c5d +8742,65578b296316b3ef +8743,8e10bf939e9541f3 +8744,d0571def8ce4a020 +8745,2929a8f3565191e8 +8746,e25955a03d48b28e +8747,ad3ff4da3b27e53d +8748,064b05e0cc0ce2dd +8749,cc06959e30eb2360 +8750,05f616582eac96e5 +8751,b3e46b2a175d60b4 +8752,16c356c3463f529b +8753,a57be5704af8008a +8754,02c892ece8c8f96d +8755,f551998503f41469 +8756,579131b907d40ffb +8757,b7c415ac7878af06 +8758,459efe1c8b507c57 +8759,ecfc57f204a4028f +8760,a0ee2a9b3d5d579e +8761,d5c1e155807c5418 +8762,a61389835c2bc68d +8763,56247f203bb9a4cb +8764,b2b2d498baf849bf +8765,103d76374bf0bb02 +8766,abe5f0297af6765e +8767,d58d83a3ed01e2c4 +8768,4dd54c8bd5d1c20f +8769,af96204779e8bfdc +8770,790294e58406c6d7 +8771,62bf1c6c22d325d7 +8772,0d1816337dbbf145 +8773,bca123296cfdd701 +8774,8c4c9d12a5ab5d39 +8775,c95e3cfaec331d70 +8776,26aee140076bc302 +8777,9fccec47ec3534b5 +8778,e30a973db82516ae +8779,7fec408fcc8f691f +8780,3551744d46a41bee +8781,1620c22a2c8d2d98 +8782,40c9bb4b778960a0 +8783,31897e433cdc1401 +8784,d266e0bf7c9958a7 +8785,dbc2dd3b91485595 +8786,845a9a133efeb817 +8787,690f1e95bc0d9483 +8788,7240a313ab3b521b +8789,9021d7cae0f1ccdd +8790,6489587dccd6f82b +8791,f1623836da87dc08 +8792,9fc1254d3d7c87c9 +8793,53276c2ba31000d7 +8794,a5678d853fae9bca +8795,5c50b9c05f176736 +8796,c90ca1ac3a73cc03 +8797,15de67598a944503 +8798,6a3a932e55d019e4 +8799,33b971fde5389fd2 +8800,2a77f9a6ba0560b3 +8801,795cbf85c8a65152 +8802,0b8aa92b5745361f +8803,a7826981a9656acf +8804,45f46c3f254cc184 +8805,f031495f85031dfe +8806,0402e04afef104da +8807,97f774cbb3ac3ee0 +8808,839492915ecddb06 +8809,6d3b27bd5aa9e3d5 +8810,3d2192b6baad3d32 +8811,c77510f26814f15c +8812,58ef92bc093b47ce +8813,93cea69f399cb63b +8814,d9ac224c3c6e2abd +8815,aa6e8b3586bce028 +8816,3962d2716ee7f32e +8817,b50ecda0692be6d4 +8818,08a93eda7337e0c7 +8819,3c6a2b3a98ad5583 +8820,6df36475651a45e9 +8821,966d378dd4c33b2e +8822,148f8009e96e59c6 +8823,08f008f1689322f2 +8824,941e0c71d9c49a35 +8825,a33232196e2172ac +8826,86c0802723b183d2 +8827,a90c56253da8ab68 +8828,935e4fe940a5be6f +8829,e17b5c440cc5ef9d +8830,e083d1f56b5f561a +8831,527a2b17cfd90662 +8832,5475eda2768fe4c9 +8833,017eeca34e82d3b1 +8834,012fa65200fc418e +8835,930cec2542250343 +8836,c39f541366801a8e +8837,a1dffcb27c16a8fe +8838,d3314dc41ce7ade3 +8839,05c97be9da5866dd +8840,1f0e3f06d5382187 +8841,e1f61e489b18a640 +8842,d8f25bfe02850209 +8843,77d2017458988b62 +8844,5360ba5286e474a9 +8845,ab2fc5fe57e8c5d0 +8846,973432c389634802 +8847,9f8262a977e688ed +8848,e2c32fc4f2a119d6 +8849,5bf4e6d31f03a645 +8850,831eec8b9b9a5205 +8851,1201612fea67c959 +8852,cee9ef33323c7c85 +8853,e7b399cfbcc19343 +8854,736a4f3dff39a401 +8855,de8c78efe9f4b9bc +8856,d8d36140fe24806e +8857,4d052f2d610a930a +8858,69633ebdfdc7b45d +8859,b9d430cb24bee3af +8860,0bcb22eb914c37ce +8861,6f7e327c0cabf62f +8862,fd891fa835e6a328 +8863,c2bd99913c428ce6 +8864,1c95e6816e4c0d6f +8865,181693230c35dbe5 +8866,f2617dffb8405f16 +8867,fd4e22094a2d3df2 +8868,e5620c6daec894ab +8869,9a41011c503ae79b +8870,943a3f338d7925c7 +8871,00e5fa1ec5124fc7 +8872,21f19af76bdb2756 +8873,ddc9b45da0a2e9f7 +8874,cccf41fa295ffe89 +8875,5eaa5c6fe037b99b +8876,240d89d40ee71c16 +8877,21c414742298f7fd +8878,608b26777e637097 +8879,07f2132b30b7b88f +8880,1827a091c73722cf +8881,7a77b93c0e1fdab5 +8882,09a60edce9edcb43 +8883,f248fc117b957377 +8884,0355945c052bac3a +8885,daec3e7ca93dbebe +8886,9e66f479e1a62e79 +8887,98fe58cfbc2a3dd3 +8888,00e50646ac3552ef +8889,796e01938bad3d98 +8890,efc3e776f333efbc +8891,a7bbb29008440d4c +8892,d37e2328d7294b50 +8893,d7d0db34b8b0baf0 +8894,906e0bf5a003315d +8895,167c71162520f7d3 +8896,8fe4e338a18dfb0f +8897,594678c3304068d5 +8898,6de17c9c40127731 +8899,d15f69cda8b6906a +8900,5f1b88fc71e7e2b8 +8901,1536ffb9d3bf99df +8902,1964b41feaa61c39 +8903,588bd9d64fed8e3d +8904,987d3ea5868ee3d3 +8905,c38c5a4767e5f552 +8906,d2c2d4855e994af0 +8907,1b47c7c843affdb0 +8908,16911d363b7a41a5 +8909,01d721b14dffcc20 +8910,89e886a04eb6a3af +8911,5ad2ffa5dbe7fd87 +8912,27baef230149fa47 +8913,67125b94c2b11085 +8914,0661203683974fad +8915,fb39d585880402c5 +8916,cf40af1ce7eab2ea +8917,509554939cd19ff9 +8918,3c866bbc10200330 +8919,49dcf3313e183bf4 +8920,e1223499f7b9a818 +8921,0dcd896585cc209a +8922,ee4da49f900e8f23 +8923,ceb0df508dc01e75 +8924,09b15adf60d085fe +8925,9d79dc6e5b5fe6c1 +8926,97df26bca8eedc8a +8927,a45642f2d8172631 +8928,5ffabd7167b29809 +8929,aa3b34fbf26f2262 +8930,a26305459359e0bd +8931,aaf104b8c49aefb4 +8932,68738c3f18fddfd6 +8933,7610030805d00857 +8934,a74adc58a33b18a7 +8935,94193cd7d46acd0d +8936,9f2a685e385a3478 +8937,dd2e12a91bb35348 +8938,7dbcf4ff9548144c +8939,566db45f6337b1c1 +8940,c9323eea1244e0b8 +8941,cfac317e60633805 +8942,052c6988139ba3a1 +8943,efa5fb187f58acf3 +8944,766c8ec80aae3df2 +8945,9a558965981d1b51 +8946,0ef7d8ca04992842 +8947,c25d51c3e8649590 +8948,60554e849eaa75f4 +8949,caa7621c66a8151e +8950,24d2e45c52975fcc +8951,0870eb43aad155db +8952,0e3f339116619dd9 +8953,c24b4455e0cd2b79 +8954,284c6955c7285ee2 +8955,cbdcddc84acf1f4f +8956,58c38ebba824d10b +8957,713c375f5a8b6ea4 +8958,fcdd63d5c6788399 +8959,200e6e60afafe063 +8960,604e1a26da1a74c0 +8961,44b093e60a8ccf25 +8962,1ff3f140390ac2aa +8963,7c88ecd5bad78cb3 +8964,68a960bd82f38866 +8965,00ea02eaa7b3098b +8966,99a89f0eca11335a +8967,b182182d7cb2b862 +8968,436f0ced314ad166 +8969,5bb638352fd655f3 +8970,4d0a39f3527d622a +8971,50b42b1848a7669b +8972,f86e333c6b1dc15d +8973,8c4eca2a0378e906 +8974,3f71534009418590 +8975,cc6c76805ed2f88c +8976,321d928b166ab336 +8977,0c8a8780e02e53d6 +8978,4fa6f26885bed012 +8979,babdbb2af8bc7450 +8980,26df68eeae98987c +8981,02074871dc9f1f17 +8982,1e4bf0256926c459 +8983,ba5b98b6f1185678 +8984,632a9c481b4421ec +8985,cfddda149bd9a8b9 +8986,901cebdb09a77c31 +8987,29d201f9465975da +8988,80aa2cd5a2573f74 +8989,5de7d1da8660377b +8990,873a6e1c952799b6 +8991,cc6c6ac1c735e521 +8992,8eb757b6a21cb576 +8993,c93407b8c8add7aa +8994,f30d1202748030e1 +8995,e40226b1c47b76a9 +8996,de0b122add011742 +8997,794b848748c3f586 +8998,b356bda57d17b910 +8999,32b5f491ca57ecdf +9000,3b8aa76175e8b476 +9001,6fa8a1a3496a08e7 +9002,16c0cb684838a4af +9003,4d722adbfa03ce31 +9004,21198180949739f8 +9005,a0f1fd06071471b3 +9006,16c3a58e05c6406a +9007,4a1dba0e20e69f57 +9008,7e14a318166ed150 +9009,b2d2610d70eae3f0 +9010,0d437ba59fc37213 +9011,676939c378902d03 +9012,b9c90b895fa2384b +9013,a042ed5e868a47fd +9014,16ffd78800655631 +9015,226a23c8e827dc9b +9016,6edb29fd437bda98 +9017,f89528ee836f9acf +9018,28606b5dd7d9c957 +9019,29912d66ca8b4593 +9020,2eb46dcec83ef1c7 +9021,575d36495932dada +9022,c1b6a9a236524111 +9023,54ee7ce1c632a216 +9024,8894842734b305f9 +9025,6d6d7a45293d86f0 +9026,c037566774cb767e +9027,04c877f5f938648c +9028,1d4aaf6fb473e31a +9029,508290e9dfdc6ddc +9030,d375c78c44cc321e +9031,4296f7ef7941031d +9032,01f83281aa17734c +9033,56cf0db56ce97488 +9034,41afca5dae93affc +9035,6ce8c6bba73cd685 +9036,b99ba81f8f178e76 +9037,17923182fc68347d +9038,e8ca697fbddb028e +9039,cd4ad57e5f32c2a4 +9040,95d0d89187592a58 +9041,ae65bd54a8813020 +9042,34ef00887bfe4d37 +9043,9abc433c19c34488 +9044,65c34a184f3c9a44 +9045,b3078cd4f5cce01a +9046,ff516222b50d413d +9047,e27d76b1c31e0e90 +9048,277eabf68d4e35a8 +9049,2751373ecb6f9a17 +9050,b4955347cb5f5727 +9051,f22a8f77b7b145b1 +9052,505e7aba26e0ae4f +9053,e3bbf602576e7081 +9054,a33bc00d2a18e901 +9055,e4da6196df20c37e +9056,0de4aac88312b4fe +9057,8809347f11f2564a +9058,827756e67ef4d2d4 +9059,45f674562809f744 +9060,3fb02590631d4e28 +9061,ee021a6fa6cc7fb9 +9062,68b32a6a34992c48 +9063,161d143c69a4e76d +9064,4700361ff761cf51 +9065,e1f7815ac5ced026 +9066,bc63c6df7e1328a1 +9067,f9ee6b2e6cbb841b +9068,2c4b0e1e062d0447 +9069,929f66301ec875d8 +9070,4dbad662447fb920 +9071,0506e2bbe0293642 +9072,4794f073f5a78aee +9073,654b8ae72ae7b07f +9074,8a92d6f23358250a +9075,646df38f1fd6aa65 +9076,8417a1835fe5c1a2 +9077,236b9b9cc45140f4 +9078,6c5c700bfbc90873 +9079,b6db17ceb5f09770 +9080,6564133ba9bd4565 +9081,a243d104fb3ad132 +9082,410405045f8498d7 +9083,112a9e962ec66c69 +9084,f2e0ddc6a4f3e5f8 +9085,f405144db2666cb4 +9086,ff0ad15f03e5372d +9087,63aafd2a5506710c +9088,394f5eee7641cd03 +9089,9228b48bc0d7cbcf +9090,4b260f579d3cbca4 +9091,87e890ec88c1af04 +9092,38815b4532b8667f +9093,74b469afa5202fda +9094,1ed49422ba57f0fa +9095,a35245b4edea2fde +9096,7ac5d523fe746d90 +9097,d56548d1735df7c5 +9098,c52030be6efd39f2 +9099,7715fff5e464e355 +9100,56006dfbc364cf85 +9101,2ded5cf5899a724d +9102,664c330363eb52a8 +9103,76e81defa064adf3 +9104,168a4cc3c2f7ee7a +9105,505228870364103d +9106,3500a49ce93b7500 +9107,3383b7481e219d2e +9108,87b247f4db4bcf78 +9109,b4fc6a106914ce5a +9110,5ec7e01b1eab0e70 +9111,6cf1cda86cb9f7d1 +9112,f5b0281866f944c8 +9113,bfd1e84f90f435bc +9114,0d78ca34eb35f575 +9115,7a43b7c96d0aeaba +9116,0d7330188ebfae08 +9117,fb33f8b16b38af22 +9118,6a68404237e17a97 +9119,b344c6b547eb6d5e +9120,be8f1c4f619e423f +9121,e4b07869122bfd45 +9122,5032bb88494c9f2f +9123,127a529029fbfa89 +9124,d3ce0300e42cb820 +9125,5d97f18066951046 +9126,59c0969594cc2fa5 +9127,ac04a2aaeac6af08 +9128,299da4adc2641804 +9129,e470b18cfa1ec93b +9130,fccff91a02519d54 +9131,dd42f635b9ae3088 +9132,a2b9f4be5dab3272 +9133,61229d38acc1b166 +9134,709eacd6c0c0e68a +9135,7ad26dbde8ba5932 +9136,28cf6de1f82bb77a +9137,ab514f3826ed84c9 +9138,eeea30185aaadc09 +9139,786b57238690c6f7 +9140,7aa24e731f4af26b +9141,05fcbfc359b520e1 +9142,d52ad3dd0d57c66d +9143,c6ef9aa1b35d88a9 +9144,3d99dba84cb356ac +9145,4a1acd565e32dd10 +9146,9d372f8566456a68 +9147,a85f982a87c148c1 +9148,1c21dd237a7fbd1e +9149,584aea738d867bb1 +9150,43f48da809d1c91c +9151,880083d4ef0708a8 +9152,bf39929f106703ab +9153,14a906b81d6d92b0 +9154,8de7f25826894b85 +9155,be3b10a6a746d425 +9156,b1a64af1d85c9579 +9157,9ac6eefbe67344f1 +9158,67fd25886f7a51ae +9159,832079adbf896a32 +9160,5789dcfe067ddc90 +9161,f85800a554f5fd4d +9162,a9efd32be84316b9 +9163,5eff8323b96afca7 +9164,046140c2c4d1fa01 +9165,8fd35b57d77b3029 +9166,68389de95a15e450 +9167,d964662d23a684cf +9168,121a2b4e2b5e0473 +9169,6e2982b6adf09914 +9170,30ba19b9f18c4697 +9171,43af550c93f23144 +9172,affafce703d65aa1 +9173,913033f24887f5c7 +9174,9e165d33e9b42ca6 +9175,b6b067cbeb33e4a0 +9176,c790f5bf8c8d381f +9177,2913ad062fff052b +9178,a18cd6886ada72ff +9179,99360d8c70567a42 +9180,bc5cdc5045f5453f +9181,a6e22611153bf453 +9182,c405744f4d8c7862 +9183,b24ef7aa4e75a42a +9184,0797d289bfcb2ebd +9185,6078c5d57c4352b9 +9186,4428117c3d21201b +9187,5755a132f0265af8 +9188,e73ff2385539a3c0 +9189,fef79f409f489608 +9190,30b41d35aa15682f +9191,7068a3a17c39ec33 +9192,21339fc0ddba3d11 +9193,dec6fea98f5254ea +9194,0e01ab9f7e8fe3ea +9195,b6a0b892c31ffca5 +9196,51d02d596e065b59 +9197,ab5763a478f065cc +9198,553aa786c5c09441 +9199,60febf5c26d7119d +9200,a8517a2a221d3d5d +9201,6b06dfff979871df +9202,c5526f1151e5dfb3 +9203,f5c5a1f3c24820c1 +9204,dcd6b799732c6490 +9205,db4e4cea0ed330eb +9206,0bc97c37bb2a8c45 +9207,be8681e1ef8d73b9 +9208,a27dd1204f48a63b +9209,84b5905f6e11d395 +9210,c09abd3c5c6b5dfd +9211,e0fabeb8e692d2ed +9212,4e56c62d665eead8 +9213,0340568fbd549797 +9214,983d10317103c859 +9215,68d23039975caf1b +9216,d934ba4fed7dd773 +9217,1a4677b4b762c07a +9218,f96ad7ba03c47217 +9219,b45ce29b9005a24a +9220,8499c58d1f4564f3 +9221,8a86f4b0d6edcccd +9222,cce6ac1139f3a1c1 +9223,2bb6b5073bfe9bb1 +9224,1240a822579802a1 +9225,6353ed4779c05a35 +9226,c13ff8218da9ab24 +9227,214a693d3db560f4 +9228,823134c45924911d +9229,7cf4b5f370a35c0f +9230,c03113477393e815 +9231,fa2905b80eb92f41 +9232,329a6659da681eb1 +9233,cdb4ce2d55393bf5 +9234,d0796919ec138c6d +9235,b1e87e0b3552eaa3 +9236,340d61483a09c82c +9237,26e0639cea6ce749 +9238,53d355ffa73b8016 +9239,9747cb438b0fda69 +9240,e83b0ef7638fe451 +9241,d88b6ebd0b1b1f07 +9242,c1cc2e3300f47e83 +9243,6de99e4a2b642360 +9244,93d8cc1361e469a5 +9245,0df6e709daed3054 +9246,129fa798a1f7e23e +9247,00dc77354b9af96f +9248,f7b0998a65b7296c +9249,64d7bda084b62579 +9250,6fb23585c49c2ab1 +9251,6fe2513e7a4b2678 +9252,c5f29aeb3eafa088 +9253,e9057d5331338c7f +9254,091d3ba8f0c20415 +9255,6bd5a92e25ce4e49 +9256,5c40c9ce003f1244 +9257,c58f6bbcdee81c80 +9258,bbf9e130c95ef6b6 +9259,5455dbe459bf11ca +9260,6101af69d132a681 +9261,26d74e52793751d4 +9262,53c4ca98e6caa5a4 +9263,9638d1605ebada25 +9264,e98f1556637dfaaf +9265,5b49687607c65152 +9266,d857197e83d44bc8 +9267,dc8b014084f40712 +9268,5c4b53b814462b22 +9269,48f154235be60a1f +9270,a8847762c359ddfa +9271,a7e9057a0ca74f3f +9272,b4ef218d25b31b25 +9273,139f4df0ce535dc2 +9274,fd84a8a7cb139b16 +9275,30cdd8b233a257ce +9276,107e9af87a8757ef +9277,f0d3ea1d1cad00e6 +9278,1ce1f1ba3b77f41b +9279,5d506db941da83fc +9280,0378ce4c1b79731a +9281,e69467f0190885fe +9282,a3549242800056cb +9283,51e3d7a926d28571 +9284,2df4f682e2a57095 +9285,0f2910d293e4ad81 +9286,339c39906cf56ad7 +9287,61c5d16c13428a98 +9288,21465270b92010f5 +9289,2ab26123635442e5 +9290,c5cac4c4290fb23a +9291,d5703dcaafdf56ce +9292,c6103198e45809f1 +9293,cbece61093604c39 +9294,52680d7c16e46e4f +9295,3c1351b79963ef4c +9296,1f29c6ac2a23b9fb +9297,611a74e7d1088123 +9298,5285b4472755eb7f +9299,ad0d4a0a876b46ec +9300,75b9c943bbf694a6 +9301,a7e6424b0aa0530a +9302,494804d78cf5c149 +9303,3f0d1cbe95054104 +9304,40658120def6b8f8 +9305,1ae93090118b2fc9 +9306,758d62c32e7ce576 +9307,f42a93e70b567b27 +9308,5e1f761eb73ba5af +9309,83c3819d917d24fe +9310,0b45b902e0d04b12 +9311,64610976ca81da50 +9312,ba2276be95ab6347 +9313,464cb49b00149450 +9314,0f773fa3cd2d7018 +9315,983ca93e2dca2228 +9316,5f8953cf65ec6267 +9317,5ed3f86412058c37 +9318,5c6beba6e4b09a72 +9319,ddedbb1ce2204fbd +9320,219c5fc5875fe252 +9321,b8aedf9087096fd2 +9322,a4b3e524842a1ab5 +9323,1bc9c1fb0e383c16 +9324,269fb5c697a85489 +9325,1ee204da0e857cd8 +9326,03593ecd245ca953 +9327,9dda55e7505bbcb1 +9328,8fbef91888136017 +9329,2188c3fad90ea2f5 +9330,21daba32026257d7 +9331,053b99dae5f8bbe2 +9332,0b91d11c7e43176e +9333,bd6e6b51c7605763 +9334,14ae634c6025f455 +9335,b0f014eafa6e2029 +9336,892fab2bb61fbb8e +9337,f286b9e846e6537f +9338,9ad58501704230b2 +9339,c00038759d179b5a +9340,ed525a25af7a0609 +9341,dc400d7ac49b97bd +9342,56bb043a63d11030 +9343,09e6fa6e03c5b620 +9344,94842832d46faab2 +9345,108d3765779236b0 +9346,733d1ecd5eede0d1 +9347,b01a2dcce12aaa25 +9348,227a4fb833056e0c +9349,38d016227dc00031 +9350,59bc69def210f88f +9351,ced4ca1ef61df223 +9352,50df8516619b8300 +9353,23ed7149b613ff94 +9354,c6a542754bd96326 +9355,1336efeaff826a44 +9356,d0625b0cfd36846b +9357,997827e23c831b7c +9358,e0bb7385893a70d6 +9359,6cd97d0d3a3be196 +9360,3a68f8c124b22d2d +9361,3b0eb825fe728f8f +9362,95deac0b22e6fff4 +9363,825803dd67b895ed +9364,7ce1dcd1b6fefa04 +9365,d895e6b59eac3358 +9366,26afc9a865a110fe +9367,325472d15b8020d2 +9368,f576b5de439c9a28 +9369,e64cfaac125de37d +9370,261a9fe949217e40 +9371,9d076bbfac629d1e +9372,fb04bab0b629de0c +9373,691441e01fa118ef +9374,7203284e95c3289f +9375,4c1cde04a1c7d798 +9376,834495d43466057f +9377,0a00f40716d76025 +9378,6113596218681cbe +9379,a1ebb55f1516847e +9380,7d7a882491d26d60 +9381,48095e2c26471675 +9382,e03acea9905c483e +9383,0105f13112ee4054 +9384,5541d4e549967824 +9385,8459908664c7171f +9386,9e21cfe88b2784bb +9387,6daa0d407744ab7a +9388,0f8f754757c1846a +9389,65433dc201c8d6fc +9390,0b0fd774c55fa4be +9391,4f2e912dd9d9eef1 +9392,c112f59af70e3eb1 +9393,3901633120fbef56 +9394,d6bfa4b3b3ede7af +9395,3620299e58868cc5 +9396,786a10248993ba09 +9397,fcbe21e218ab1314 +9398,b1a262629f0200d6 +9399,4d0cdd5900870ca3 +9400,0230b26dc370629e +9401,db70f867e84621f3 +9402,7c2419ca29840508 +9403,9493185ce22267b7 +9404,c1bcc885caf11512 +9405,884e631adced37b8 +9406,f160f0e8912a2bec +9407,d7d36d9fd73bdf3d +9408,41229cb6e3e28883 +9409,88e205b548feefad +9410,13de8f3cd1c52099 +9411,7fdf0f43deff324f +9412,6fcd84ca5f40deff +9413,cef1a36c45df22c3 +9414,c611cf7fecbee28d +9415,9a64ec2e704f4b8f +9416,0b899e2b7d1822d3 +9417,0386fdac2f7454f0 +9418,95917ebf37712d81 +9419,2efbe1c5fc35af4d +9420,c0dca7e42da7234f +9421,9c0910fd54a49909 +9422,9b4789e757e7d1e5 +9423,53df44960fc9fa0e +9424,f4dfe6c47df39f4c +9425,4e6d0483c070d5e7 +9426,73c84af1ae1e13ca +9427,076c4f5e9fabbb08 +9428,981c3cf1c95234a6 +9429,fff20cf9f7520c93 +9430,938915f3a84c07c9 +9431,0051ab5250258de9 +9432,7bb92f254f43a3aa +9433,7d05a66295d627c8 +9434,46d3f3e8137d6cc5 +9435,b273fad862fb5a12 +9436,f0054937aeb3b5d5 +9437,3ab90c15054c9688 +9438,8c9459ca44f9ea84 +9439,df3c93db27aaf480 +9440,7a511d1053886144 +9441,bef8edfd4c58f36e +9442,db5c9c6548e80ba7 +9443,c82c0bb9199f7ae0 +9444,e4e9f9ede9761d96 +9445,b34dd46cd3c1e6ec +9446,28d5fe8d6a592c4c +9447,a9c2a1014d3ffc21 +9448,e10ff78d535f737e +9449,930545bae4f03111 +9450,07dc294f6a8096e6 +9451,58ad487a86f978c4 +9452,711e319a09f01032 +9453,90a9ee691992b6ec +9454,b44f69fe39b5097c +9455,de16bb5e8f5da4f6 +9456,6228f243f87babf0 +9457,2df70d1e6edaa59f +9458,7cf215357e974af9 +9459,ed9f308abef87678 +9460,4b5c3eca9911efbd +9461,901785d292915229 +9462,16b26cb24b1ea00b +9463,bf688a0ddfc49578 +9464,63e045dd9b3f8982 +9465,386e188b36b2298f +9466,06b64483f9e43ef2 +9467,86741c24d86a4a34 +9468,bd3d12720785cf34 +9469,1c77a4e6dc8d82ed +9470,b8a155810e815438 +9471,6e2a265f1194d1ff +9472,14b171fa867783fe +9473,1bfb6ab8c71ab2b6 +9474,8e3497046d104abb +9475,279b2fe32ffbc4b7 +9476,21565869d70c9e8d +9477,716dfdb031e69ac0 +9478,2c004f08f1a68998 +9479,afcba90295e551c6 +9480,680ba56380272897 +9481,c1e019e433657c40 +9482,02bd677b57f04005 +9483,a5abdbe15a3c98f7 +9484,4bb9ad73b0aac66d +9485,8488120816d9fcf4 +9486,b273da69b6f36758 +9487,819a3cf7436ae026 +9488,f2aba583025218a2 +9489,678df45d0a7ef4ee +9490,3df7da2beca57657 +9491,e170937879115cc8 +9492,e3b1a1efac76df28 +9493,72dafbcb11e3f715 +9494,97304883c74c9328 +9495,41b931a157a99647 +9496,b9d7fbc0ccfb5b0b +9497,8fd5a3e6cad60be9 +9498,0d090b6241d9ff18 +9499,20e97da6fdf9fe2f +9500,cd570e5e7ee8d71d +9501,24db2e29c1272a49 +9502,8a881e85ae0abd55 +9503,a78eb02d5981c42c +9504,346de044c1fee2d3 +9505,33c1b7948c7d9e60 +9506,5e290a6a91b32416 +9507,ef30e74a2b193b1e +9508,8fbd5ede56e039cc +9509,bf2f5d7b2b535e80 +9510,7f4f60ab6c808868 +9511,74c1a015f1091b49 +9512,965b50b8707cd6ef +9513,a7a3365e25d23c43 +9514,e0934f3d979d8044 +9515,60d11c6a73d66d2c +9516,ccc2b5245e42c212 +9517,7ddbb918249aa63b +9518,1013780d62a9cd85 +9519,f8d186b9dcd32f81 +9520,92813fbeacbd5d55 +9521,b76a10900170ada6 +9522,770c165f07059d88 +9523,7443ef0905271532 +9524,d8ae5ff5db82c3c3 +9525,e4b5a3c68885980f +9526,c6a7d753b51feea6 +9527,f3cd5a94949c608d +9528,b67fc13edb40449b +9529,23d4ff9e51aca960 +9530,92527ae6e8f95e84 +9531,e93094b9953803f5 +9532,aad8be9e93f7978e +9533,fee0229934292503 +9534,b825fd5cfd54dba5 +9535,6c4b08db288cd952 +9536,791543d3855ab6e3 +9537,52862cceef096710 +9538,483a083d332a1acf +9539,7eae71e8e83280ad +9540,1ecf2785787f03d8 +9541,cc31a026199df6c5 +9542,8bc05a519a654470 +9543,a915c6a03cf0afe1 +9544,e6ed847c4893b874 +9545,ff7a5bd60da939fc +9546,9db68a6cf935c76e +9547,c97d1d9776928891 +9548,fd2a5b7276dc806d +9549,b3c258000d08d463 +9550,ffe6c9935220958e +9551,455a8a207251c41b +9552,c6f73ba7d405c20d +9553,c9f4a605c2ef25ab +9554,f48d3ea4a3f88275 +9555,41090933d40c1067 +9556,128aa27576396816 +9557,f5ab2f0bf2d4c404 +9558,8f139beafd7e2e02 +9559,d203ce04f75a1027 +9560,8bdb4545d280bff1 +9561,1d89aabf37364a3a +9562,7e538e471ccae9f6 +9563,7fec3528ce7a42d2 +9564,3fd82bc0a0b8143e +9565,80d8e7ed3bc7949b +9566,fa844ccc070640d4 +9567,01e1f0245e03ada6 +9568,0c9f4e096ec313a7 +9569,534c7f4d308555a4 +9570,d1c70f5e1321c4f1 +9571,ba0646fe511b0517 +9572,a38cf3b9783c9240 +9573,211dc182a77d3811 +9574,557c92261ae1a2e1 +9575,fa1043c807e66534 +9576,05b10e5dc42dc8af +9577,77d3afa39a19a97d +9578,ebc15a18e145c319 +9579,1b4980e29b5d9b9a +9580,954d93abd45cfbe7 +9581,8fa3f4c1582912cc +9582,1e40b3f1e49e9166 +9583,634b43b0570caaaa +9584,6a7a1c7ecac1d9c8 +9585,4dc2cb708188ab57 +9586,d7caec4f0629c392 +9587,19119ca57037cb4b +9588,1e33ad88463adbcc +9589,8ee85aa509ed7471 +9590,34bfe750cacbfd73 +9591,ccf4d110451d4854 +9592,140c9ab4ace12a5b +9593,854073075d18dd38 +9594,fbf6a7715d8c1b6a +9595,beb257b0b970fdae +9596,4f585ffaf6355e3c +9597,7cd8e4c08c5e93e0 +9598,064cf1b25128df16 +9599,fe67dbc4bfb6691d +9600,5003d9273130157e +9601,b5d8e2ecd481a09d +9602,bd811a23cd6d768b +9603,53a3121c6ad98eb7 +9604,ca49bddab78970c0 +9605,5c9642350bee4964 +9606,0882c5421b6e8b69 +9607,5f44dced5c8fa8a2 +9608,d09149da7f6a34be +9609,cb306539a24f48e7 +9610,38cda17d45456983 +9611,2c210d9de2afd2c9 +9612,318877cb26629ec1 +9613,aa6cd67baa94364e +9614,e3c1f9538057a38a +9615,bcbe6081ac27780b +9616,fbcac26555f40139 +9617,0545c10ced529c78 +9618,dc03d321a6bc059d +9619,541d43115e98c982 +9620,d011d36a2663aae1 +9621,f7a587bf57e28a1d +9622,56e27f8eeaf9cabe +9623,9ac36631ea23e76a +9624,670b4eb79f464705 +9625,5b23d44c725aef1d +9626,6ac6e688e0a1ac33 +9627,2360af6c19f1c3ea +9628,15a45bb6116336b8 +9629,916d687a0b7e7ead +9630,4f5ae8c4bd31d9d8 +9631,4dd9573a3bbb5d7a +9632,2c2ac1df581338f8 +9633,40a2f7ecbef06d59 +9634,6cd7f81d75be8b4b +9635,37f12da84c3aaab7 +9636,553c0e8d6a5865d2 +9637,773c9a4a03f64c0d +9638,7baf4ef8fa8ab7fb +9639,013e9e1581765ad8 +9640,02a329cf045cbc37 +9641,d650da39c837e3e1 +9642,1b86243ef262e23a +9643,dee56f8da3d3ace3 +9644,132e6884966a62bb +9645,07154d0ce5154b85 +9646,9e427f1cfa99c1c6 +9647,d5303827fd0ed80f +9648,4ec1ae75dceeeffd +9649,7500ff1f1b64101c +9650,b0d721a3b66b38dc +9651,6c9eb7e14c96e8b1 +9652,e937db1593d61b55 +9653,706a644b9a9e29cf +9654,5ec045bba3160110 +9655,5f68c60aa2bdc484 +9656,f5cc6f3950eee02e +9657,9cdcc7488cac0870 +9658,3c86ec8828f650fa +9659,696323ea73329e90 +9660,0b51f626c4188cc3 +9661,4e6a802ae00a33a0 +9662,ce5179548bd6b0b8 +9663,d04647b1d3d4f3b0 +9664,e98ea98f11ee63e5 +9665,cb61d88599a5b5da +9666,53577c5065beb4a3 +9667,3c4e4eb148860759 +9668,0f90936ae6b63c1a +9669,ee6cda6196d1e755 +9670,5996e5cced432994 +9671,83aa3ec75dfb30c4 +9672,98d07ca919375018 +9673,259d152e9dbaa42c +9674,3820da4540ca6193 +9675,e25e55c69c896693 +9676,362e6f0073a3f8cc +9677,b0a05fa1d9cf732c +9678,edd38cf6fcc8c4a7 +9679,1986835fe86e6cd3 +9680,29bc530acb8ffa3a +9681,6b9de3216d12c73d +9682,125dfc198988af66 +9683,50a4ce46257b5afc +9684,92a7e8bce9f05270 +9685,6219b4c9459b85ea +9686,2ed314429ea24dc8 +9687,8788373d1f8c8a7a +9688,67b997949de01578 +9689,c4f20b23f83a3d06 +9690,57426cc7cdaa34c4 +9691,d42038c5234a23b2 +9692,37b162acd8038031 +9693,ab3f150a2e5cec06 +9694,343a2fdf7acc67c5 +9695,e8d95bab931f2b3b +9696,9bd1c6c93220c130 +9697,02bda8e83a07728b +9698,9c1c65bd54c2fa86 +9699,c2f56d3eefc2bc88 +9700,62678b51997d014b +9701,63bc177ecf783173 +9702,dd2604296ffb1c1f +9703,6415ce0f21932dc6 +9704,c3abe0abcda6e5a8 +9705,25ebd3cc1966668e +9706,c147e175a525b557 +9707,c51d7df0e15fda67 +9708,c81e3b98fe25f351 +9709,2a4bfaa02dd4c4d2 +9710,f1700a90ac982f76 +9711,04727bc8caa3f103 +9712,a040a104215c2ee7 +9713,54b93b845e07ea03 +9714,0e19e00f37a602c0 +9715,1092101a04aabcd4 +9716,04e7c8a2b5d29d66 +9717,cc9f6df1043d677e +9718,d3612a8b83d7e5cd +9719,4accfb91dbecd1b4 +9720,397d1e972a45392f +9721,8f01cf7105353410 +9722,a68299daa469eb92 +9723,090343e01ea5e527 +9724,6ac14337e2b12eb3 +9725,af6a08b306a85cbc +9726,6f6ee2819b82d9ad +9727,c475e5924959b39e +9728,c8d6be1c11ed54e1 +9729,9f686d8c4b3acbe3 +9730,9753b63143498b9d +9731,42a0ad7006f913c6 +9732,6a52963a64dace35 +9733,500f03f322f6eb87 +9734,0e29b219f597312a +9735,9bc689b3ee34c739 +9736,e0ffba7f0212a4d4 +9737,7a41dbbf9c83f542 +9738,cbc77f49e142435f +9739,1152b1bf19aac5d5 +9740,9c256ffe25d5b262 +9741,7cd9e3b6b1ecabfe +9742,b0cd907e4b5ac080 +9743,948816262e105185 +9744,6df755177b922cd5 +9745,d5eb41015f7c598b +9746,4df293d9979c7e46 +9747,837e7f54f6b4bac8 +9748,420b7496d975f8fd +9749,e8a876ad036ea861 +9750,a69569f370eb289b +9751,9a6bfa2c3ef01d44 +9752,e47c2de95859b228 +9753,bf337390f0dcd0ff +9754,f8799ff9f7848fc7 +9755,15c5be98d0a69f5f +9756,7030d963eca5db75 +9757,2b1f317f3b20abac +9758,d445b4d7a2882f62 +9759,b403bae84a772cd8 +9760,9ccaaf798e601f5b +9761,bfbc70f2a564d233 +9762,71c66a1a61d4e3b4 +9763,f40f384a312414dd +9764,dd15d7f550dd284d +9765,e4f7ea2c8bacb564 +9766,eddee00e13671a87 +9767,b974ad447102217f +9768,75337f8cfbfc946e +9769,16afeb4c3a01bad3 +9770,b12c30aff2ed5c9f +9771,140904f0cf9c9f52 +9772,a4d93be6b02b852c +9773,736d49a994a187e7 +9774,670b99a410ae3fc5 +9775,aa643f9fb0102432 +9776,3c035bdd06d1c52c +9777,07df1d5aebb04c6b +9778,62ee924fd1942da7 +9779,b1a7ad19fa1fbdb6 +9780,4d55c856d1d9861e +9781,54c4668bb68ad4db +9782,e60ff2f4712255c4 +9783,0d49fe126a191774 +9784,665f4b38779286b1 +9785,70a845dbfc8acd82 +9786,8593bd131c05b9cf +9787,31a64333832d17cf +9788,96ebd0421b6617c1 +9789,723ca14aae1ad292 +9790,93e3e03940676825 +9791,922871bb4b19742a +9792,c4259e4bcd3af817 +9793,c3bf8ed196edafe7 +9794,f1578d111eed4ee5 +9795,bc089dd4ee5d60f1 +9796,030050ae525c6acb +9797,0c374c7de8ca6068 +9798,82b7e5fe4067af8a +9799,947cb84328fc7973 +9800,0ebeba510e424409 +9801,a5cdb9761b44f383 +9802,174fb6ff98b5e727 +9803,cec3436530ccd11e +9804,4279c9051160f90f +9805,8034c52690dd1ee6 +9806,49a4c50ac4f2a23d +9807,a64db140c2f65a86 +9808,b43dc6f4dbba69ab +9809,b669beecf1ad5c8d +9810,cd0f4423e1f20aac +9811,e185e7a60b22680f +9812,26ecd1f6a44a06c6 +9813,ea4ba15b72c4fd6c +9814,3038a506a7d827aa +9815,8fc19907da82777d +9816,ac9bff27ab77393a +9817,7cf3b06b06061509 +9818,7aefe006a8258a59 +9819,c8cc032b1ac66578 +9820,11bc8188184364aa +9821,5385040d6cce1790 +9822,9cd9e2d31d45066f +9823,f0d244238a0f8439 +9824,e036ae4665cc9682 +9825,fa5e9c6a234b9494 +9826,82efc5c6c7b9234f +9827,088ed9337b36942b +9828,b237c7a8b5f5cd34 +9829,87dec4acdee34aba +9830,225e8483ca51d128 +9831,22acebf98eb2dca3 +9832,29d52682a2dd2af5 +9833,c2e9ba16afffe3e1 +9834,91a94690a9c70785 +9835,2aa6490803bce418 +9836,697b2299ae65b13a +9837,f630be7cfe5568bf +9838,8f8d26540c752d00 +9839,2bdd0b3efa9364af +9840,e67ef88ebe44fb62 +9841,050fe1698cce1c71 +9842,8a48cbab9d247c7f +9843,f833ba7c7e282017 +9844,0cace1cbce5ea013 +9845,6100cc22f0ce619a +9846,089f5fb02f7d7888 +9847,6ed1964a550f07de +9848,fabc4781140d44be +9849,720ba2ec897424bb +9850,3e4afaa1d85698a3 +9851,80773e799e3a0aa0 +9852,438326cbac55439e +9853,e94529fa438f7c67 +9854,6ffb2e875033343f +9855,309db598efdb800f +9856,2548c9f4ea32abb6 +9857,d5a48b57ae6858e2 +9858,76d55829e6be791c +9859,e7f682779e8504be +9860,f8659558790b897f +9861,fffbba76dcbf8866 +9862,66f27a3db5f47b91 +9863,8078b85cc5aa9f46 +9864,ff7aa3bca9f98adb +9865,acf1d30424c6c9b2 +9866,198883f7bbdfc92d +9867,8e1dfcbd06d35339 +9868,46f6135246fa63ca +9869,9736a3b2fd38fae5 +9870,e1ba11d77f445f5a +9871,15dc9e96d2b0705a +9872,ddc2c902479fa9f5 +9873,e799875c6b3c37bc +9874,32167b91f8d2c00f +9875,c99fc9f0b64f737b +9876,069efb254b2b0283 +9877,6d3f5770a7663624 +9878,8b525774c6e12d64 +9879,01a01b9c427bbe37 +9880,8f406e61b776a964 +9881,3a81a2e9fad5f7ae +9882,38d59af48daca70b +9883,9e62bf38ab0fbc57 +9884,147cce5fd7dd4082 +9885,84662fe2ac84ca26 +9886,a3235228558ff8cd +9887,558c84052a085a13 +9888,f7332d29c962f0dc +9889,1f52f47e9f0b4dc5 +9890,f17b04dc62afd45f +9891,fadf0779b74a4e9d +9892,9d631a0cc4f12179 +9893,44e3a14a42eb77d4 +9894,c67e532c15e63768 +9895,8b3835a9e67085e3 +9896,7d9a6b65c5117d5e +9897,6667743fee38f26d +9898,03b0eeffae5d9486 +9899,1b00906840515a5a +9900,2fb9e0b1576af8a5 +9901,bb1b2fcc092ee1b5 +9902,907a319a11a1bef3 +9903,051f42b2db8f347d +9904,41e11bd97da9b887 +9905,96dfe8f9c788fe12 +9906,b7f1febc81adecbf +9907,b2fef056e815ca67 +9908,0c1816e5a38a655a +9909,57845c56ff0e49c9 +9910,3d97c03a03108227 +9911,541373cce096375c +9912,ee5a79b5abe9d8f3 +9913,8b7d56b2aca6c801 +9914,fa9aa6bda025e982 +9915,25f58edaec123d2c +9916,df394db3f76752d4 +9917,171b398059ff104b +9918,4d4dec3d6994b9c7 +9919,5d857be50531aa22 +9920,66aa9453e4023fc0 +9921,33bfce5053d3b559 +9922,3ef628040edbab7c +9923,e2e16643cf024a78 +9924,83745570877f6a92 +9925,305cda54585c446d +9926,426b8ffbb4925947 +9927,8e7bdb1f2ce70c76 +9928,c765ae2dfef06083 +9929,37365a6e6587cee8 +9930,6169bbf4619c0db6 +9931,29447a59f187a853 +9932,f409c5979482877c +9933,5eccc6c5bb57b73c +9934,56be083c8a0aff34 +9935,86c6d5f56c78544b +9936,ef2e6485d54cdd60 +9937,a7d604d272d4ecd6 +9938,bc66c1ab1b7d191c +9939,d7f62199dfed5f8f +9940,39c4f8e25a7878d6 +9941,8bf3e94103bd76d7 +9942,f89f92d037c8a587 +9943,25f212d77b3af9f6 +9944,6576071aeb9d948d +9945,540666aace3c1423 +9946,9f5421b801b5b889 +9947,46fff62a07611bb4 +9948,b72e01535df4c25d +9949,569ac4f992ba7e0b +9950,595629cc8b3ff466 +9951,b8a9667b9c576ed8 +9952,7b809096a04fae2c +9953,f2f612ff954e384f +9954,3635a53566f6e2c5 +9955,4d2e4f88fd2bd7e8 +9956,b6f2e4017148e95a +9957,e3f267f576252be4 +9958,de206e30753ec143 +9959,456b3b3e32a8add8 +9960,698babeba972377a +9961,4898c5d206499276 +9962,beb17a03a340af25 +9963,92f213dffee40ca8 +9964,fe2c015b3538d3d6 +9965,3e7af3bd8f297e31 +9966,f69ee17e3482cd34 +9967,4592cd5849d7a8c0 +9968,dda83a3f56fc3734 +9969,218a613af8fb4eaa +9970,73b3b2495f10e336 +9971,a4705ed1b462f6a2 +9972,4a5e32e8fd03854f +9973,00a23d5d2aa1a5d1 +9974,99568ae31fc62f5c +9975,d1dc5872a124ff02 +9976,f5be4ea1775d1f65 +9977,3ac8a91db864fda4 +9978,2a3dd928e2c08f69 +9979,d208c9ebbce98c66 +9980,3e86f75b224d536d +9981,a132d343fecd9628 +9982,3fb47a15e2f3f478 +9983,e79f04fb51840d6d +9984,61e49e4392fc5236 +9985,6835ba0d5f37049b +9986,06d57e39ea7bd36c +9987,dca9dd07fcf9a0a9 +9988,4011f437ce15ad2e +9989,83be5cd3c4393527 +9990,bd701fd331fa0a9b +9991,6d8e4fa6bba4ee2f +9992,37b2e26e2469ff31 +9993,c5cda6682989c5f7 +9994,44a2508d77072998 +9995,a86703f93cfb1330 +9996,8cf008a5e3f0b913 +9997,2b2e483ddde94387 +9998,3ed4d004eaa6c289 +9999,0c3dd053f486cba6 +10000,48425f340df8cf3b +10001,6d9b2b928cd2147e +10002,269cb49e9c7c9cf1 +10003,cc69536ff45cea34 +10004,11f8dd0dbeca0e7f +10005,6160a647cf33db33 +10006,6a37fb5083505b0a +10007,90ee8032a71493fa +10008,b8140c3d6902343a +10009,2d00dbf5c9bbea0e +10010,4f244e0a0f383944 +10011,5a6bbf3c84a95374 +10012,8904fe6849739028 +10013,d0467cae445709b9 +10014,36b072876fa49aa4 +10015,195035bd7706f0d2 +10016,8714cf9607326afa +10017,507e0b3fb3c97487 +10018,5400209550f2b85b +10019,791e04b8ba85ded9 +10020,3e959bfa8db51b07 +10021,1eb070c6d8df0888 +10022,c56102c79f1b0058 +10023,4862796c1cfae0d3 +10024,e837793c74df475f +10025,61c29c69e172b74a +10026,0a27d965540e255c +10027,ed9a8844c1823df2 +10028,d40f63e9386e7f1f +10029,c5ead1e60aafa4c8 +10030,f21213a1c16d2536 +10031,f7c063ca4ca55553 +10032,17c32f9b631af265 +10033,ef4d166901998b61 +10034,16c81cf358b4ab5d +10035,f43a388d6636499f +10036,942080a44810544c +10037,8d1e5b22921eb2a2 +10038,3d8058a0e0207ec6 +10039,d49777db352c3eb4 +10040,25c4ae49c43237df +10041,b30a02b70bdbf8e1 +10042,c3423696b9fdea0f +10043,9487b55d339504dc +10044,365bcb8cbeb78923 +10045,94ee487a7e9a55ed +10046,e9324c2aed9620a4 +10047,1c1c3a056961635f +10048,e6ef6fd4a2124246 +10049,1ed0cd333468db8c +10050,12d371fa6250db61 +10051,eba9148c5e0ab5b9 +10052,116b30a45726754d +10053,307a6b675df0ebf8 +10054,af3c7880a0df16af +10055,22278578a4664dd8 +10056,bebee4d0f05a8a19 +10057,2f3ce203aa970f7b +10058,fd7e58e24c68aac1 +10059,1f88a38cdb31ed80 +10060,20aeb949f930f3d6 +10061,d7fcef0900d19cdf +10062,515091c0ce40709f +10063,1c1eb173116855a3 +10064,2c3ab8f3706b4638 +10065,7564a2aa4f98ff04 +10066,ae860bf6e96cbb7e +10067,d20c49e2decf7dba +10068,ecd72eabd0d26459 +10069,ecd88f279d567e99 +10070,2c8992a794d85a94 +10071,ca3a88fd06aa0990 +10072,7ec8e6d98bde15a6 +10073,efd655299477cc73 +10074,198c9a2768b778bc +10075,705b7e475391c9f7 +10076,4a537edeb0bab391 +10077,1891cd5e8a99f1f2 +10078,fe76bea7f87a2a04 +10079,0e76ccf1ade8d795 +10080,013efc87e1e2bc12 +10081,1ddf12a09b1dae07 +10082,19ef32578e0b21fb +10083,7817674bd536f16f +10084,e5a8f751c3f0d7b7 +10085,288efb85ebdf9592 +10086,9cb04cf08f8af50f +10087,6b9f751450d7bb9c +10088,582970bb3d002025 +10089,9f628af48558e765 +10090,4b990d033d418974 +10091,d3c6d7f893608106 +10092,3ce683c7c91034d2 +10093,14f6b8dcf4875692 +10094,e3833a6d037d266d +10095,45273477bda3682e +10096,239d9307e56ce722 +10097,4efb1c380aa3ecc0 +10098,7a2a60fc31ee5bc4 +10099,9a00e8a48b7bf62b +10100,fad92df73119d401 +10101,547bbe2b637d58e1 +10102,35f77138d9d45ded +10103,b463332fe8dcae33 +10104,76b9aad1dbfaa1d4 +10105,9f6a0b27f797ae7d +10106,9fa303a2da0a5e22 +10107,18c43233fb13093b +10108,f18e03921ab8892e +10109,178051810f2d3453 +10110,fc4e0b9a4ddebd1c +10111,cec6f68cd1454baa +10112,30761979db5d87fc +10113,5adfbc7c1fe19b72 +10114,bc90f295e5bc8983 +10115,2a03c6a07402cf2a +10116,6992f22b440a0ff1 +10117,12f735e55d1a7a93 +10118,bf3c686c0ce759a1 +10119,b48bdd6b7bc843af +10120,b437a627522c31b2 +10121,450429d0a2dd991e +10122,48f159eec6889760 +10123,cdd2231ee6667d04 +10124,6d6a0f026cb61ec1 +10125,de6097b7ccc0f87e +10126,a591165d9d46ae30 +10127,87778b76da4abea3 +10128,9c79578a6ff83254 +10129,738f2d6388f635bc +10130,de8a9804e4dfbaaf +10131,11f8534931598ca4 +10132,f66a01791c6ecf92 +10133,5fa0074ee813c1cb +10134,6abf8123d9bafcde +10135,c96f3728e4050396 +10136,a58c28ab372e6ba8 +10137,ab28cf4202423786 +10138,6d58dc18fffcec79 +10139,e9b927528c5cf504 +10140,210f88971ae1dbac +10141,e21c93c87310cd8e +10142,e08886731c2a43fe +10143,abc285ba0f257e7c +10144,646213dfb10405f4 +10145,e4f92ce513fc28c4 +10146,a4266d31658c97cd +10147,765b42edd4f67d8c +10148,cd5270a4530824d4 +10149,369cf82f34e68622 +10150,98a3a90124c127e1 +10151,d7ac35bc9d277b92 +10152,ec1a6ce47b2af25e +10153,93ba02e7d5fcd6e3 +10154,46453187fd4cb494 +10155,7906432d17c49d74 +10156,f624e90efcbe835d +10157,b7ee6cf74b1ca287 +10158,df3d8de8ee6bafa5 +10159,c1e2ad4765ed5f0e +10160,ad289bf8b18eb58d +10161,79aac565b68639f3 +10162,9b192231f7038955 +10163,67ccc03db3f43a94 +10164,08b2d9536366d532 +10165,3750f831493f403a +10166,28ecc1c1ef71b9b9 +10167,786f7650c819ff6a +10168,e2ec66571d0f5c62 +10169,33c9c4955b970012 +10170,62cdf149647ed8d8 +10171,cd2c585d2f090ded +10172,6e9e176cf67f7b5b +10173,83db942fe3f93106 +10174,067e62a576beaea7 +10175,8efe54f79b2aa291 +10176,d91595b88e0f25f1 +10177,c1969112e000207b +10178,ec6501479608a91e +10179,da84a89ea0d787f4 +10180,ae35c53fe8e8cdea +10181,d766572d7eb5a2f8 +10182,d7ca87ad8aca96ae +10183,06d4b3a969a82f2a +10184,79b6e6b86c60d531 +10185,419f5e8453fbcd4e +10186,bacb29bce626ed1c +10187,ffe369d41c370d1f +10188,23385a6bf1c2d370 +10189,907229e536df460d +10190,8a0a97d238da139b +10191,28c30f862ff52558 +10192,cebdb4e68f2ab5d0 +10193,84388fa38811c35d +10194,1327928b5e6484d9 +10195,0197fe76979c2ae4 +10196,61d6059dfeb233d3 +10197,20eb670f2b754864 +10198,14b4f261348814aa +10199,4f8c7468db9b9e4a +10200,7b648e88d2ba75f1 +10201,e85118616ea09de0 +10202,def2c0543a1487fa +10203,51216a647f4827d4 +10204,86a6ad3b89fe4142 +10205,933f48b295891e3f +10206,ea6ad9e68845b246 +10207,59a0bd8407e75989 +10208,7c9facaef7ef38db +10209,bdac0ffbad25dd21 +10210,6bcb97c4fc310e2f +10211,f23d53092a5c42d5 +10212,95a49f3f109d01f0 +10213,5a963d31d7e19c07 +10214,d97d939255a0b97a +10215,09dbe6f45acc2da7 +10216,d046d098a0acb937 +10217,71f8c6c5bbfe7afa +10218,a02b127257e5c88f +10219,c967c3d5f09f2805 +10220,32318d57104c7832 +10221,47013f3d0181fc66 +10222,e504ceb4e93a0107 +10223,4922c14ec98cf20e +10224,221206c401f7ed03 +10225,81df81a5f2886493 +10226,389a93ec7b366b84 +10227,284aed7356b8912e +10228,f93ce9c1328aba01 +10229,16bfe78df3dfb793 +10230,94180f065734b8c0 +10231,e0705996cfbd4ae0 +10232,04b67489efd8b6aa +10233,c7a63ceaec2cd5bf +10234,78f57bc00569bcdd +10235,1a80b501d6c53091 +10236,455dfa2fa48034c3 +10237,128ba8ebff1da97e +10238,278486c8a0d74a70 +10239,46c39956bffd67ff diff --git a/hashlib/test/hmac_test.dart b/hashlib/test/hmac_test.dart new file mode 100644 index 0000000..eb7c1f8 --- /dev/null +++ b/hashlib/test/hmac_test.dart @@ -0,0 +1,137 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:hashlib/src/algorithms/hmac.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('HMAC test', () { + test("name", () { + final key = "key"; + expect(md5.hmac.byString(key).name, 'MD5/HMAC'); + expect(sha1.hmac.byString(key).name, 'SHA1/HMAC'); + expect(sha256.hmac.byString(key).name, 'SHA-256/HMAC'); + }); + test("with MD5", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = "80070713463e7749b90c2dc24911e275"; + final actual = md5.hmac.byString(key, utf8).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-1", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"; + final actual = sha1.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-224", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "88ff8b54675d39b8f72322e65ff945c52d96379988ada25639747e69"; + final actual = sha224.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-256", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"; + final actual = sha256.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-384", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = "d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6" + "fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237"; + final actual = sha384.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-512", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb" + "82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a"; + final actual = sha512.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-512/224", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "a1afb4f708cb63570639195121785ada3dc615989cc3c73f38e306a3"; + final actual = sha512t224.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA-512/256", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "7fb65e03577da9151a1016e9c2e514d4d48842857f13927f348588173dca6d89"; + final actual = sha512t256.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA3-224", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "ff6fa8447ce10fb1efdccfe62caf8b640fe46c4fb1007912bf85100f"; + final actual = sha3_224.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA3-256", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "8c6e0683409427f8931711b10ca92a506eb1fafa48fadd66d76126f47ac2c333"; + final actual = sha3_256.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA3-384", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = "aa739ad9fcdf9be4a04f06680ade7a1bd1e01a0af6" + "4accb04366234cf9f6934a0f8589772f857681fcde8acc256091a2"; + final actual = sha3_384.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + test("with SHA3-512", () { + final key = "key"; + final msg = "The quick brown fox jumps over the lazy dog"; + final expected = + "237a35049c40b3ef5ddd960b3dc893d8284953b9a4756611b1b61bffcf53edd979" + "f93547db714b06ef0a692062c609b70208ab8d4a280ceee40ed8100f293063"; + final actual = sha3_512.hmac.byString(key).string(msg).hex(); + expect(actual, expected); + }); + + test('sink test', () { + final key = "key".codeUnits; + final msg = "The quick brown fox jumps over the lazy dog".codeUnits; + final output = "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"; + final sink = HMACSink(sha1, Uint8List.fromList(key)); + expect(sink.closed, isFalse); + for (int i = 0; i < msg.length; i += 7) { + sink.add(msg.skip(i).take(7).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(() => sink.add(msg), throwsStateError); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + expect(sink.closed, isFalse); + sink.add(msg); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/keccak_test.dart b/hashlib/test/keccak_test.dart new file mode 100644 index 0000000..a73099e --- /dev/null +++ b/hashlib/test/keccak_test.dart @@ -0,0 +1,78 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/src/algorithms/keccak/keccak.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('Keccak test', () { + test('The state size assertion', () { + KeccakHash(stateSize: 0, paddingByte: 0); + KeccakHash(stateSize: 50, paddingByte: 0); + KeccakHash(stateSize: 99, paddingByte: 0); + expect( + () => KeccakHash(stateSize: -1, paddingByte: 0), + throwsA(isA()), + ); + expect( + () => KeccakHash(stateSize: 100, paddingByte: 0), + throwsA(isA()), + ); + expect( + () => KeccakHash(stateSize: 101, paddingByte: 0), + throwsA(isA()), + ); + expect( + () => KeccakHash(stateSize: 150, paddingByte: 0), + throwsA(isA()), + ); + }); + + test('Keccak-224 with empty string', () { + expect(keccak224sum(""), + "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"); + }); + test('Keccak-256 with empty string', () { + expect(keccak256sum(""), + "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); + }); + test('Keccak-384 with empty string', () { + expect( + keccak384sum(""), + "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2" + "dd2b21362337441ac12b515911957ff"); + }); + test('Keccak-512 with empty string', () { + expect( + keccak512sum(""), + "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c0" + "0fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"); + }); + + test('Keccak-224 with "abc"', () { + final input = "abc"; + final output = "c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8"; + expect(keccak224sum(input), output); + }); + test('Keccak-256 with "abc"', () { + final input = "abc"; + final output = + "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45"; + expect(keccak256sum(input), output); + }); + test('Keccak-384 with "abc"', () { + final input = "abc"; + final output = "f7df1165f033337be098e7d288ad6a2f74409d7a60b49c3664221" + "8de161b1f99f8c681e4afaf31a34db29fb763e3c28e"; + expect(keccak384sum(input), output); + }); + test('Keccak-512 with "abc"', () { + final input = "abc"; + final output = + "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5" + "d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96"; + expect(keccak512sum(input), output); + }); + }); +} diff --git a/hashlib/test/md2_test.dart b/hashlib/test/md2_test.dart new file mode 100644 index 0000000..5878f4f --- /dev/null +++ b/hashlib/test/md2_test.dart @@ -0,0 +1,88 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "8350e5a3e24c153df2275c9f80692773", + "a": "32ec01ec4a6dac72c0ab96fb34c0b5d1", + "abc": "da853b0d3f88d99b30283a69e6ded6bb", + "message digest": "ab4f496bfb2a530b219ff33031fe06b0", + "abcdefghijklmnopqrstuvwxyz": "4e8ddff3650292ab5a4108c3aa47940b", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": + "da33def2a42df13975352846c30338cd", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890": + "d5976f79d83d3a0dc9806c3c66f3efd8", +}; + +void main() { + group('MD2 test', () { + test('with an empty string', () { + expect(md2sum(""), tests[""]); + }); + + test('with a single letter', () { + expect(md2sum("a"), tests["a"]); + }); + + test('with a few letters', () { + expect(md2sum("abc"), tests["abc"]); + }); + + test('with a short string', () { + expect(md2sum("message digest"), tests["message digest"]); + }); + + test('with special case', () { + var key = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + expect(md2sum(key), tests[key]); + }); + + test('with longest string', () { + var last = tests.entries.last; + expect(md2sum(last.key), last.value); + }); + + test('with all known cases', () { + tests.forEach((key, value) { + expect(md2sum(key), value); + }); + }); + + test('with stream', () async { + final last = tests.entries.last; + final input = last.key.codeUnits; + final stream = Stream.fromIterable([ + input.take(7).toList(), + input.skip(7).take(10).toList(), + input.skip(17).take(15).toList(), + input.skip(32).toList(), + ]); + final result = await md2.bind(stream).first; + expect(result.hex(), last.value, reason: "'${last.key}'"); + }); + + test('sink test', () { + final last = tests.entries.last; + final input = last.key.codeUnits; + final output = last.value; + final sink = md2.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < input.length; i += 12) { + sink.add(input.skip(i).take(12).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/md4_test.dart b/hashlib/test/md4_test.dart new file mode 100644 index 0000000..b16574b --- /dev/null +++ b/hashlib/test/md4_test.dart @@ -0,0 +1,80 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "31d6cfe0d16ae931b73c59d7e0c089c0", + "a": "bde52cb31de33e46245e05fbdbd6fb24", + "abc": "a448017aaf21d8525fc10ae87aa6729d", + "message digest": "d9130a8164549fe818874806e1c7014b", + "abcdefghijklmnopqrstuvwxyz": "d79e1c308aa5bbcdeea8ed63df412da9", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": + "043f8582f241db351ce627e153e7f0e4", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890": + "e33b4ddc9c38f2199c3e7b164fcc0536", + "123": "c58cda49f00748a3bc0fcfa511d516cb", + "test": "db346d691d7acc4dc2625db19f9e3f52", + 'message': "ffa70bbb57bda34ec842cac3d9a099aa", + "Hello World": "77a781b995cf1cfaf39d9e2f5910c2cf", + List.filled(128, "a").join(): "cb4a20a561558e29460190c91dced59f", + List.filled(511, "a").join(): "1c2912a2a50886af88bbf6b374593d6c", + List.filled(512, "a").join(): "71ad0ebe8db92f0deca36c233e1ac4cb", + List.filled(513, "a").join(): "e5f5b4253616aeb972b6f823a2519911", + // List.filled(1000000, "a").join(): "bbce80cc6bb65e5c6745e30d4eeca9a4", +}; + +void main() { + group('MD4 test', () { + test('with empty string', () { + expect(md4sum(""), tests[""]); + }); + + test('with single letter', () { + expect(md4sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(md4sum("abc"), tests["abc"]); + }); + + test('with longest string', () { + var last = tests.entries.last; + expect(md4sum(last.key), last.value); + }); + + test('with special case', () { + var key = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + expect(md4sum(key), tests[key]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(md4sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(md4sum(key), value); + }); + }); + + test('with stream', () async { + final last = tests.entries.last; + final input = last.key.codeUnits; + final stream = Stream.fromIterable([ + input.take(7).toList(), + input.skip(7).take(10).toList(), + input.skip(17).take(15).toList(), + input.skip(32).toList(), + ]); + final result = await md4.bind(stream).first; + expect(result.hex(), last.value, reason: "'${last.key}'"); + }); + }); +} diff --git a/hashlib/test/md5_test.dart b/hashlib/test/md5_test.dart new file mode 100644 index 0000000..de9ed35 --- /dev/null +++ b/hashlib/test/md5_test.dart @@ -0,0 +1,118 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('MD5 test', () { + test('with empty string', () { + expect(md5sum(""), equals("d41d8cd98f00b204e9800998ecf8427e")); + }); + + test('with single letter', () { + expect(md5sum("a"), equals("0cc175b9c0f1b6a831c399e269772661")); + }); + + test('with few letters', () { + expect(md5sum("abc"), equals("900150983cd24fb0d6963f7d28e17f72")); + }); + + test('"message digest"', () { + final input = "message digest"; + final output = "f96b697d7cb7938d525a2f31aaf161d0"; + expect(md5sum(input), equals(output)); + }); + test('"abcdefghijklmnopqrstuvwxyz"', () { + final input = "abcdefghijklmnopqrstuvwxyz"; + final output = "c3fcd3d76192e4007dfb496cca67e13b"; + expect(md5sum(input), equals(output)); + }); + test('with string A-Za-z0-9', () { + final input = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + final output = "d174ab98d277d9f5a5611c2c9f419d9f"; + expect(md5sum(input), equals(output)); + }); + + test('with a very long number string', () { + final input = + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"; + final output = "57edf4a22be3c955ac49da2e2107b67a"; + expect(md5sum(input), equals(output)); + }); + test('"123"', () { + final input = "123"; + final output = "202cb962ac59075b964b07152d234b70"; + expect(md5sum(input), equals(output)); + }); + test('"test"', () { + final input = "test"; + final output = "098f6bcd4621d373cade4e832627b4f6"; + expect(md5sum(input), equals(output)); + }); + test('"message"', () { + final input = 'message'; + final output = "78e731027d8fd50ed642340b7c9a63b3"; + expect(md5sum(input), equals(output)); + }); + test('"Hello World"', () { + final input = "Hello World"; + final output = "b10a8db164e0754105b7a99be72e3fe5"; + expect(md5sum(input), equals(output)); + }); + test('List.filled(512, "a").join()', () { + final input = List.filled(512, "a").join(); + final output = "56907396339ca2b099bd12245f936ddc"; + expect(md5sum(input), equals(output)); + }); + test('List.filled(128, "a").join()', () { + final input = List.filled(128, "a").join(); + final output = "e510683b3f5ffe4093d021808bc6ff70"; + expect(md5sum(input), equals(output)); + }); + test('List.filled(513, "a").join()', () { + final input = List.filled(513, "a").join(); + final output = "6649c3e827e44f7bf539768bddf76435"; + expect(md5sum(input), equals(output)); + }); + test('List.filled(511, "a").join()', () { + final input = List.filled(511, "a").join(); + final output = "3ba3485f242a5859f4417ccf004cd74c"; + expect(md5sum(input), equals(output)); + }); + test('List.filled(1000000, "a").join()', () { + final input = List.filled(1000000, "a").join(); + final output = "7707d6ae4e027c70eea2a935c2296f21"; + expect(md5sum(input), equals(output)); + }, skip: true); + + test('with stream', () async { + final input = List.filled(511, "a").join(); + final stream = Stream.fromIterable(input.codeUnits); + final output = "3ba3485f242a5859f4417ccf004cd74c"; + final actual = await md5.byteStream(stream); + expect(actual.hex(), output); + }); + + test('sink test', () { + final input = List.filled(511, "a".codeUnitAt(0)); + final output = "3ba3485f242a5859f4417ccf004cd74c"; + final sink = md5.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < input.length; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/pbkdf2_test.dart b/hashlib/test/pbkdf2_test.dart new file mode 100644 index 0000000..36aabfc --- /dev/null +++ b/hashlib/test/pbkdf2_test.dart @@ -0,0 +1,187 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('PBKDF2 test', () { + test("name", () { + final iv = "key".codeUnits; + expect(sha256.pbkdf2(iv).name, 'SHA-256/HMAC/PBKDF2'); + expect(sha256.hmac.pbkdf2(iv).name, 'SHA-256/HMAC/PBKDF2'); + expect(sha1.pbkdf2(iv).name, 'SHA1/HMAC/PBKDF2'); + expect(sha1.hmac.pbkdf2(iv).name, 'SHA1/HMAC/PBKDF2'); + expect(md5.pbkdf2(iv).name, 'MD5/HMAC/PBKDF2'); + expect(md5.hmac.pbkdf2(iv).name, 'MD5/HMAC/PBKDF2'); + }); + test('fromSecurity', () { + var pw = 'password'.codeUnits; + var out = PBKDF2.fromSecurity(PBKDF2Security.little).convert(pw); + expect(out.length, PBKDF2Security.little.dklen); + }); + + test("Default method: pbkdf2", () { + var hash = pbkdf2( + 'password'.codeUnits, + "some salt".codeUnits, + 50, + 32, + ); + var matcher = + '09d106dccc35eae63c48aa472394de511547ce296ab55685b7ba8b304bec68fe'; + expect(hash.hex(), matcher); + }); + + test("with MD5", () { + final pw = 'password'.codeUnits; + final iv = "some salt".codeUnits; + final result = + '592e779487b7c4dc20ca5cd276163bbb760a40960bb17187cd4895238361d201'; + final output = md5.pbkdf2(iv, iterations: 100, keyLength: 32).hex(pw); + expect(output, equals(result)); + }); + + test("with MD5 through HMAC", () { + final pw = 'password'.codeUnits; + final iv = "some salt".codeUnits; + final result = '592e779487b7c4dc20ca5cd276163bbb'; + final output = md5.pbkdf2(iv, iterations: 100, keyLength: 16).hex(pw); + expect(output, equals(result)); + }); + + test("with SHA-1", () { + final pw = 'password'.codeUnits; + final iv = "some salt".codeUnits; + final result = + 'a001e5ddf0b823ccc74edc957ab881e7924ef5c608956cd7d32606b8d7c8acb1'; + final output = sha1.pbkdf2(iv, iterations: 100, keyLength: 32).hex(pw); + expect(output, equals(result)); + }); + + test("with SHA-224", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha224.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '57f86bc67aad5fa335f8f0f8ecd7b550c7f2462502d3058897299f49111f8948'; + expect(output, equals(matcher)); + }); + + test("with SHA-256", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha256.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '09d106dccc35eae63c48aa472394de511547ce296ab55685b7ba8b304bec68fe'; + expect(output, equals(matcher)); + }); + + test("with SHA-384", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha384.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '6091b46523e28ffa34d777f81c9ef446cd2983601a6dbdd8cc63aa0fa461b624'; + expect(output, equals(matcher)); + }); + + test("with SHA-512", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha512.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '05f45e131d21985a38c25cb30c9edee0bfe697d19fb84a0d55e89e2a347c7905'; + expect(output, equals(matcher)); + }); + + test("with SHA-512/224", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha512t224.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '7b03e2f53046cf52a0d8ace8f469bef3fdbe0a2b4b112b10586d33119a98aa94'; + expect(output, equals(matcher)); + }); + + test("with SHA-512/256", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha512t256.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '73b02a03a67fe08ab8fee80f2d135f4afb954380406994b0f2670a0f5d0c7faa'; + expect(output, equals(matcher)); + }); + + test("with SHA3-224", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha3_224.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '3543a75506759d603c2058847f39969f8d6c164ebc50c53eb44f290c7835521c'; + expect(output, equals(matcher)); + }); + + test("with SHA3-256", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha3_256.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + 'c4aae4cbf79071757bf167a8cff387a615295bed94320d394e9ed15a4b53a9c1'; + expect(output, equals(matcher)); + }); + + test("with SHA3-384", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha3_384.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + 'e39eef6add54c1b1cddb35dcf44cce8163941b1e73a26bd6f422dbdf4a98b7c0'; + expect(output, equals(matcher)); + }); + + test("with SHA3-512", () { + var pw = 'password'.codeUnits; + var iv = "some salt".codeUnits; + var output = sha3_512.pbkdf2(iv, iterations: 50, keyLength: 32).hex(pw); + var matcher = + '349d16a5e9cb37d277c0d05235c63bf1d094367c27968262d9d9460d96bbed79'; + expect(output, equals(matcher)); + }); + + test("long password with SHA-256", () { + var hash = pbkdf2( + 'passwd'.codeUnits, + "salt".codeUnits, + 1, + 256, + ); + var matcher = + '55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc' + '49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783' + 'c294e850150390e1160c34d62e9665d659ae49d314510fc98274cc7968196810' + '4b8f89237e69b2d549111868658be62f59bd715cac44a1147ed5317c9bae6b2a' + 'd89a7e71d005442240f5d97bd6d58c2cec9417c63f4ebf19661303a083c430c5' + 'ac29e5732761e3659cdf6a7b0f13f630042fadef4ed2c2a59d805b39590beedf' + '906b7f15744f4f2403cd27c0b61d9c270f6395a47e72cd57ff14a63eb0d38a7e' + 'fac778f409b9d733e12ca7afb23690b212e5f55397bdc884c73193cb2feec7ef'; + expect(hash.hex(), matcher); + }); + + test("The iterations must be at least 1", () { + expect(() => pbkdf2([9], [5], 0), throwsStateError); + expect(() => pbkdf2([9], [5], -1), throwsStateError); + }); + + test("The iterations must be less than 2^31", () { + expect(() => pbkdf2([9], [5], 0x80000000), throwsStateError); + expect(() => pbkdf2([9], [5], 0x8FFFFFFF), throwsStateError); + expect(() => pbkdf2([9], [5], 0xFFFFFFFF), throwsStateError); + }); + + test("The keyLength must be at least 1", () { + expect(() => pbkdf2([9], [5], 10, 0), throwsStateError); + expect(() => pbkdf2([9], [5], 10, -1), throwsStateError); + }); + }); +} diff --git a/hashlib/test/poly1305_test.dart b/hashlib/test/poly1305_test.dart new file mode 100644 index 0000000..0aff801 --- /dev/null +++ b/hashlib/test/poly1305_test.dart @@ -0,0 +1,295 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +const cases = [ + // Raw Poly1305 + // onetimeauth.c from nacl-20110221 + [ + "eea6a7251c1e72916d11c2cb214d3c25" "2539121d8e234e652d651fa4c8cff880", + "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a" + "c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738" + "b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da" + "99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5", + "f3ffc7703f9400e52a7dfb4b3d3305d9" + ], + // Specific test cases generated from test-poly1305aes from poly1305aes-20050218 that + // expose Java unsigned integer problems + [ + "01bcb20bfc8b6e03609ddd09f44b060f" "95cc0e44d0b79a8856afcae1bec4fe3c", + "66f75c0e0c7a40658629e3392f7f8e3349a02191ffd49f39879a8d9d1d0e23ea3caa4d240bd2ab8a8c4a6bb8d3288d9de4b793f05e97646dd4d98055de" + "fc3e0677d956b4c62664bac15962ab15d93ccbbc03aafdbde779162ed93b55361f0f8acaa41d50ef5175927fe79ea316186516eef15001cd04d3524a55" + "e4fa3c5ca479d3aaa8a897c21807f721b6270ffc68b6889d81a116799f6aaa35d8e04c7a7dd5e6da2519e8759f54e906696f5772fee093283bcef7b930" + "aed50323bcbc8c820c67422c1e16bdc022a9c0277c9d95fef0ea4ee11e2b27276da811523c5acb80154989f8a67ee9e3fa30b73b0c1c34bf46e3464d97" + "7cd7fcd0ac3b82721080bb0d9b982ee2c77feee983d7ba35da88ce86955002940652ab63bc56fb16f994da2b01d74356509d7d1b6d7956b0e5a557757b" + "d1ced2eef8650bc5b6d426108c1518abcbd0befb6a0d5fd57a3e2dbf31458eab63df66613653d4beae73f5c40eb438fbcfdcf4a4ba46320184b9ca0da4" + "dfae77de7ccc910356caea3243f33a3c81b064b3b7cedc7435c223f664227215715980e6e0bb570d459ba80d7512dbe458c8f0f3f52d659b6e8eef19ee" + "71aea2ced85c7a42ffca6522a62db49a2a46eff72bd7f7e0883acd087183f0627f3537a4d558754ed63358e8182bee196735b361dc9bd64d5e34e1074a" + "855655d2974cc6fa1653754cf40f561d8c7dc526aab2908ec2d2b977cde1a1fb1071e32f40e049ea20f30368ba1592b4fe57fb51595d23acbdace324cd" + "d78060a17187c662368854e915402d9b52fb21e984663e41c26a109437e162cfaf071b53f77e50000a5388ff183b82ce7a1af476c416d7d204157b3633" + "b2f4ec077b699b032816997e37bceded8d4a04976fd7d0c0b029f290794c3be504c5242287ea2f831f11ed5690d92775cd6e863d7731fd4da687ebfb13" + "df4c41dc0fb8", + "ae345d555eb04d6947bb95c0965237e2" + ], + [ + "cd07fd0ef8c0be0afcbdb30af4af0009" "76fb3635a2dc92a1f768163ab12f2187", + "f05204a74f0f88a7fa1a95b84ec3d8ffb36fcdc7723ea65dfe7cd464e86e0abf6b9d51" + "db3220cfd8496ad6e6d36ebee8d990f9ce0d3bb7f72b7ab5b3ab0a73240d11efe77" + "2c857021ae859db4933cdde4387b471d2ce700fef4b81087f8f47c307881fd83017a" + "fcd15b8d21edf9b704677f46df97b07e5b83f87c8abd90af9b1d0f9e2710e8ebd0d4" + "d1c6a055abea861f42368bed94d9373e909c1d3715b221c16bc524c55c31ec3eab20" + "4850bb2474a84f9917038eff9d921130951391b5c54f09b5e1de833ea2cd7d3b3067" + "40abb7096d1e173da83427da2adddd3631eda30b54dbf487f2b082e8646f07d6e0a8" + "7e97522ca38d4ace4954bf3db6dd3a93b06fa18eb56856627ed6cffcd7ae26374554" + "ca18ab8905f26331d323fe10e6e70624c7bc07a70f06ecd804b48f8f7e75e910165e" + "1beb554f1f0ec7949c9c8d429a206b4d5c0653102249b6098e6b45fac2a07ff0220b" + "0b8ae8f4c6bcc0c813a7cd141fa8b398b42575fc395747c5a0257ac41d6c1f434cfb" + "f5dfe8349f5347ef6b60e611f5d6c3cbc20ca2555274d1934325824cef4809da293e" + "a13f181929e2af025bbd1c9abdc3af93afd4c50a2854ade3887f4d2c8c225168052c" + "16e74d76d2dd3e9467a2c5b8e15c06ffbffa42b8536384139f07e195a8c9f70f514f3" + "1dca4eb2cf262c0dcbde53654b6250a29efe21d54e83c80e005a1cad36d5934ff01c3" + "2e4bc5fe06d03064ff4a268517df4a94c759289f323734318cfa5d859d4ce9c16e63" + "d02dff0896976f521607638535d2ee8dd3312e1ddc80a55d34fe829ab954c1ebd54d" + "929954770f1be9d32b4c05003c5c9e97943b6431e2afe820b1e967b19843e5985a13" + "1b1100517cdc363799104af91e2cf3f53cb8fd003653a6dd8a31a3f9d566a7124b0f" + "fe9695bcb87c482eb60106f88198f766a40bc0f4873c23653c5f9e7a8e446f770beb" + "8034cf01d21028ba15ccee21a8db918c4829d61c88bfa927bc5def831501796c5b40" + "1a60a6b1b433c9fb905c8cd40412fffee81ab", + "045be28cc52009f506bdbfabedacf0b4" + ], + // Test case from JIRA issue BJA-620 + [ + "ffffffffffffffffffffffffffffffff" "ffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffff", + "c80cb43844f387946e5aa6085bdf67da" + ], +]; + +void main() { + group('Poly1305 test', () { + test('the RFC sample', () { + var r = fromHex("85d6be7857556d337f4452fe42d506a8"); + var s = fromHex("0103808afb0db2fd4abff6af4149f51b"); + var m = "Cryptographic Forum Research Group".codeUnits; + var actual = "a8061dc1305136c6c22b8baf0c0127a9"; + expect(poly1305.pair(r, s).convert(m).hex(), actual); + }); + + test("example from NACL", () { + var key = [ + 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91, // + 0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25, + 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65, + 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80, + ]; + var msg = [ + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, // + 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, + 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, + 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, + 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, + 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, + 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, + 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, + 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, + 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, + 0xe3, 0x55, 0xa5 + ]; + var mac = [ + 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, // + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9 + ]; + var res = poly1305auth(msg, key); + expect(res.bytes, equals(mac)); + }); + + test("NACL example with wrap key", () { + var key = [ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + var msg = [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + ]; + var mac = [ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + var res = poly1305auth(msg, key); + expect(res.bytes, equals(mac)); + }); + + test("example from poly1305-donna", () { + var key = List.generate(32, (i) => (i + 221) & 0xFF); + var msg = List.generate(73, (i) => (i + 121) & 0xFF); + var mac = [ + 0xdd, 0xb9, 0xda, 0x7d, 0xdd, 0x5e, 0x52, 0x79, // + 0x27, 0x30, 0xed, 0x5c, 0xda, 0x5f, 0x90, 0xa4 + ]; + var res = poly1305auth(msg, key); + expect(res.bytes, mac); + }); + + test('key = strings of zeros', () { + var m = "Cryptographic Forum Research Group".codeUnits; + var key = List.filled(32, 0); + var actual = List.filled(16, 0); + expect(poly1305auth(m, key).bytes, equals(actual)); + }); + + test('random key, empty message', () { + var m = []; + var key = fromHex( + 'c90e3dd155bcd5dfc5ac9a73eed584e6652bd6b403cdafd31bed3427442d29a9', + ); + var actual = "652bd6b403cdafd31bed3427442d29a9"; + expect(poly1305auth(m, key).hex(), actual); + }); + + test('random key, single message', () { + var m = "0".codeUnits; + var key = fromHex( + 'b90e3dd1e5bc6cdfc5ac9a73eed584e6652bd3b409acdafd31bed3427442dae1', + ); + var actual = "1aa7542dcbfafa4e04e7808ab84a989f"; + expect(poly1305auth(m, key).hex(), actual); + }); + + test("buffered update", () { + var key = [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00 + ]; + var mac = [ + 0xc6, 0x9d, 0xc3, 0xb9, 0x75, 0xee, 0x5f, 0x6b, // + 0x28, 0x99, 0x57, 0x94, 0x41, 0x27, 0xd7, 0x5e, + ]; + + var sink = poly1305.by(key).createSink(); + for (int i = 0; i < 256; i++) { + var mac = poly1305 + .pair( + List.generate(16, (j) => i), + List.generate(16, (j) => 0xFF), + ) + .convert(List.generate(i, (j) => i)); + sink.add(mac.bytes); + } + expect(sink.digest().bytes, equals(mac)); + }); + + test("from bc-java test cases", () { + for (final x in cases) { + var mac = poly1305auth( + fromHex(x[1]), + fromHex(x[0]), + ); + expect(mac.hex(), x[2]); + } + }); + + test('pair with invalid key length', () { + var s = Uint8List(16); + expect(() => poly1305.pair([], s).convert([100]), throwsStateError); + expect(() => poly1305.pair([10], s).convert([100]), throwsStateError); + expect(() => poly1305.pair(Uint8List(32), s).convert([100]), + throwsStateError); + expect(() => poly1305.pair(Uint8List(20), s).convert([100]), + throwsStateError); + }); + + test('pair with invalid secret length', () { + var r = Uint8List(16); + expect(() => poly1305.pair(r, []).convert([100]), throwsStateError); + expect(() => poly1305.pair(r, [10]).convert([100]), throwsStateError); + expect(() => poly1305.pair(r, Uint8List(20)).convert([100]), + throwsStateError); + }); + + test('pair with secret = null and 16 bit key', () { + var r = fromHex("85d6be7857556d337f4452fe42d506a8"); + var m = "Cryptographic Forum Research Group".codeUnits; + var out1 = poly1305.pair(r).convert(m).hex(); + var out2 = poly1305auth(m, r).hex(); + expect(out1, equals(out2)); + }); + + test('pair with secret = null and 32 bit key', () { + var r = fromHex( + "85d6be7857556d337f4452fe42d506a8" + "0103808afb0db2fd4abff6af4149f51b", + ); + var m = "Cryptographic Forum Research Group".codeUnits; + var out1 = poly1305.pair(r).convert(m).hex(); + var out2 = poly1305auth(m, r).hex(); + expect(out1, equals(out2)); + }); + + test('sink test', () { + final key = fromHex(cases[2][0]); + final msg = fromHex(cases[2][1]); + final output = cases[2][2]; + + final sink = Poly1305Sink(key); + expect(sink.closed, isFalse); + for (int i = 0; i < msg.length; i += 7) { + sink.add(msg.skip(i).take(7).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(() => sink.add(msg), throwsStateError); + expect(sink.digest().hex(), equals(output)); + + sink.reset(); + expect(sink.closed, isFalse); + + sink.add(msg); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + + test("The key length must be either 16 or 32 bytes", () { + for (int i = 0; i < 64; ++i) { + final key = Uint8List(i); + if (i == 16 || i == 32) { + Poly1305Sink(key); + } else { + expect(() => Poly1305Sink(key), throwsA(isA())); + } + } + }); + }); +} diff --git a/hashlib/test/random/random_test.dart b/hashlib/test/random/random_test.dart new file mode 100644 index 0000000..9f5e718 --- /dev/null +++ b/hashlib/test/random/random_test.dart @@ -0,0 +1,429 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore_for_file: no_leading_underscores_for_local_identifiers + +import 'dart:isolate'; +import 'dart:typed_data'; + +import 'package:hashlib/random.dart'; +import 'package:hashlib/src/random/generators.dart'; +import 'package:test/test.dart'; + +const int _maxInt = 0xFFFFFFFF; + +@pragma('vm:entry-point') +void nextSeedIsolate(SendPort port) { + port.send($generateSeed()); +} + +var testRandom = HashlibRandom.custom(() => _maxInt); + +void runFunctionalText(HashlibRandom rand) { + rand.nextInt(); + rand.nextBetween(30, 50); + rand.nextBool(); + rand.nextByte(); + rand.nextBytes(10); + rand.nextDouble(); + rand.nextInt(); + rand.nextNumbers(10); + rand.nextString(10); + rand.nextWord(); +} + +void main() { + group('functional tests', () { + test("secure random", () { + runFunctionalText(HashlibRandom(RNG.secure)); + }); + test("system random", () { + runFunctionalText(HashlibRandom(RNG.system)); + }); + group("keccak random", () { + test('functions', () { + runFunctionalText(HashlibRandom(RNG.keccak)); + }); + test('with seed', () { + var rand = HashlibRandom(RNG.keccak, seed: 100); + expect(rand.nextInt(), 3662713900); + }); + }); + group("sha256 random", () { + test("functions", () { + runFunctionalText(HashlibRandom(RNG.sha256)); + }); + test('with seed', () { + var rand = HashlibRandom(RNG.sha256, seed: 100); + expect(rand.nextInt(), 3624764737); + }); + }); + group("sm3 random", () { + test("functions", () { + runFunctionalText(HashlibRandom(RNG.sm3)); + }); + test('with seed', () { + var rand = HashlibRandom(RNG.sm3, seed: 100); + expect(rand.nextInt(), 874203019); + }); + }); + group("md5 random", () { + test("functions", () { + runFunctionalText(HashlibRandom(RNG.md5)); + }); + test('with seed', () { + var rand = HashlibRandom(RNG.md5, seed: 100); + expect(rand.nextInt(), 368434865); + }); + }); + test("xxh64 random", () { + runFunctionalText(HashlibRandom(RNG.xxh64)); + }, tags: ['vm-only']); + }); + + test('seed generator uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask($generateSeed), + )); + expect(seeds.toSet().length, 1000); + }); + + test('seed generator uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn(nextSeedIsolate, receiver.sendPort), + )); + final seeds = await receiver.take(100).toList(); + expect(seeds.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + + test('random bytes length = 0', () { + expect(randomBytes(0), []); + }); + test('random bytes length = 1', () { + expect(randomBytes(1).length, 1); + }); + test('random bytes length = 100', () { + expect(randomBytes(100).length, 100); + }); + + test('random numbers length = 0', () { + expect(randomNumbers(0), []); + }); + test('random numbers length = 1', () { + expect(randomNumbers(1).length, 1); + }); + test('random numbers length = 100', () { + expect(randomNumbers(100).length, 100); + }); + test('random numbers value', () { + final result = randomNumbers(10); + expect(result, anyElement(greaterThan(255))); + }); + + test('fill random bytes', () { + var data = Uint8List(10); + fillRandom(data.buffer); + expect(data, anyElement(isNonZero)); + }); + + test('fill random numbers', () { + var data = Uint32List(10); + fillNumbers(data); + expect(data, anyElement(greaterThan(255))); + }); + + test('fill test random', () { + int i, c; + for (c = 0; c <= 100; ++c) { + for (i = 0; i + c <= 100; ++i) { + var data = Uint8List(100); + testRandom.fill(data.buffer, i, c); + int s = data.fold(0, (p, e) => p + (e > 0 ? 1 : 0)); + expect(s, c, reason: 'fill($i, $c) : $data'); + } + } + }); + + test('next between', () { + var rand = HashlibRandom.secure(); + expect(rand.nextBetween(0, 0), 0); + expect(rand.nextBetween(1, 1), 1); + expect(rand.nextBetween(5, 10), lessThanOrEqualTo(10)); + expect(rand.nextBetween(10, 5), greaterThanOrEqualTo(5)); + expect(rand.nextBetween(-5, -2), lessThan(0)); + expect(rand.nextBetween(-5, -15), lessThan(0)); + for (int i = 0; i < 100; ++i) { + expect(rand.nextBetween(0, 1), lessThanOrEqualTo(1)); + expect(rand.nextBetween(0, 3), lessThanOrEqualTo(3)); + expect(rand.nextBetween(0, 10), lessThanOrEqualTo(10)); + expect(rand.nextBetween(0, 50), lessThanOrEqualTo(50)); + expect(rand.nextBetween(0, 500), lessThanOrEqualTo(500)); + expect(rand.nextBetween(0, 85701), lessThanOrEqualTo(85701)); + expect(rand.nextBetween(1, _maxInt), greaterThanOrEqualTo(1)); + expect(rand.nextBetween(3, _maxInt), greaterThanOrEqualTo(3)); + expect(rand.nextBetween(10, _maxInt), greaterThanOrEqualTo(10)); + expect(rand.nextBetween(50, _maxInt), greaterThanOrEqualTo(50)); + expect(rand.nextBetween(500, _maxInt), greaterThanOrEqualTo(500)); + expect(rand.nextBetween(85701, _maxInt), greaterThanOrEqualTo(85701)); + } + }); + + test('random string throws StateError on empty whitelist', () { + expect( + () => randomString( + 50, + whitelist: [], + ), + throwsStateError); + expect( + () => randomString( + 50, + whitelist: [1, 2, 3], + blacklist: [1, 2, 3], + ), + throwsStateError); + expect( + () => randomString( + 50, + numeric: true, + blacklist: '0123456789'.codeUnits, + ), + throwsStateError); + }); + + group('HashlibRandom.nextString', () { + late HashlibRandom random; + final _lower = 'abcdefghijklmnopqrstuvwxyz'.codeUnits; + final _upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.codeUnits; + final _digits = '0123456789'.codeUnits; + final _controls = [ + 0, 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, + 127 + ]; + final _punctuations = [ + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // + 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126, + ]; + + setUp(() { + // Mock generator with predictable values + final items = [ + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, // + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84 + ]; + int p = 0; + random = HashlibRandom.custom(() { + p %= items.length; + return items[p++]; + }); + }); + + test('should return a string of correct length', () { + final result = random.nextString(10); + expect(result.length, equals(10)); + }); + + test('should contain only ASCII characters by default', () { + final result = random.nextString(10); + for (int i = 0; i < result.length; i++) { + expect(result.codeUnitAt(i), inInclusiveRange(0, 127)); + } + }); + + test('should include only lowercase characters when lower is true', () { + final result = random.nextString( + 25, + lower: true, + upper: false, + numeric: false, + controls: false, + punctuations: false, + ); + expect(result.codeUnits, everyElement(isIn(_lower))); + }); + + test('should include uppercase characters when upper is true', () { + final result = random.nextString( + 25, + lower: false, + upper: true, + numeric: false, + controls: false, + punctuations: false, + ); + expect(result.codeUnits, everyElement(isIn(_upper))); + }); + + test('should include numeric characters when numeric is true', () { + final result = random.nextString( + 25, + lower: false, + upper: false, + numeric: true, + controls: false, + punctuations: false, + ); + expect(result.codeUnits, everyElement(isIn(_digits))); + }); + + test('should include control characters when controls is true', () { + final result = random.nextString( + 25, + lower: false, + upper: false, + numeric: false, + controls: true, + punctuations: false, + ); + expect(result.codeUnits, everyElement(isIn(_controls))); + }); + + test('should include punctuation characters when punctuations is true', () { + final result = random.nextString( + 25, + lower: false, + upper: false, + numeric: false, + controls: false, + punctuations: true, + ); + expect(result.codeUnits, everyElement(isIn(_punctuations))); + }); + + test('should include multiple (lower, numeric)', () { + final result = random.nextString( + 50, + lower: true, + upper: false, + numeric: true, + controls: false, + punctuations: false, + ); + final matcher = [..._lower, ..._digits]; + expect(result.codeUnits, everyElement(isIn(matcher))); + }); + + test('should include multiple (upper, numeric)', () { + final result = random.nextString( + 50, + lower: false, + upper: true, + numeric: true, + controls: false, + punctuations: false, + ); + final matcher = [..._upper, ..._digits]; + expect(result.codeUnits, everyElement(isIn(matcher))); + }); + + test('should include multiple (numeric, controls)', () { + final result = random.nextString( + 50, + lower: false, + upper: false, + numeric: true, + controls: true, + punctuations: false, + ); + final matcher = [..._controls, ..._digits]; + expect(result.codeUnits, everyElement(isIn(matcher))); + }); + + test('should include multiple (lower, punctuations)', () { + final result = random.nextString( + 50, + lower: true, + upper: false, + numeric: false, + controls: false, + punctuations: true, + ); + final matcher = [..._lower, ..._punctuations]; + expect(result.codeUnits, everyElement(isIn(matcher))); + }); + + test('should use whitelist if provided', () { + final whitelist = [65, 66, 67]; // A, B, C + final result = random.nextString(10, whitelist: whitelist); + expect(result.codeUnits, everyElement(isIn(whitelist))); + }); + + test('should remove characters in blacklist', () { + final blacklist = [65, 66, 67]; // A, B, C + final result = random.nextString(10, blacklist: blacklist, lower: true); + expect(result.codeUnits, isNot(anyOf(blacklist))); + }); + + test('should throw StateError if whitelist is empty', () { + expect(() => random.nextString(10, whitelist: []), + throwsA(isA())); + }); + + test('should return an empty string if length is 0', () { + final result = random.nextString(0); + expect(result, isEmpty); + }); + + test('should return deterministic output with the same seed', () { + int p = 0, q = 0; + final random1 = HashlibRandom.custom(() => p++); + final random2 = HashlibRandom.custom(() => q++); + + final result1 = random1.nextString(10); + final result2 = random2.nextString(10); + + expect(result1, equals(result2)); + }); + }); + + group('Test \$seedList', () { + test('Test with a normal length list', () { + int seed = 123456789; + var data = Uint8List(64); + $seedList(data, seed); + expect(data, isNot(equals(Uint8List(64)))); + }); + + test('Test with small list', () { + int seed = 123456789; + for (int i = 1; i < 8; ++i) { + var data = Uint8List(i); + $seedList(data, seed); + expect(data, isNot(equals(Uint8List(i)))); + } + }); + + test('Test with uneven list', () { + int seed = 123456789; + for (int i = 1; i < 4; ++i) { + var data = Uint8List(64 + i); + $seedList(data, seed); + expect(data.skip(64), isNot(equals(Uint8List(i)))); + } + }); + + test('Test with same seed', () { + int seed = 123456789; + var data1 = Uint8List(255); + var data2 = Uint8List(255); + $seedList(data1, seed); + $seedList(data2, seed); + expect(data1, equals(data2)); + }); + + test('Test with different seed', () { + int seed1 = 123456789; + int seed2 = 987654321; + var data1 = Uint8List(255); + var data2 = Uint8List(255); + $seedList(data1, seed1); + $seedList(data2, seed2); + expect(data1, isNot(equals(data2))); + }); + }); +} diff --git a/hashlib/test/random/uuid_test.dart b/hashlib/test/random/uuid_test.dart new file mode 100644 index 0000000..d5d2012 --- /dev/null +++ b/hashlib/test/random/uuid_test.dart @@ -0,0 +1,297 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:isolate'; +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/src/uuid.dart'; +import 'package:test/test.dart'; + +@pragma('vm:entry-point') +void runIsolate(dynamic inp) { + final port = inp[0] as SendPort; + switch (inp[1] as String) { + case 'v1': + return port.send(uuid.v1()); + case 'v3': + return port.send(uuid.v3()); + case 'v4': + return port.send(uuid.v4()); + case 'v5': + return port.send(uuid.v5()); + case 'v6': + return port.send(uuid.v6()); + case 'v7': + return port.send(uuid.v7()); + case 'v8': + return port.send(uuid.v8()); + } + throw ArgumentError('Undefined version'); +} + +void main() { + group('UUID v1', () { + test("known value", () { + final time = DateTime.parse('2022-02-22T14:22:22-0500').toUtc(); + final clockSeq = 0x33C8; + final node = 0x9F6BDECED846; + final out = 'c232ab00-9414-11ec-b3c8-9f6bdeced846'; + final res = uuid.v1(node: node, clockSeq: clockSeq, utc: time); + expect(res, equals(out)); + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v1), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v1'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('UUID v3', () { + test("known value", () { + final namespace = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; + final name = 'www.example.com'; + final out = '5df41881-3aed-3515-88a7-2f4a814cf09e'; + final res = uuid.v3(name: name, namespace: namespace); + expect(res, equals(out)); + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v3), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v3'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('UUID v4', () { + test("known value", () { + final out = RegExp(r'........-....-4...-....-............'); + final res = uuid.v4(); + expect(res, matches(out)); + final part4 = fromHex(res.split('-')[3]).buffer.asUint8List(); + expect(part4[0] >>> 6, 2); + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v4), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v4'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('UUID v5', () { + test("known value", () { + final namespace = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; + final name = 'www.example.com'; + final out = '2ed6657d-e927-568b-95e1-2665a8aea6a2'; + final res = uuid.v5(name: name, namespace: namespace); + expect(res, equals(out)); + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v5), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v5'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('UUID v6', () { + test("known value", () { + final time = DateTime.parse('2022-02-22T14:22:22-0500').toUtc(); + final clockSeq = 0x33C8; + final node = 0x9F6BDECED846; + final out = '1ec9414c-232a-6b00-b3c8-9f6bdeced846'; + final res = uuid.v6(node: node, clockSeq: clockSeq, utc: time); + expect(res, equals(out)); + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v6), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v6'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('UUID v7', () { + test("known value", () { + final time = DateTime.parse('2022-02-22T14:22:22-0500').toUtc(); + final out = RegExp(r'017f22e2-79b0-7...-....-............'); + final res = uuid.v7(utc: time); + expect(res, matches(out)); + final part4 = fromHex(res.split('-')[3]).buffer.asUint8List(); + expect(part4[0] >>> 6, 2); + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v7), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v7'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('UUID v8', () { + test("known value 1", () { + final nonce = fromHex('2489E9AD2EE20E000EC932D5F69181C0'); + final out = '2489e9ad-2ee2-8e00-8ec9-32d5f69181c0'; + final res = uuid.v8(nonce: nonce); + expect(res, equals(out)); + }); + test("known value 2", () { + final nonce = fromHex('5c146b143c524afd938a375d0df1fbf6'); + final out = '5c146b14-3c52-8afd-938a-375d0df1fbf6'; + final res = uuid.v8(nonce: nonce); + expect(res, equals(out)); + }); + test("throws argument error on invalid nonce", () { + for (int i = 0; i < 20; ++i) { + final nonce = Uint8List(i); + if (i == 16) { + uuid.v8(nonce: nonce); + } else { + expect( + () => uuid.v8(nonce: nonce), + throwsArgumentError, + reason: 'length: $i', + ); + } + } + }); + test('uniqueness with futures', () async { + final seeds = await Future.wait(List.generate( + 1000, + (_) => Future.microtask(uuid.v8), + )); + expect(seeds.toSet().length, 1000); + }); + + test('uniqueness with isolates', () async { + final receiver = ReceivePort(); + await Future.wait(List.generate( + 100, + (_) => Isolate.spawn( + runIsolate, + [receiver.sendPort, 'v8'], + errorsAreFatal: true, + ), + )); + final items = await receiver.take(100).toList(); + expect(items.toSet().length, 100); + }, tags: ['vm-only'], timeout: Timeout(Duration(minutes: 5))); + }); + + group('NamespaceValue', () { + final matcher = matches('........-....-....-....-............'); + test('dns', () { + expect(Namespace.dns.value, matcher); + }); + test('url', () { + expect(Namespace.url.value, matcher); + }); + test('oid', () { + expect(Namespace.oid.value, matcher); + }); + test('x500', () { + expect(Namespace.x500.value, matcher); + }); + test('nil', () { + expect(Namespace.nil.value, matcher); + }); + test('max', () { + expect(Namespace.max.value, matcher); + }); + test('time', () { + expect(Namespace.time, matcher); + }); + }); +} diff --git a/hashlib/test/registry_test.dart b/hashlib/test/registry_test.dart new file mode 100644 index 0000000..c445e3d --- /dev/null +++ b/hashlib/test/registry_test.dart @@ -0,0 +1,89 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore_for_file: always_declare_return_types, deprecated_member_use_from_same_package + +import 'package:test/test.dart'; +import 'package:hashlib/hashlib.dart'; // Adjust the import path as needed + +// Mock or custom implementations for testing purposes +class CustomHashBase extends HashBase { + @override + String get name => 'custom-hash'; + + @override + createSink() { + throw UnimplementedError(); + } +} + +class CustomBlockHashBase extends BlockHashBase { + @override + String get name => 'custom-block-hash'; + + @override + createSink() { + throw UnimplementedError(); + } +} + +void main() { + group('HashRegistry', () { + test('lookup should return the correct HashBase algorithm by name', () { + expect(HashRegistry.lookup('SHA-256'), equals(sha256)); + expect(HashRegistry.lookup('sha256'), equals(sha256)); + expect(HashRegistry.lookup('SHA2'), equals(sha256)); + expect(HashRegistry.lookup('md5'), equals(md5)); + expect(HashRegistry.lookup('blake2b512'), equals(blake2b512)); + }); + + test('lookup should return null for an unknown algorithm name', () { + expect(HashRegistry.lookup('unknown-algo'), isNull); + }); + + test('register should add a new HashBase algorithm', () { + final customHash = CustomHashBase(); + HashRegistry.register(customHash); + expect(HashRegistry.lookup(customHash.name), equals(customHash)); + }); + + test('register should override an existing HashBase algorithm', () { + final customHash = CustomHashBase(); + HashRegistry.register(customHash, 'Sha-256'); + expect(HashRegistry.lookup('sha256'), equals(customHash)); + }); + + test('register should add BlockHashBase algorithm', () { + HashRegistry.register(md5, 'test-md5'); + expect(HashRegistry.lookup('test-md5'), equals(md5)); + expect(BlockHashRegistry.lookup('test-md5'), equals(md5)); + }); + }); + + group('BlockHashRegistry', () { + test('lookup should return the correct algorithm by name', () { + expect(BlockHashRegistry.lookup('blake2b512'), equals(blake2b512)); + expect(BlockHashRegistry.lookup('BLAKE2'), equals(blake2b512)); + expect(BlockHashRegistry.lookup('sha3_512'), equals(sha3_512)); + expect(BlockHashRegistry.lookup('sha3-384'), equals(sha3_384)); + expect(BlockHashRegistry.lookup('sha3 256'), equals(sha3_256)); + }); + + test('lookup should return null for an unknown algorithm', () { + expect(BlockHashRegistry.lookup('unknown-algo'), isNull); + }); + + test('register should add a new BlockHashBase algorithm', () { + final customBlockHash = CustomBlockHashBase(); + BlockHashRegistry.register(customBlockHash); + expect(BlockHashRegistry.lookup(customBlockHash.name), + equals(customBlockHash)); + }); + + test('register should override an existing BlockHashBase algorithm', () { + final customBlockHash = CustomBlockHashBase(); + BlockHashRegistry.register(customBlockHash, 'blake2b512'); + expect(BlockHashRegistry.lookup('blake2b512'), equals(customBlockHash)); + }); + }); +} diff --git a/hashlib/test/ripemd128_test.dart b/hashlib/test/ripemd128_test.dart new file mode 100644 index 0000000..27a0784 --- /dev/null +++ b/hashlib/test/ripemd128_test.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('RIPEMD-128 test', () { + test('with defined cases', () { + var m = [ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890123456789012345678901234" + "5678901234567890", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + ]; + var r = [ + "cdf26213a150dc3ecb610f18f6b38b46", + "86be7afa339d0fc7cfc785e72f578d33", + "c14a12199c66e4ba84636b0f69144c77", + "9e327b3d6e523062afc1132d7df9d1b8", + "fd2aa607f71dc8f510714922b371834e", + "a1aa0689d0fafa2ddc22e88b49133a06", + "d1e959eb179c911faea4624c60c5c702", + "3f45ef194732c2dbb2c4a2c769795fa3", + "7388178e5d59f3a68b4bf524f6c7a970", + "f49f55294493b91df0a2592440a5e2ca", + ]; + for (var i = 0; i < m.length; ++i) { + expect(ripemd128sum(m[i]), r[i]); + } + }); + test('with a millian "a"', () { + var m = List.filled(1000000, 'a'.codeUnitAt(0)); + var r = "4a7f5723f954eba1216c9d8f6320431f"; + expect(ripemd128.convert(m).hex(), r); + }, skip: true); + + test('sink test', () { + final input = + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + .codeUnits; + final output = "3f45ef194732c2dbb2c4a2c769795fa3"; + final sink = ripemd128.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < input.length; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/ripemd160_test.dart b/hashlib/test/ripemd160_test.dart new file mode 100644 index 0000000..5155f2b --- /dev/null +++ b/hashlib/test/ripemd160_test.dart @@ -0,0 +1,84 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('RIPEMD-160 test', () { + test('with empty string', () { + var m = ""; + var r = "9c1185a5c5e9fc54612808977ee8f548b2258d31"; + expect(ripemd160sum(m), r); + }); + test('with long string 1', () { + var m = "The quick brown fox jumps over the lazy dog"; + var r = "37f332f68db77bd9d7edd4969571ad671cf9dd3b"; + expect(ripemd160sum(m), r); + }); + test('with long string 2', () { + var m = "The quick brown fox jumps over the lazy cog"; + var r = "132072df690933835eb8b6ad0b77e7b6f14acad7"; + expect(ripemd160sum(m), r); + }); + test('with defined cases', () { + var m = [ + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890123456789012345678901234" + "5678901234567890", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + ]; + var r = [ + "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", + "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", + "5d0689ef49d2fae572b881b123a85ffa21595f36", + "f71c27109c692c1b56bbdceb5b9d2865b3708dbc", + "12a053384a9c0c88e405a06c27dcf49ada62eb2b", + "b0e20b6e3116640286ed3a87a5713079b21f5189", + "9b752e45573d4b39f4dbd3323cab82bf63326bfb", + "1f931a136bf9f411832ab15bd11a8953111febef", + "53875380569546ee9738f5a59fdea9db521cb9ce", + ]; + for (var i = 0; i < m.length; ++i) { + expect(ripemd160sum(m[i]), r[i]); + } + }); + test('with a millian "a"', () { + var m = List.filled(1000000, 'a'.codeUnitAt(0)); + var r = '52783243c1697bdbe16d37f97f68f08325dc1528'; + expect(ripemd160.convert(m).hex(), r); + }, skip: true); + test('string: "Hello, world!"', () { + var m = "Hello, world!"; + var r = "58262d1fbdbe4530d8865d3518c6d6e41002610f"; + expect(ripemd160sum(m), r); + }); + + test('sink test', () { + final input = + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + .codeUnits; + final output = "9b752e45573d4b39f4dbd3323cab82bf63326bfb"; + final sink = ripemd160.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < input.length; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/ripemd256_test.dart b/hashlib/test/ripemd256_test.dart new file mode 100644 index 0000000..3db185e --- /dev/null +++ b/hashlib/test/ripemd256_test.dart @@ -0,0 +1,68 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('RIPEMD-256 test', () { + test('with defined cases', () { + var m = [ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890123456789012345678901234" + "5678901234567890", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + ]; + var r = [ + "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", + "f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925", + "afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65", + "87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e", + "649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133", + "3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f", + "5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", + "06fdcc7a409548aaf91368c06a6275b553e3f099bf0ea4edfd6778df89a890dd", + "03d951c62461ff80f687d64d29f0a4af554b50fa4373782f0d8170fb579a04c2", + "ae09a84230167ebce8a512f37afe8cf46a572537ca026c74be1f94c8bda074e4", + ]; + for (var i = 0; i < m.length; ++i) { + expect(ripemd256sum(m[i]), r[i]); + } + }); + test('with a millian "a"', () { + var m = List.filled(1000000, 'a'.codeUnitAt(0)); + var r = "ac953744e10e31514c150d4d8d7b6773" + "42e33399788296e43ae4850ce4f97978"; + expect(ripemd256.convert(m).hex(), r); + }, skip: true); + + test('sink test', () { + final input = + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + .codeUnits; + final output = + "06fdcc7a409548aaf91368c06a6275b553e3f099bf0ea4edfd6778df89a890dd"; + final sink = ripemd256.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < input.length; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/ripemd320_test.dart b/hashlib/test/ripemd320_test.dart new file mode 100644 index 0000000..bcceeff --- /dev/null +++ b/hashlib/test/ripemd320_test.dart @@ -0,0 +1,68 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('RIPEMD-320 test', () { + test('with defined cases', () { + var m = [ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890123456789012345678901234" + "5678901234567890", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678901", + ]; + var r = [ + "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", + "ce78850638f92658a5a585097579926dda667a5716562cfcf6fbe77f63542f99b04705d6970dff5d", + "de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d", + "3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197", + "cabdb1810b92470a2093aa6bce05952c28348cf43ff60841975166bb40ed234004b8824463e6b009", + "d034a7950cf722021ba4b84df769a5de2060e259df4c9bb4a4268c0e935bbc7470a969c9d072a1ac", + "ed544940c86d67f250d232c30b7b3e5770e0c60c8cb9a4cafe3b11388af9920e1b99230b843c86a4", + "557888af5f6d8ed62ab66945c6d2a0a47ecd5341e915eb8fea1d0524955f825dc717e4a008ab2d42", + "6904accd706958e5a3945d41229c6d043a80d3524a04e1fe9f9570b64ab1d91629b31c40a76d2ca6", + "44723549cc506a8e0782494e87d510837225c493185b4c4a630b807d5e40e73038aa5923f3c3309e", + ]; + for (var i = 0; i < m.length; ++i) { + expect(ripemd320sum(m[i]), r[i]); + } + }); + test('with a millian "a"', () { + var m = List.filled(1000000, 'a'.codeUnitAt(0)); + var r = "bdee37f4371e20646b8b0d862dda16292ae36f4" + "0965e8c8509e63d1dbddecc503e2b63eb9245bb66"; + expect(ripemd320.convert(m).hex(), r); + }, skip: true); + + test('sink test', () { + final input = + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + .codeUnits; + final output = + "557888af5f6d8ed62ab66945c6d2a0a47ecd5341e915eb8fea1d0524955f825dc717e4a008ab2d42"; + final sink = ripemd320.createSink(); + expect(sink.closed, isFalse); + for (int i = 0; i < input.length; i += 48) { + sink.add(input.skip(i).take(48).toList()); + } + expect(sink.digest().hex(), equals(output)); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + sink.reset(); + sink.add(input); + sink.close(); + expect(sink.closed, isTrue); + expect(sink.digest().hex(), equals(output)); + }); + }); +} diff --git a/hashlib/test/scrypt_test.dart b/hashlib/test/scrypt_test.dart new file mode 100644 index 0000000..6c18dca --- /dev/null +++ b/hashlib/test/scrypt_test.dart @@ -0,0 +1,268 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('scrypt test', () { + test("with empty password and empty salt and r=1", () { + var hash = scrypt( + [], + [], + N: 16, + r: 1, + p: 1, + dklen: 64, + ); + var matcher = + '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442' + 'fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906'; + expect(hash.hex(), matcher); + }); + + test("with empty password and empty salt and r=2", () { + var hash = scrypt( + [], + [], + N: 16, + r: 2, + p: 1, + dklen: 64, + ); + var matcher = + '5517696d05d1df94fb42f067d9fcdb14d9effe8ac37500957e1b6f1d383ea029' + '61accf2409bba1ae87c94c6fc69f9b32393eea0b877eb7803c2f151a888acdb6'; + expect(hash.hex(), matcher); + }); + + test("with empty password and empty salt and p=2", () { + var hash = scrypt( + [], + [], + N: 16, + r: 1, + p: 2, + dklen: 64, + ); + var matcher = + '7e0ce022d41610408361d487a4962d0b39f8172397d62e911108b5ad4adb3dc7' + 'faf817f593b6b83cc42b040d975d564ce1fdb2c432e7cbe8cdcaa5a0ad6bf647'; + expect(hash.hex(), matcher); + }); + + test("with empty password and 'salt'", () { + var hash = scrypt( + [], + "salt".codeUnits, + N: 16, + r: 1, + p: 1, + dklen: 64, + ); + var matcher = + 'eec80a460eeaab62fe1630b19497e7ba6a1ff85f50807b9cfe52a9f192e5b60c' + 'b73563d28e4cb148ba301a2271de3682b88c4677caa2e061d2d0e29990cd4e09'; + expect(hash.hex(), matcher); + }); + + test("with 'password' and empty salt", () { + var hash = scrypt( + "password".codeUnits, + [], + N: 16, + r: 1, + p: 1, + dklen: 64, + ); + var matcher = + 'd33c6ec1818daaf728f55afadfeaa558b38efa81305b3521a7f12f4be097e84d' + '184092d2a2e93bf71fd1efe052710f66b956ce45da43aa9099de7406d3a05e2a'; + expect(hash.hex(), matcher); + }); + + test("with empty 'passwd' and 'salt'", () { + var hash = scrypt( + "passwd".codeUnits, + "salt".codeUnits, + N: 16, + r: 1, + p: 1, + dklen: 64, + ); + var matcher = + 'd1635540c8e908f949eaf651eef261cd38e73e0c5c0fe1673e21d72442edb957' + '7bcaa47ea345a789ec687efd4c21224c7cc9fd892954c40df024bf44d6b8bf2a'; + expect(hash.hex(), matcher); + }); + + test("with a long key length", () { + var hash = scrypt( + "a test key".codeUnits, + "some salt".codeUnits, + N: 16, + r: 8, + p: 2, + dklen: 256, + ); + var matcher = '9ddb1ba07f1973893a3f2629c23449b4ab189eef07a3a8b521cd129' + 'ee43cb39067ce849085311849736159ec828d09b0f8f423051dddfb85835730eb' + '455af9a27a46f198d301e5f6ad678c0ec7c3559bf390887563e951d1070f1613f' + '8f68eeb565196bf8896a948e183af3e10127e098230e86870c3b6b62f43a7ac9f' + '9078619d93c4dadffb4d198bccd9676eb979102b48ccd6ab6f31ce6f4e1cf420e' + 'cfc6f4840fc30eebd6223dfeed1aa95637c6d594386317885e2b2817e6e88b502' + 'd7d9896b01877c97791d0e5ca6e7d9982b59a7655710f343713e2bc2259624792' + '795bdc9cef22b805c36d15102b1eda1d62f766b02579ef74fb4488faa91973a2a00'; + expect(hash.hex(), matcher); + }); + + test("with long r and p parameters", () { + var hash = scrypt( + "a test key".codeUnits, + "some salt".codeUnits, + N: 16, + r: 28, + p: 22, + dklen: 128, + ); + var matcher = '48a2b70cc60f0608775f6616167492381f1a6673c4422fe76f3197c8' + '45d35844fee961ef7cf5783bb2b5a84883423e766be1224f2435bdc738245a0d025' + '2a3626a73e1548f3807b4a8fe39b779deedf200deb593d078f2e98e989b90030ab3' + '9938bf52fa291683fd8ebaa1abbfedee33a2df7b3cf1b000e5b8634097990c7ce4'; + expect(hash.hex(), matcher); + }); + + test("with random N, r, p", () { + var hash = scrypt( + "a test key".codeUnits, + "some salt".codeUnits, + N: 128, + r: 81, + p: 49, + dklen: 120, + ); + var matcher = '183944033aa4a4fc92c783b6d40236220a1985ddbed2e6b29abb5d382' + 'aecfac52e992d3eb779f7573c66f563d4365e8dae680ecdb59a017af70ed30f398a' + 'f4fd0a0cb3bf9c9dc04e3f177936249ac87d619ed41b6b05d2d6dfe95d32153338b' + 'c03c4b68fd46e13c9c0e7f7946ee6856cf068f1702e2fbd98'; + expect(hash.hex(), matcher); + }); + + test("with security", () { + var hash = scrypt( + [], + [], + security: ScryptSecurity.test, + ); + var matcher = + '5517696d05d1df94fb42f067d9fcdb14d9effe8ac37500957e1b6f1d383ea029' + '61accf2409bba1ae87c94c6fc69f9b32393eea0b877eb7803c2f151a888acdb6'; + expect(hash.hex(), matcher); + }); + + test("with security overrides", () { + var hash = scrypt( + [], + [], + security: ScryptSecurity.test, + r: 1, + ); + var matcher = + '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442' + 'fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906'; + expect(hash.hex(), matcher); + }); + }); + + group('Scrypt Factory Tests', () { + test("with security", () { + var hash = Scrypt.fromSecurity(ScryptSecurity.test, salt: []); + var matcher = + '5517696d05d1df94fb42f067d9fcdb14d9effe8ac37500957e1b6f1d383ea029' + '61accf2409bba1ae87c94c6fc69f9b32393eea0b877eb7803c2f151a888acdb6'; + expect(hash.convert([]).hex(), matcher); + }); + + test('throws if cost is less than 1', () { + expect( + () => Scrypt(cost: 0), + throwsA(isA().having( + (e) => e.message, 'message', 'The cost must be at least 1')), + ); + }); + + test('throws if cost is greater than 2^24', () { + expect( + () => Scrypt(cost: 0x1000000), + throwsA(isA().having( + (e) => e.message, 'message', 'The cost must be less than 2^24')), + ); + }); + + test('throws if cost is not a power of 2', () { + expect( + () => Scrypt(cost: 5), + throwsA(isA().having( + (e) => e.message, 'message', 'The cost must be a power of 2')), + ); + }); + + test('throws if derivedKeyLength is less than 1', () { + expect( + () => Scrypt(cost: 2, derivedKeyLength: 0), + throwsA(isA().having((e) => e.message, 'message', + 'The derivedKeyLength must be at least 1')), + ); + }); + + test('throws if blockSize is less than 1', () { + expect( + () => Scrypt(cost: 2, blockSize: 0), + throwsA(isA().having( + (e) => e.message, 'message', 'The blockSize must be at least 1')), + ); + }); + + test('throws if parallelism is less than 1', () { + expect( + () => Scrypt(cost: 2, parallelism: 0), + throwsA(isA().having( + (e) => e.message, 'message', 'The parallelism must be at least 1')), + ); + }); + + test('throws if blockSize * parallelism is too big', () { + expect( + () => Scrypt(cost: 2, blockSize: 0x2000000, parallelism: 1), + throwsA(isA().having((e) => e.message, 'message', + 'The blockSize * parallelism is too big')), + ); + }); + + test('uses provided salt if not null', () { + var salt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + var scrypt = Scrypt(cost: 2, salt: salt); + expect(scrypt.salt, equals(salt)); + }); + + test('generates a random salt if salt is null', () { + var scrypt = Scrypt(cost: 2); + expect(scrypt.salt.length, 16); + }); + + test('creates an instance with valid parameters', () { + var salt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + var scrypt = Scrypt( + cost: 2, + salt: salt, + blockSize: 8, + parallelism: 1, + derivedKeyLength: 64); + expect(scrypt.salt, equals(salt)); + expect(scrypt.cost, equals(2)); + expect(scrypt.blockSize, equals(8)); + expect(scrypt.parallelism, equals(1)); + expect(scrypt.derivedKeyLength, equals(64)); + }); + }); +} diff --git a/hashlib/test/sha1_test.dart b/hashlib/test/sha1_test.dart new file mode 100644 index 0000000..2704a13 --- /dev/null +++ b/hashlib/test/sha1_test.dart @@ -0,0 +1,76 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "a": "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", + "abc": "a9993e364706816aba3e25717850c26c9cd0d89d", + "123": "40bd001563085fc35165329ea1ff5c5ecbdbbeef", + "test": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + 'message': "6f9b9af3cd6e8b8a73c2cdced37fe9f59226e27d", + "Hello World": "0a4d55a8d778e5022fab701977c5d840bbc486d0", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": + "761c457bf73b14d27e9e9265c46f4b4dda11f940", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890": + "50abf5706a150990a08b2c5ea40fa0e585554732", + "The quick brown fox jumps over the lazy dog": + "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + "The quick brown fox jumps over the lazy cog": + "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "84983e441c3bd26ebaae4aa1f95129e5e54670f1", + List.filled(512, "a").join(): "164557facb73929875168c1e92caf09bb6064564", + List.filled(128, "a").join(): "ad5b3fdbcb526778c2839d2f151ea753995e26a0", + List.filled(513, "a").join(): "87ecd7233dbe9d7543a9a199fc671a90e469873d", + List.filled(511, "a").join(): "b9370eafb7ac772c6c1dc6b88ac9ad466b880ea1", + List.filled(1000000, "a").join(): "34aa973cd4c4daa4f61eeb2bdbad27316534016f", +}; + +void main() { + group('SHA1 test', () { + test('with empty string', () { + expect(sha1sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha1sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha1sum("abc"), tests["abc"]); + }); + + test('with longest string', () { + var last = tests.entries.last; + expect(sha1sum(last.key), last.value); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha1sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha1sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha1.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/sha224_test.dart b/hashlib/test/sha224_test.dart new file mode 100644 index 0000000..ffa3cf0 --- /dev/null +++ b/hashlib/test/sha224_test.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", + "a": "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", + "abc": "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": + "bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890": + "b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e", + "The quick brown fox jumps over the lazy dog": + "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525", + "The quick brown fox jumps over the lazy cog": + "fee755f44a55f20fb3362cdc3c493615b3cb574ed95ce610ee5b1e9b", + List.filled(512, "a").join(): + "e926c6b764d4b216c99067c92f838ca1c5793c13c782d9ef7b668d71", + List.filled(128, "a").join(): + "39873a2441c56608137850f4c54dde157710b9a2b83c8bdc756dd643", + List.filled(513, "a").join(): + "e0afca6342847c80827fdc511f0004e53239d3c2f82f67ddd8185bef", + List.filled(511, "a").join(): + "6eb1c24577241c0871ec3ab020786f59cecb2edb6acef2d483051d6a", + List.filled(1000000, "a").join(): + "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", +}; + +void main() { + group('SHA224 test', () { + test('with empty string', () { + expect(sha224sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha224sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha224sum("abc"), tests["abc"]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha224sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha224sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha224.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/sha256_test.dart b/hashlib/test/sha256_test.dart new file mode 100644 index 0000000..82094c2 --- /dev/null +++ b/hashlib/test/sha256_test.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "a": "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "abc": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": + "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890": + "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e", + "The quick brown fox jumps over the lazy dog": + "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + "The quick brown fox jumps over the lazy cog": + "e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be", + List.filled(512, "a").join(): + "471be6558b665e4f6dd49f1184814d1491b0315d466beea768c153cc5500c836", + List.filled(128, "a").join(): + "6836cf13bac400e9105071cd6af47084dfacad4e5e302c94bfed24e013afb73e", + List.filled(513, "a").join(): + "02425c0f5b0dabf3d2b9115f3f7723a02ad8bcfb1534a0d231614fd42b8188f6", + List.filled(511, "a").join(): + "058fc5084b6355a06099bfef3de8e360344046dc5a47026de47470b9aabb5bfd", + List.filled(1000000, "a").join(): + "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", +}; + +void main() { + group('SHA256 test', () { + test('with empty string', () { + expect(sha256sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha256sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha256sum("abc"), tests["abc"]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha256sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha256sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha256.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/sha384_test.dart b/hashlib/test/sha384_test.dart new file mode 100644 index 0000000..88614f3 --- /dev/null +++ b/hashlib/test/sha384_test.dart @@ -0,0 +1,79 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c" + "0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", + "a": "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce" + "9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", + "abc": "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a" + "8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe" + "8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b", + "The quick brown fox jumps over the lazy dog": + "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c4940" + "11e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", + "The quick brown fox jumps over the lazy cog": + "098cea620b0978caa5f0befba6ddcf22764bea977e1c70b348" + "3edfdf1de25f4b40d6cea3cadf00f809d422feb1f0161b", + List.filled(512, "a").join(): + "e685ba7acf4eedd1742f2a97c845e7825982d840623525e491" + "40680fdde0f2631e5fce9dfcfb42ba7b27c9eb35a62b87", + List.filled(128, "a").join(): + "edb12730a366098b3b2beac75a3bef1b0969b15c48e2163c23" + "d96994f8d1bef760c7e27f3c464d3829f56c0d53808b0b", + List.filled(513, "a").join(): + "c3f1d47c5dad5c3b8cc1242da14220af7f9036acf98369be3c" + "c102b069476a9b3e50b9a131756396c8c267dce06a35f0", + List.filled(511, "a").join(): + "db100a1eed3842c61d73064b62543cd4531dafa8bfecf6f27d" + "cfdebbaf60ea14563ea1b486e4f6b9a14fcb0dac05c5f2", + List.filled(1000000, "a").join(): + "9d0e1809716474cb086e834e310a4a1ced149e9c00f2485279" + "72cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985", +}; + +void main() { + group('SHA384 test', () { + test('with empty string', () { + expect(sha384sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha384sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha384sum("abc"), tests["abc"]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha384sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha384sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha384.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/sha3_test.dart b/hashlib/test/sha3_test.dart new file mode 100644 index 0000000..c6bb8ab --- /dev/null +++ b/hashlib/test/sha3_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('SHA3 test', () { + test('name', () { + expect(sha3_224.name, 'SHA3-224'); + expect(sha3_256.name, 'SHA3-256'); + expect(sha3_384.name, 'SHA3-384'); + expect(sha3_512.name, 'SHA3-512'); + }); + + test('SHA3-224 with empty string', () { + expect(sha3_224sum(""), + "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"); + }); + + test('SHA3-384 with exact block size', () { + final input = + "e35780eb9799ad4c77535d4ddb683cf33ef367715327cf4c4a58ed9cbdcdd486" + "f669f80189d549a9364fa82a51a52654ec721bb3aab95dceb4a86a6afa93826d" + "b923517e928f33e3fba850d45660ef83b9876accafa2a9987a254b137c6e140a" + "21691e1069413848"; + final output = + "d1c0fa85c8d183beff99ad9d752b263e286b477f79f0710b0103170173978133" + "44b99daf3bb7b1bc5e8d722bac85943a"; + expect(sha3_384.convert(fromHex(input)).hex(), output); + final encoded = String.fromCharCodes(fromHex(input)); + expect(sha3_384sum(encoded), output); + }); + + test('SHA3-256 with short message', () { + final input = + "9f2fcc7c90de090d6b87cd7e9718c1ea6cb21118fc2d5de9f97e5db6ac1e9c10"; + final output = + "2f1a5f7159e34ea19cddc70ebf9b81f1a66db40615d7ead3cc1f1b954d82a3af"; + expect(sha3_256.convert(fromHex(input)).hex(), output); + }); + + test('SHA3-512 with multi block size', () { + final input = + "3a3a819c48efde2ad914fbf00e18ab6bc4f14513ab27d0c178a188b61431e7f5" + "623cb66b23346775d386b50e982c493adbbfc54b9a3cd383382336a1a0b2150a" + "15358f336d03ae18f666c7573d55c4fd181c29e6ccfde63ea35f0adf5885cfc0" + "a3d84a2b2e4dd24496db789e663170cef74798aa1bbcd4574ea0bba40489d764" + "b2f83aadc66b148b4a0cd95246c127d5871c4f11418690a5ddf01246a0c80a43" + "c70088b6183639dcfda4125bd113a8f49ee23ed306faac576c3fb0c1e256671d" + "817fc2534a52f5b439f72e424de376f4c565cca82307dd9ef76da5b7c4eb7e08" + "5172e328807c02d011ffbf33785378d79dc266f6a5be6bb0e4a92eceebaeb1"; + final output = + "6e8b8bd195bdd560689af2348bdc74ab7cd05ed8b9a57711e9be71e9726fda45" + "91fee12205edacaf82ffbbaf16dff9e702a708862080166c2ff6ba379bc7ffc2"; + expect(sha3_512.convert(fromHex(input)).hex(), output); + final encoded = String.fromCharCodes(fromHex(input)); + expect(sha3_512sum(encoded), output); + }); + + test('SHA3-256 with "a"', () { + final input = "a"; + final output = + "80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b"; + expect(sha3_256sum(input), output); + }); + + test('SHA3-256 with "abc"', () { + final input = "abc"; + final output = + "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"; + expect(sha3_256sum(input), output); + }); + + test('SHA3-256 with long arbitrary string', () { + final input = "A quick brown fox jumps over the lazy dog"; + final output = + "2baa15b5a204f74ae708d588793657a70cda2288a06e7e12c918cc3aedc5cd8d"; + expect(sha3_256sum(input), output); + }); + }); +} diff --git a/hashlib/test/sha512_224_test.dart b/hashlib/test/sha512_224_test.dart new file mode 100644 index 0000000..a290861 --- /dev/null +++ b/hashlib/test/sha512_224_test.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", + "a": "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327", + "abc": "4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "e5302d6d54bb242275d1e7622d68df6eb02dedd13f564c13dbda2174", + "The quick brown fox jumps over the lazy dog": + "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37", + "The quick brown fox jumps over the lazy cog": + "2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5", + List.filled(512, "a").join(): + "057bab73fa47ac3e597a34d02c1e285e2d5d8a2e90c9079f549b4af6", + List.filled(128, "a").join(): + "261b94bcba554264b3b738e9e09e7dc68ac8e0b4c8517fe9bb7c3617", + List.filled(513, "a").join(): + "502ec9656e1e0b96f9a2699c04cec265edc690b729c45037c6b37a00", + List.filled(511, "a").join(): + "bd0452a57045c857de05b1c1d94fb49624b00ceaf0ec4c0d4d656a89", + List.filled(1000000, "a").join(): + "37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287", + List.filled(112, "a").join(): + "79b41fef2a0439d2705724a67615f7bcbcd2bf5664a7774b80818eb6", +}; + +void main() { + group('SHA512224 test', () { + test('with empty string', () { + expect(sha512t224sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha512t224sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha512t224sum("abc"), tests["abc"]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha512t224sum(key), value); + }); + + test('known cases', () { + tests.forEach((key, value) { + // print(toHex(crypto.sha512224.convert(toBytes(key)).bytes)); + expect(sha512t224sum(key), value); + }); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha512t224sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha512t224.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/sha512_256_test.dart b/hashlib/test/sha512_256_test.dart new file mode 100644 index 0000000..b120689 --- /dev/null +++ b/hashlib/test/sha512_256_test.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", + "a": "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8", + "abc": "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "bde8e1f9f19bb9fd3406c90ec6bc47bd36d8ada9f11880dbc8a22a7078b6a461", + "The quick brown fox jumps over the lazy dog": + "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d", + "The quick brown fox jumps over the lazy cog": + "cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb", + List.filled(512, "a").join(): + "092b65b92e80ccf4c66683684fb02da4567160534abede190e9b2edef6156839", + List.filled(128, "a").join(): + "b88f97e274f9c1d49f181c8cbd01a9c74930ad055a46ac4499a1d601f1c80bf2", + List.filled(513, "a").join(): + "a59cf33e5ad3e70d4962adbb833d021eafa48f85dd9788f84fca4cf762c5f1c7", + List.filled(511, "a").join(): + "7e627ccc0719192627fcf9f3987d3da9a61f261a09580371e1ea4622b8ccfcc8", + List.filled(1000000, "a").join(): + "9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21", + List.filled(112, "a").join(): + "9216b5303edb66504570bee90e48ea5beaa5e9fe9f760bbd3e0460559fc005f6", +}; + +void main() { + group('SHA512256 test', () { + test('with empty string', () { + expect(sha512t256sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha512t256sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha512t256sum("abc"), tests["abc"]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha512t256sum(key), value); + }); + + test('known cases', () { + tests.forEach((key, value) { + // print(toHex(crypto.sha512256.convert(toBytes(key)).bytes)); + expect(sha512t256sum(key), value); + }); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha512t256sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha512t256.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/sha512_test.dart b/hashlib/test/sha512_test.dart new file mode 100644 index 0000000..eb73529 --- /dev/null +++ b/hashlib/test/sha512_test.dart @@ -0,0 +1,82 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:math'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +final tests = { + "": "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" + "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", + "a": "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f53" + "02860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", + "abc": "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": + "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335" + "96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445", + "The quick brown fox jumps over the lazy dog": + "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64" + "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", + "The quick brown fox jumps over the lazy cog": + "3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4a" + "b3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045", + List.filled(512, "a").join(): + "0210d27bcbe05c2156627c5f136ade1338ab98e06a4591a00b0bcaa61662a593" + "1d0b3bd41a67b5c140627923f5f6307669eb508d8db38b2a8cd41aebd783394b", + List.filled(128, "a").join(): + "b73d1929aa615934e61a871596b3f3b33359f42b8175602e89f7e06e5f658a24" + "3667807ed300314b95cacdd579f3e33abdfbe351909519a846d465c59582f321", + List.filled(513, "a").join(): + "ebfd31a4fae71ce18d1df9c4c8cfa9803d8390fc3ef3c122c3ddf4015af96abd" + "90ffc16f3f0ef66ffd28295603250407402e68a0cc0bcd5f38b9557717ea3d39", + List.filled(511, "a").join(): + "fe32a1f497ce532d041889133436c7086ea40410af5728a6b958aa4a169de44e" + "3884311461188be5f65e79b9a53d010d8347ac20118e4e05df787a17ba71204b", + List.filled(1000000, "a").join(): + "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb" + "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b", + List.filled(112, "a").join(): + "c01d080efd492776a1c43bd23dd99d0a2e626d481e16782e75d54c2503b5dc32" + "bd05f0f1ba33e568b88fd2d970929b719ecbb152f58f130a407c8830604b70ca", +}; + +void main() { + group('SHA512 test', () { + test('with empty string', () { + expect(sha512sum(""), tests[""]); + }); + + test('with single letter', () { + expect(sha512sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sha512sum("abc"), tests["abc"]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sha512sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sha512sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sha512.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/shake_test.dart b/hashlib/test/shake_test.dart new file mode 100644 index 0000000..3d8fe6f --- /dev/null +++ b/hashlib/test/shake_test.dart @@ -0,0 +1,145 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; +import 'dart:async'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +void main() { + group('SHAKE test', () { + test("Shake128 name", () { + expect(Shake128(8).name, 'SHAKE-128/64'); + expect(shake128.of(4).name, 'SHAKE-128/32'); + expect(shake128_128.name, 'SHAKE-128/128'); + expect(shake128_160.name, 'SHAKE-128/160'); + expect(shake128_224.name, 'SHAKE-128/224'); + expect(shake128_256.name, 'SHAKE-128/256'); + expect(shake128_384.name, 'SHAKE-128/384'); + expect(shake128_512.name, 'SHAKE-128/512'); + }); + + test("Shake256 name", () { + expect(Shake256(8).name, 'SHAKE-256/64'); + expect(shake256.of(4).name, 'SHAKE-256/32'); + expect(shake256_128.name, 'SHAKE-256/128'); + expect(shake256_160.name, 'SHAKE-256/160'); + expect(shake256_224.name, 'SHAKE-256/224'); + expect(shake256_256.name, 'SHAKE-256/256'); + expect(shake256_384.name, 'SHAKE-256/384'); + expect(shake256_512.name, 'SHAKE-256/512'); + }); + + test('SHAKE-128 with empty message', () { + expect( + shake128.of(512).convert([]).hex().substring((512 - 32) * 2), + "43e41b45a653f2a5c4492c1add544512dda2529833462b71a41a45be97290b6f", + ); + }); + + test('shake128sum', () { + expect( + shake128sum('a test message', 32), + "763cd3748d2c24843f8f1c9b1ae78514f10e1e9a964e81e1295609fc81c936e0", + ); + }); + + test('shake128sum with encoding', () { + expect( + shake128sum('a test message', 32, utf8, true), + "763CD3748D2C24843F8F1C9B1AE78514F10E1E9A964E81E1295609FC81C936E0", + ); + }); + + test('SHAKE-128 with some message', () { + var inp = 'a test message'.codeUnits; + expect( + shake128.of(128).convert(inp).hex(), + "763cd3748d2c24843f8f1c9b1ae78514f10e1e9a964e81e1295609fc81c936e0" + "55b4b59405ad0509a27e80273f8219ee4fb25e77f3ca75994fbe1c0753014575" + "6364ae785175d206393eb5808166fdee95f80256c0ec53ebd1ffba21f56f0603" + "c01b0d0842977a4570612a5f184e39d60a59d605b281810a9fb2c387e5beacfe", + ); + }); + + test('SHAKE-128 with 1600-bit message', () async { + final sc = StreamController>(); + final digest = shake128.of(512).bind(sc.stream); + final buf = List.filled(20, 0xA3); + for (int i = 0; i < 200; i += 20) { + sc.sink.add(buf); + } + sc.close(); + final out = await digest.first; + expect( + out.hex().substring((512 - 32) * 2), + "44c9fb359fd56ac0a9a75a743cff6862f17d7259ab075216c0699511643b6439", + ); + }); + + test('shake256sum', () { + expect( + shake256sum('a test message', 32), + "06cd8095b01a33a20e67c1c265af4079a8b861687d6e87e447861c4221dbe83d", + ); + }); + + test('shake256sum with encoding', () { + expect( + shake256sum('a test message', 32, utf8, true), + "06CD8095B01A33A20E67C1C265AF4079A8B861687D6E87E447861C4221DBE83D", + ); + }); + + test('SHAKE-256 with some message', () { + var inp = 'a test message'.codeUnits; + expect( + shake256.of(128).convert(inp).hex(), + "06cd8095b01a33a20e67c1c265af4079a8b861687d6e87e447861c4221dbe83d" + "e9c36540e3e4b9b7f75f84e1d8fc57451d2fca0b052691d4cb448e0fe2132419" + "3feb52911aeedb57093d07b3ba128508271de6554cc651415e5af3f1b4d09d53" + "7e87b0b7685031e09a848d60ff6a86c5f9f5a5b5a3070ce677b949264f6b4046", + ); + }); + + test('SHAKE-256 with empty message', () { + expect( + shake256.of(512).convert([]).hex().substring((512 - 32) * 2), + "ab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a", + ); + }); + + test('SHAKE-256 with 1600-bit message', () async { + final sc = StreamController>(); + final digest = shake256.of(512).bind(sc.stream); + final buf = List.filled(20, 0xA3); + for (int i = 0; i < 200; i += 20) { + sc.sink.add(buf); + } + sc.close(); + final out = await digest.first; + expect(out.hex().substring((512 - 32) * 2), + "6a1a9d7846436e4dca5728b6f760eef0ca92bf0be5615e96959d767197a0beeb"); + }); + + test('SHAKE-128 generator', () { + var original = shake128.of(1024).convert([]).bytes; + expect(shake128generator().take(1024), equals(original)); + }); + test('SHAKE-256 generator', () { + var original = shake256.of(1024).convert([]).bytes; + expect(shake256generator().take(1024), equals(original)); + }); + test('SHAKE-128 generator with seed', () { + var seed = '012345678910111213141516171819'.codeUnits; + var original = shake128.of(1024).convert(seed).bytes; + expect(shake128generator(seed).take(1024), equals(original)); + }); + test('SHAKE-256 generator with seed', () { + var seed = '012345678910111213141516171819'.codeUnits; + var original = shake256.of(1024).convert(seed).bytes; + expect(shake256generator(seed).take(1024), equals(original)); + }); + }); +} diff --git a/hashlib/test/sm3_test.dart b/hashlib/test/sm3_test.dart new file mode 100644 index 0000000..8c401cc --- /dev/null +++ b/hashlib/test/sm3_test.dart @@ -0,0 +1,93 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; +import 'package:pointycastle/digests/sm3.dart' as pc_sm3; + +final tests = { + "": "1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b", + "a": "623476ac18f65a2909e43c7fec61b49c7e764a91a18ccb82f1917a29c86c5e88", + "abc": "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", + "message digest": + "c522a942e89bd80d97dd666e7a5531b36188c9817149e9b258dfe51ece98ed77", + "abcdefghijklmnopqrstuvwxyz": + "b80fe97a4da24afc277564f66a359ef440462ad28dcc6d63adb24d5c20a61595", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": + "2971d10c8842b70c979e55063480c50bacffd90e98e2e60d2512ab8abfdfcec5", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890": + "ad81805321f3e69d251235bf886a564844873b56dd7dde400f055b7dde39307a", + "123": "6e0f9e14344c5406a0cf5a3b4dfb665f87f4a771a31f7edbb5c72874a32b2957", + "test": "55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23", + 'message': "1756ac517f85ffda751dcdebf3c89575272fc56904f9baad983ec44c36feac7b", + "Hello World": + "77015816143ee627f4fa410b6dad2bdb9fcbdf1e061a452a686b8711a484c5d7", + List.filled(512, "a").join(): + "d2219631eeb014040abf9716ebba9b35aaba4ecc2065088df0a2cbd0db1b9ce9", + List.filled(128, "a").join(): + "5fd947effbe82a5925faaee9123d43cea200cc257b28ed797505694b4bb020f6", + List.filled(513, "a").join(): + "97baef04b5211a439b17eb067ad904e52b12058d7510669ad29b63b9d4609479", + List.filled(511, "a").join(): + "5f4141700026fec7880a6d1d5f34dcc9253dea2df32928f71bc93860d675b38c", + List.filled(1000000, "a").join(): + "c8aaf89429554029e231941a2acc0ad61ff2a5acd8fadd25847a3a732b3b02c3", +}; + +void main() { + group('SM3 test', () { + test('with empty string', () { + expect(sm3sum(""), tests[""]); + }); + + test('with single letter -pc', () { + pc_sm3.SM3Digest().process(Uint8List.fromList("a".codeUnits)); + }); + + test('with single letter', () { + expect(sm3sum("a"), tests["a"]); + }); + + test('with few letters', () { + expect(sm3sum("abc"), tests["abc"]); + }); + + test('with longest string', () { + var last = tests.entries.last; + expect(sm3sum(last.key), last.value); + }); + + test('with special case', () { + var key = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + expect(sm3sum(key), tests[key]); + }); + + test('with string of length 511', () { + var key = tests.keys.firstWhere((x) => x.length == 511); + var value = tests[key]!; + expect(sm3sum(key), value); + }); + + test('with known cases', () { + tests.forEach((key, value) { + expect(sm3sum(key), value); + }); + }); + + test('with stream', () async { + for (final entry in tests.entries) { + final stream = Stream.fromIterable( + List.generate(1 + (entry.key.length >>> 3), (i) => i << 3)) + .map((e) => entry.key.substring(e, min(entry.key.length, e + 8))) + .map((s) => s.codeUnits); + final result = await sm3.bind(stream).first; + expect(result.hex(), entry.value); + } + }); + }); +} diff --git a/hashlib/test/totp_test.dart b/hashlib/test/totp_test.dart new file mode 100644 index 0000000..20d0f47 --- /dev/null +++ b/hashlib/test/totp_test.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:test/test.dart'; +import 'package:hashlib/hashlib.dart'; + +void main() { + final secret = Uint8List.fromList([ + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + ]); + + group('TOTP', () { + test('algorithm name', () { + expect(TOTP(secret).name, 'SHA1/HMAC'); + expect(TOTP(secret, algo: md5).name, 'MD5/HMAC'); + }); + + test('secret, label and issuer values', () { + var totp = TOTP(secret, label: 'test label', issuer: 'test issuer'); + expect(totp.secret, equals(secret)); + expect(totp.label, equals('test label')); + expect(totp.issuer, equals('test issuer')); + + var totp2 = TOTP(secret); + expect(totp2.secret, equals(secret)); + expect(totp2.label, null); + expect(totp2.issuer, null); + }); + + test('should generate OTP of correct length', () { + expect(TOTP(secret).valueString().length, equals(6)); + }); + + test('number of digits must be at least 4', () { + for (int i = 0; i < 20; ++i) { + int cb() => TOTP(secret, digits: i).valueString().length; + if (i < 4 || i > 15) { + expect(cb, throwsA((e) => e is AssertionError), reason: 'digits: $i'); + } else { + expect(cb(), equals(i), reason: 'digits: $i'); + } + } + }); + + test('should generate different OTPs over time', () { + var totp = TOTP(secret); + int time = 30000 - totp.currentTime % 30000; + totp.adjustClock(time); + int otp1 = totp.value(); + totp.adjustClock(time + 30000); + int otp2 = totp.value(); + expect(otp1, isNot(equals(otp2))); + totp.adjustClock(time + 1); + int otp3 = totp.value(); + expect(otp1, equals(otp3)); + totp.adjustClock(time - 100); + int otp4 = totp.value(); + expect(otp1, isNot(equals(otp4))); + }); + + test('should adjust the clock correctly', () { + var totp1 = TOTP(secret); + var totp2 = TOTP(secret); + totp2.adjustClock(30030); + + int otp1 = totp1.value(); + int otp2 = totp2.value(); + + expect(otp1, isNot(equals(otp2))); + }); + + test('stream should emit OTPs periodically', () async { + int ms = 80; + var totp = TOTP(secret, period: Duration(milliseconds: ms)); + totp.adjustClock(ms - totp.currentTime % ms); + final otps = {}; + var subscription = totp.stream.listen((otp) { + otps.add(otp); + }); + await Future.delayed( + Duration(milliseconds: 4 * ms), + subscription.cancel, + ); + expect(otps.length, inInclusiveRange(2, 6)); + }); + + test('stream should emit OTP string periodically', () async { + int ms = 80; + var totp = TOTP(secret, period: Duration(milliseconds: ms)); + totp.adjustClock(ms - totp.currentTime % ms); + final otps = {}; + var subscription = totp.streamString.listen((otp) { + otps.add(otp); + }); + await Future.delayed( + Duration(milliseconds: 4 * ms), + subscription.cancel, + ); + expect(otps.length, inInclusiveRange(2, 6)); + }); + }); +} diff --git a/hashlib/test/xxh128_test.dart b/hashlib/test/xxh128_test.dart new file mode 100644 index 0000000..eef633f --- /dev/null +++ b/hashlib/test/xxh128_test.dart @@ -0,0 +1,128 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore: library_annotations +@Tags(['vm-only']) + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +const seed = 0x9e3779b185ebca8d; +final cases = fromHex( + '0052929bb732a3242d00af950eecb893e3dfef93aad6cd2a538b5c3f545a6fd559c0fffc8f85b9331dab74f7b6059327b07084b3677c9f76480072ed7b9817e8dd485e0c0ccbd0653fadb28f11b06ce88db0f186086159566c8e4e781363bdab9d327309ea712fd97a9d55f0ca8ad0e95e1a36b36b0fca51ef8ba2c462ed0096f33449eb0fd13b92a1a963dbaaed3dcff10942cdf9b321a2ebf2c8f4e42f48d14b10f4c2efecf84ab53874c3a4a6620ebffd633741e386981aeb4cba56036687ed004559c18544b6c368f941a9eaf987e09f12d0d51454485d444051e338069a4c3c0def6489f8a361eee3c51c9368c8e597d70998ff97a84ceaa479abcd2cc89f1bf2f1cee282503882ad8e9bb8b488818eb636d9a96548743cc9dbfcbbd82a229eb424e2b267abaa13e22a4dfc711c076291bdf8e2975d0c84fd6745671b099a4b20a2773095da28b1863f9ef2e1db10df90f86d912f0678b3485bdff6dbd87ca7aea589404c027320f09fdd637995b103c47e6f2fe022f6d488e9666e9d3519bd411b4f1acfd578b00049f01f8f8df614bcb5946dc45376a7a75391cf8db6166c397e362f06f2231e8e0fc886f476618ef66436fc8c27a1fa12cbfece583f8167886c7dc081e7f8c08e540ec9d9519d219035690a0baca171444b9f45fe9d981f1e1b776c5df1fb7e2c64fe6b571968cddde4d009361a609962d707e64d0986f78e9b2f42d983cba5caad2262757f5b40ef1aafec48756b22b5c405004d2a097d8b8d6ebb5cd4a6b2a10d24acaf16f37f6ebafd0d0791d263f1bb83de41481b7431e2f33f19a750f24e5bae206093d50c7ea5527798ecd52c0d52e75cae0484effbaecdb45cbac8ce982bd0a3a2e6256eb9cc066ab27f56578b4caa09214f4ac3904ba9d00736cf54119e27e39f503f58c294d47188a7814ed78f1e5d21ddc2016d5a1fd194b659885e377d176e8e1655107ccf70eae75029a542e03028a01e3dd559b168737022d33d2a634613aedb1e350598a1dd56f0e3dc62b1cc259122db36fc998c813776d677f3acf44c16a684ffda1082fc1f4f73e87cf5a96829b37fa47b1f2ca010aba85d82adf74eb7130c4d4ef53fa3938892ef424cfc95bfd276c2928f86903b7b845f7b57c9b95af823b3263d411ede092bbddc53138b199ba2f7f58c317390c5a1d3b943706c768efe8fd306f59d84d075dafdc074f24bb42a776fd4be4a472606f04d2c901cde7e083828801606663bfc74e59c926f26ad0e2505451f421ffeba7ef6133be520acebb0b22a31301a6cc0a6a2a5f241299e4819e225c4713a79ddbe1fcf634355761336bf3a3a70026000a7114e675d36640ff0df89c016c657d4701296c94f9bbaacc7572385e1a056f9511a2b18cfd6a773ee01defd63ea25c7ea5473c72a71b3f6a52b7a9819254d77951405cf9d42f6544e4c77ec3648cc47ac94810d108850f7a2d8c1ca827bd7c42d092627fbe6065ee7c61ad70aa64029c0e4211a91b19f4d007edaaae26da8f51308daec116b3396c89a7750e3426221cb8039e5f2f22820431816cf20c5c1650b93711c520b41981eba8507ce90fbdc9b9603c8cfbf4c0d8faa40a096cd43a7b3a48ab29a0a5e812d87b6990b0500e2732bbe8992d1dfe590a30f47d6966ae6558db19630ff3825f357f7bdcae02ec36a4df3ea5f14751d3fabda08062b5934e38fdb9dfbc5181663f17475debd527d867ffaf8a976f9cf383a7fb98ec2e70d4eb288de12a3b47907691cccae0f646d4c57aed99d835f109a33e23703aaa9bc92e9e11dfc6481b926ecd2e10d69f66bfe022fa623138786e4ff702ce1c6111b92815068efd923946d8b57cc99f339129a7cf872394360f16c5489a4d8ee7f9e1911b48b7275ab0076fed358991439a34cea606aff7ed88eab3fc54d0cb5c766083e6b39af5b11e34a100b2750cbc031dcb3047fc2310b0992a47e89d7a09870fed21b8c027d8c948034364907fb973d369c89ddef5590d2e5c907cb41e2f9e36bc43479180c119c397379192347bb3008406509d7e0ce8c874187ee9a6fedd150faceb93ebf7f2dcfc6f15acff65a930def663ab3a6856c54bf61aa380cfc9e97a9aea84d23a732b694759bdf8c602e6d28e9186e27e61d3538996b86de70972e75ce6add5e87f184f6e0f4dfd678a43378b3e62b45c51ebaebaf434ed79e3ac25ef4bb3685e2a0ddf30e311d396e70c7b7ab84a9c4941090badbdc3517a1e0390e7984d4d561536af2729d151b0995cc45a1b60cf02ce3dd789cb620558b83c1c78b8cefd33e2cc21962a3527950a2cefea375b4c86462839d153b551416a17dd0d523f6a29ea4a659fd8b7a9a8e0c8c54580e4765e0fc0512ae82d35b741692f692fd876b6f54aa6fda98f21f1643bb17123127687a44c392e4ea9a5eeb369f38b503db0bcf8ad22560011f91493c881a5f05059819fffe564c0a1c7a873a4994f81745e4bd9279a5ec0a01cffd871f0a0fd161dbb03a02953da066a21f82d83d3a7acfd9f37943aab6e27babe872f474a9953c259a38a29894ba1f46aef1888db89ca84c8ca08bf69c9c6a4450fc821a948056e97da613fb9d38a56dd42e744253f07600406f5362ba041389c5e3b5512d06d72037e0fbdc049441d11b44b495335760aab1ee556efbc876b25439226151d24dcd74bc89a065a4954889938415b7a2e406710f653b9abc5338fb94b16bcda96a7cc8890114dfd603ffa5ea071abb8d720c36f20564b6e4be4315f3528594e9051b46c559a4c13c027c36d95efffe96e11caa567a14e4166f3d902bcd7157005d0eed2efd793e7e008d6c4dac4058ebce9d350a7f6f07f7ecbec4b4c75da6ebae3c229d032ea8a68bce62dd9e045d9e16c8270a1c2c3b481c98f7616edd8872a172095fa012c96b2c8d56f00f6adf517c1b5d89e5f9255ea75b698a5659de7c4b375860d2a3409899661c6b506a9e3fd001c81b62298acf065f2b0080e5cba7cddfc6e6cb44f9c9610cd3588bfc6fd1a91bc9b20dad644703bcb6fc738cbec1d7602227b6da3dac9532f452e490dd6224aca11de17d69b8d16aa323d9cc8cabb41d935f2174dfa063c47b7893d65548ca72d73c1cf543e6d22aac8cf71c7aa8ba9a6bce4aa39085f508d6e6a537a1a61d58af074d', +); +final secret = cases.sublist(7, 7 + 136 + 11); + +String sum([Iterable? data]) { + return xxh128.convert(data?.toList() ?? []).hex(); +} + +String seedsum([Iterable? data]) { + return XXH128().withSeed(seed).convert(data?.toList() ?? []).hex(); +} + +String secretSum([Iterable? data]) { + return XXH128(secret: secret).convert(data?.toList() ?? []).hex(); +} + +void main() { + group('xxh3-128 test', () { + test("xxh128sum", () { + final input = String.fromCharCodes(cases.take(1)); + final output = "a6cd5e9392000f6ac44bdff4074eecdb"; + expect(xxh128sum(input), output); + }); + test("with secret", () { + expect(secretSum(cases.take(6)), '376bd91b6432f36d0b61c8aca7d4778f'); + }); + + test('The secret length must be at least 136', () { + for (int i = 0; i < 136; ++i) { + var instance = xxh3_128.withSecret(Uint8List(i)); + expect(() => instance.convert([2]), throwsArgumentError); + } + }); + + test("with input length = 0", () { + expect(sum(), "99aa06d3014798d86001c324468d497f"); + }); + test("with input length = 0 and a seed", () { + expect(seedsum(), "00feaa732a3ce25ea986dfc5d7605bfe"); + }); + test("with input length = 1", () { + expect(sum(cases.take(1)), "a6cd5e9392000f6ac44bdff4074eecdb"); + }); + test("with input length = 1 and a seed", () { + expect(seedsum(cases.take(1)), "20e49abcc53b3842032be332dd766ef8"); + }); + test("with input length = 6", () { + expect(sum(cases.take(6)), "082afe0b8162d12a3e7039bdda43cfc6"); + }); + test("with input length = 6 and a seed", () { + expect(seedsum(cases.take(6)), "014bd95a51ca5ddbc5b54d56038e4e40"); + }); + test("with input length = 12", () { + expect(sum(cases.take(12)), "6e3efd8fc7802b18061a192713f69ad9"); + }); + test("with input length = 12 and a seed", () { + expect(seedsum(cases.take(12)), "ff0d60acd02ed4015d92b5d7190b12d1"); + }); + test("with input length = 24", () { + expect(sum(cases.take(24)), "0ce966e4678d37611e7044d28b1b901d"); + }); + test("with input length = 24 and a seed", () { + expect(seedsum(cases.take(24)), "d7895ded1f62559dc6cbf92a70680b19"); + }); + test("with input length = 48", () { + expect(sum(cases.take(48)), "a002ac4e5478227ef942219aed80f67b"); + }); + test("with input length = 48 and a seed", () { + expect(seedsum(cases.take(48)), "bc689f4c0152fb443a94d91333ed395a"); + }); + test("with input length = 81", () { + expect(sum(cases.take(81)), "4952f58181ab00425e8bafb9f95fb803"); + }); + test("with input length = 81 and a seed", () { + expect(seedsum(cases.take(81)), "941e9469c46edd08dc50feb227515233"); + }); + test("with input length = 222", () { + expect(sum(cases.take(222)), "337e09641b948717f1aebd597cec6b3a"); + }); + test("with input length = 222 and a seed", () { + expect(seedsum(cases.take(222)), "4740af1ae0618b49c5871b3be4506a30"); + }); + test("with input length = 403", () { + expect(sum(cases.take(403)), "1b6de21e332dd73dcdeb804d65c6dea4"); + }); + test("with input length = 403 and a seed", () { + expect(seedsum(cases.take(403)), "bed311971e0be8f26259f6ecfd6443fd"); + }); + test("with input length = 512", () { + expect(sum(cases.take(512)), "18d2d110dcc9bca1617e49599013cb6b"); + }); + test("with input length = 512 and a seed", () { + expect(seedsum(cases.take(512)), "925d06b8ec5b80403ce457de14c27708"); + }); + test("with input length = 2048", () { + expect(sum(cases.take(2048)), "f736557fd47073a5dd59e2c3a5f038e0"); + }); + test("with input length = 2048 and a seed", () { + expect(seedsum(cases.take(2048)), "23cc3a2e75ebaaea66f81670669ababc"); + }); + test("with input length = 2240", () { + expect(sum(cases.take(2240)), "ccb134fbfa7ce49d6e73a90539cf2948"); + }); + test("with input length = 2240 and a seed", () { + expect(seedsum(cases.take(2240)), "e40842f585875ba9757ba8487d1b5247"); + }); + test("with input length = 2237", () { + expect(sum(cases.take(2237)), "0cdabf3f3c98b371f403cea1763cd9cc"); + }); + test("with input length = 2237 and a seed", () { + expect(seedsum(cases.take(2237)), "3eef572c60cbcdc0f7a5385336bef410"); + }); + }); +} diff --git a/hashlib/test/xxh32_test.dart b/hashlib/test/xxh32_test.dart new file mode 100644 index 0000000..5a72932 --- /dev/null +++ b/hashlib/test/xxh32_test.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +const seed = 0x9E3779B1; +const data = [ + 158, 255, 31, 75, 94, 83, 47, 221, 181, 84, 77, 42, 149, 43, 87, 174, 93, // + 186, 116, 233, 211, 166, 76, 152, 48, 96, 192, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +]; + +void main() { + group('XXHash32 test', () { + test('xxh32code', () { + expect(xxh32code(String.fromCharCodes(data)), 0x1f1aa412); + }); + + test('with seed = 0 and an empty string', () { + expect(xxh32.convert([]).hex(), "02cc5d05"); + }); + test('with seed = 0 and a single letter', () { + expect(xxh32.convert([data[0]]).hex(), "b85cbee5"); + }); + test('with seed = 0 and 14 letters', () { + final input = String.fromCharCodes(data.take(14)); + expect(xxh32sum(input), "e5aa0ab4"); + }); + test('with seed = 0 and 101 letters', () { + expect(xxh32.convert(data).number(), 0x1f1aa412); + }); + + test('with a seed and an empty string', () { + final input = []; + expect(xxh32.withSeed(seed).convert(input).hex(), "36b78ae7"); + }); + + test('with a seed and a single letter', () { + final input = [data[0]]; + expect(xxh32.withSeed(seed).convert(input).hex(), "d5845d64"); + }); + + test('with a seed and 14 letters', () { + final input = data.take(14).toList(); + expect(xxh32.withSeed(seed).convert(input).hex(), "4481951d"); + }); + + test('with a seed and 101 letters', () { + expect(xxh32.withSeed(seed).convert(data).hex(), "498ec8e2"); + }); + + test('with 32-byte message', () { + final input = "string of 32-bytes long for test"; + expect(xxh32code(input), 0x90d90755); + }); + + test('with 64-byte message', () { + final input = + "string of 64-bytes for test. twice the size of 32-byte string."; + expect(xxh32code(input), 0x0b438557); + }); + }); +} diff --git a/hashlib/test/xxh3_test.dart b/hashlib/test/xxh3_test.dart new file mode 100644 index 0000000..018b4b8 --- /dev/null +++ b/hashlib/test/xxh3_test.dart @@ -0,0 +1,173 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore: library_annotations +@Tags(['vm-only']) + +import 'dart:typed_data'; + +import 'package:hashlib/codecs.dart'; +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +const seed = 0x9e3779b185ebca8d; +final cases = fromHex( + '0052929bb732a3242d00af950eecb893e3dfef93aad6cd2a538b5c3f545a6fd559c0fffc8f85b9331dab74f7b6059327b07084b3677c9f76480072ed7b9817e8dd485e0c0ccbd0653fadb28f11b06ce88db0f186086159566c8e4e781363bdab9d327309ea712fd97a9d55f0ca8ad0e95e1a36b36b0fca51ef8ba2c462ed0096f33449eb0fd13b92a1a963dbaaed3dcff10942cdf9b321a2ebf2c8f4e42f48d14b10f4c2efecf84ab53874c3a4a6620ebffd633741e386981aeb4cba56036687ed004559c18544b6c368f941a9eaf987e09f12d0d51454485d444051e338069a4c3c0def6489f8a361eee3c51c9368c8e597d70998ff97a84ceaa479abcd2cc89f1bf2f1cee282503882ad8e9bb8b488818eb636d9a96548743cc9dbfcbbd82a229eb424e2b267abaa13e22a4dfc711c076291bdf8e2975d0c84fd6745671b099a4b20a2773095da28b1863f9ef2e1db10df90f86d912f0678b3485bdff6dbd87ca7aea589404c027320f09fdd637995b103c47e6f2fe022f6d488e9666e9d3519bd411b4f1acfd578b00049f01f8f8df614bcb5946dc45376a7a75391cf8db6166c397e362f06f2231e8e0fc886f476618ef66436fc8c27a1fa12cbfece583f8167886c7dc081e7f8c08e540ec9d9519d219035690a0baca171444b9f45fe9d981f1e1b776c5df1fb7e2c64fe6b571968cddde4d009361a609962d707e64d0986f78e9b2f42d983cba5caad2262757f5b40ef1aafec48756b22b5c405004d2a097d8b8d6ebb5cd4a6b2a10d24acaf16f37f6ebafd0d0791d263f1bb83de41481b7431e2f33f19a750f24e5bae206093d50c7ea5527798ecd52c0d52e75cae0484effbaecdb45cbac8ce982bd0a3a2e6256eb9cc066ab27f56578b4caa09214f4ac3904ba9d00736cf54119e27e39f503f58c294d47188a7814ed78f1e5d21ddc2016d5a1fd194b659885e377d176e8e1655107ccf70eae75029a542e03028a01e3dd559b168737022d33d2a634613aedb1e350598a1dd56f0e3dc62b1cc259122db36fc998c813776d677f3acf44c16a684ffda1082fc1f4f73e87cf5a96829b37fa47b1f2ca010aba85d82adf74eb7130c4d4ef53fa3938892ef424cfc95bfd276c2928f86903b7b845f7b57c9b95af823b3263d411ede092bbddc53138b199ba2f7f58c317390c5a1d3b943706c768efe8fd306f59d84d075dafdc074f24bb42a776fd4be4a472606f04d2c901cde7e083828801606663bfc74e59c926f26ad0e2505451f421ffeba7ef6133be520acebb0b22a31301a6cc0a6a2a5f241299e4819e225c4713a79ddbe1fcf634355761336bf3a3a70026000a7114e675d36640ff0df89c016c657d4701296c94f9bbaacc7572385e1a056f9511a2b18cfd6a773ee01defd63ea25c7ea5473c72a71b3f6a52b7a9819254d77951405cf9d42f6544e4c77ec3648cc47ac94810d108850f7a2d8c1ca827bd7c42d092627fbe6065ee7c61ad70aa64029c0e4211a91b19f4d007edaaae26da8f51308daec116b3396c89a7750e3426221cb8039e5f2f22820431816cf20c5c1650b93711c520b41981eba8507ce90fbdc9b9603c8cfbf4c0d8faa40a096cd43a7b3a48ab29a0a5e812d87b6990b0500e2732bbe8992d1dfe590a30f47d6966ae6558db19630ff3825f357f7bdcae02ec36a4df3ea5f14751d3fabda08062b5934e38fdb9dfbc5181663f17475debd527d867ffaf8a976f9cf383a7fb98ec2e70d4eb288de12a3b47907691cccae0f646d4c57aed99d835f109a33e23703aaa9bc92e9e11dfc6481b926ecd2e10d69f66bfe022fa623138786e4ff702ce1c6111b92815068efd923946d8b57cc99f339129a7cf872394360f16c5489a4d8ee7f9e1911b48b7275ab0076fed358991439a34cea606aff7ed88eab3fc54d0cb5c766083e6b39af5b11e34a100b2750cbc031dcb3047fc2310b0992a47e89d7a09870fed21b8c027d8c948034364907fb973d369c89ddef5590d2e5c907cb41e2f9e36bc43479180c119c397379192347bb3008406509d7e0ce8c874187ee9a6fedd150faceb93ebf7f2dcfc6f15acff65a930def663ab3a6856c54bf61aa380cfc9e97a9aea84d23a732b694759bdf8c602e6d28e9186e27e61d3538996b86de70972e75ce6add5e87f184f6e0f4dfd678a43378b3e62b45c51ebaebaf434ed79e3ac25ef4bb3685e2a0ddf30e311d396e70c7b7ab84a9c4941090badbdc3517a1e0390e7984d4d561536af2729d151b0995cc45a1b60cf02ce3dd789cb620558b83c1c78b8cefd33e2cc21962a3527950a2cefea375b4c86462839d153b551416a17dd0d523f6a29ea4a659fd8b7a9a8e0c8c54580e4765e0fc0512ae82d35b741692f692fd876b6f54aa6fda98f21f1643bb17123127687a44c392e4ea9a5eeb369f38b503db0bcf8ad22560011f91493c881a5f05059819fffe564c0a1c7a873a4994f81745e4bd9279a5ec0a01cffd871f0a0fd161dbb03a02953da066a21f82d83d3a7acfd9f37943aab6e27babe872f474a9953c259a38a29894ba1f46aef1888db89ca84c8ca08bf69c9c6a4450fc821a948056e97da613fb9d38a56dd42e744253f07600406f5362ba041389c5e3b5512d06d72037e0fbdc049441d11b44b495335760aab1ee556efbc876b25439226151d24dcd74bc89a065a4954889938415b7a2e406710f653b9abc5338fb94b16bcda96a7cc8890114dfd603ffa5ea071abb8d720c36f20564b6e4be4315f3528594e9051b46c559a4c13c027c36d95efffe96e11caa567a14e4166f3d902bcd7157005d0eed2efd793e7e008d6c4dac4058ebce9d350a7f6f07f7ecbec4b4c75da6ebae3c229d032ea8a68bce62dd9e045d9e16c8270a1c2c3b481c98f7616edd8872a172095fa012c96b2c8d56f00f6adf517c1b5d89e5f9255ea75b698a5659de7c4b375860d2a3409899661c6b506a9e3fd001c81b62298acf065f2b0080e5cba7cddfc6e6cb44f9c9610cd3588bfc6fd1a91bc9b20dad644703bcb6fc738cbec1d7602227b6da3dac9532f452e490dd6224aca11de17d69b8d16aa323d9cc8cabb41d935f2174dfa063c47b7893d65548ca72d73c1cf543e6d22aac8cf71c7aa8ba9a6bce4aa39085f508d6e6a537a1a61d58af074d', +); +final secret = cases.sublist(7, 7 + 136 + 11); + +String sum([Iterable? data]) { + return xxh3.convert(data?.toList() ?? []).hex(); +} + +String seedSum(int seed, [Iterable? data]) { + return XXH3(seed: seed).convert(data?.toList() ?? []).hex(); +} + +String secretSum([Iterable? data]) { + return XXH3(secret: secret).convert(data?.toList() ?? []).hex(); +} + +void main() { + group('XXH3 test', () { + test("xxh3code", () { + var input = String.fromCharCodes(cases.take(12)); + final expected = 0xa713daf0dfbb77e7; + expect(xxh3code(input), expected); + }); + + test("xxh3sum", () { + var input = String.fromCharCodes(cases.take(12)); + final expected = 'a713daf0dfbb77e7'; + expect(xxh3sum(input), expected); + }); + + test('The secret length must be at least 136', () { + for (int i = 0; i < 136; ++i) { + expect(() => XXH3().withSecret(Uint8List(i)).convert([2]), + throwsArgumentError); + } + }); + + test("withSeed overrides the seed", () { + var instance = XXH3(seed: 0).withSeed(seed); + expect(instance.convert([]).hex(), "a8a6b918b2f0364a"); + }); + + test("with input length = 0", () { + expect(sum(), "2d06800538d394c2"); + }); + test("with input length = 0 and a seed", () { + expect(seedSum(seed), "a8a6b918b2f0364a"); + }); + test("with input length = 1", () { + expect(sum(cases.take(1)), "c44bdff4074eecdb"); + }); + test("with input length = 1 and a seed", () { + expect(seedSum(seed, cases.take(1)), "032be332dd766ef8"); + }); + test("with input length = 6", () { + expect(sum(cases.take(6)), "27b56a84cd2d7325"); + }); + test("with input length = 6 and a seed", () { + expect(seedSum(seed, cases.take(6)), "84589c116ab59ab9"); + }); + test("with input length = 12", () { + expect(sum(cases.take(12)), "a713daf0dfbb77e7"); + }); + test("with input length = 12 and a seed", () { + expect(seedSum(seed, cases.take(12)), "e7303e1b2336de0e"); + }); + test("with input length = 24", () { + expect(sum(cases.take(24)), "a3fe70bf9d3510eb"); + }); + test("with input length = 24 and a seed", () { + expect(seedSum(seed, cases.take(24)), "850e80fc35bdd690"); + }); + test("with input length = 48", () { + expect(sum(cases.take(48)), "397da259ecba1f11"); + }); + test("with input length = 48 and a seed", () { + expect(seedSum(seed, cases.take(48)), "adc2cbaa44acc616"); + }); + test("with input length = 80", () { + expect(sum(cases.take(80)), "bcdefbbb2c47c90a"); + }); + test("with input length = 80 and a seed", () { + expect(seedSum(seed, cases.take(80)), "c6dd0cb699532e73"); + }); + test("with input length = 195", () { + expect(sum(cases.take(195)), "cd94217ee362ec3a"); + }); + test("with input length = 195 and a seed", () { + expect(seedSum(seed, cases.take(195)), "ba68003d370cb3d9"); + }); + test("with input length = 403", () { + expect(sum(cases.take(403)), "cdeb804d65c6dea4"); + }); + test("with input length = 403 and a seed", () { + expect(seedSum(seed, cases.take(403)), "6259f6ecfd6443fd"); + }); + test("with input length = 512", () { + expect(sum(cases.take(512)), "617e49599013cb6b"); + }); + test("with input length = 512 and a seed", () { + expect(seedSum(seed, cases.take(512)), "3ce457de14c27708"); + }); + test("with input length = 2048", () { + expect(sum(cases.take(2048)), "dd59e2c3a5f038e0"); + }); + test("with input length = 2048 and a seed", () { + expect(seedSum(seed, cases.take(2048)), "66f81670669ababc"); + }); + test("with input length = 2240", () { + expect(sum(cases.take(2240)), "6e73a90539cf2948"); + }); + test("with input length = 2240 and a seed", () { + expect(seedSum(seed, cases.take(2240)), "757ba8487d1b5247"); + }); + test("with input length = 2243", () { + expect(sum(cases.take(2243)), "fdd97ddf7a83e7a9"); + }); + test("with input length = 2243 and a seed", () { + expect(seedSum(seed, cases.take(2243)), "a2115d49b6729aed"); + }); + + // test("with secret, length = 0", () { + // expect(secretSum(), "6775fd10343c92c3"); + // }); + // test("with secret, length = 1", () { + // expect(secretSum(cases.take(1)), "c3382c326e24e3cd"); + // }); + test("with secret, length = 6", () { + expect(secretSum(cases.take(6)), "82c90ab0519369ad"); + }); + test("with secret, length = 12", () { + expect(secretSum(cases.take(12)), "14631e773b78ec57"); + }); + test("with secret, length = 24", () { + expect(secretSum(cases.take(24)), "cdd5542e4a9d9fe8"); + }); + test("with secret, length = 48", () { + expect(secretSum(cases.take(48)), "33abd54d094b2534"); + }); + test("with secret, length = 80", () { + expect(secretSum(cases.take(80)), "e687ba1684965297"); + }); + test("with secret, length = 195", () { + expect(secretSum(cases.take(195)), "a057273f5eecfb20"); + }); + // test("with secret, length = 403", () { + // expect(secretSum(cases.take(403)), "f9c0ba5ba3af70b8"); + // }); + // test("with secret, length = 512", () { + // expect(secretSum(cases.take(512)), "7896e65dcfa09071"); + // }); + // test("with secret, length = 2048", () { + // expect(secretSum(cases.take(2048)), "d6545db87ecfd98c"); + // }); + // test("with secret, length = 2243", () { + // expect(secretSum(cases.take(2243)), "887810081c32460a"); + // }); + }); +} diff --git a/hashlib/test/xxh64_test.dart b/hashlib/test/xxh64_test.dart new file mode 100644 index 0000000..794bf97 --- /dev/null +++ b/hashlib/test/xxh64_test.dart @@ -0,0 +1,76 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore: library_annotations +@Tags(['vm-only']) + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +const seed = 0x9E3779B1; +const data = [ + 158, 255, 31, 75, 94, 83, 47, 221, 181, 84, 77, 42, 149, 43, 87, 174, 93, // + 186, 116, 233, 211, 166, 76, 152, 48, 96, 192, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +]; + +void main() { + group('XXHash64 test', () { + test('xxh64sum', () { + final input = String.fromCharCodes(data); + expect(xxh64sum(input), "0eab543384f878ad"); + }); + test('xxh64code', () { + final input = String.fromCharCodes(data); + final output = 0x0eab543384f878ad; + expect(xxh64code(input), output); + }); + + test('with seed = 0 and an empty string', () { + expect(xxh64.convert([]).hex(), "ef46db3751d8e999"); + }); + test('with seed = 0 and a single letter', () { + expect(xxh64.convert([data[0]]).hex(), "4fce394cc88952d8"); + }); + test('with seed = 0 and 14 letters', () { + expect(xxh64.convert(data.take(14).toList()).hex(), "cffa8db881bc3a3d"); + }); + test('with seed = 0 and 101 letters', () { + expect(xxh64.convert(data).hex(), "0eab543384f878ad"); + }); + + test('with a seed and an empty string', () { + final input = []; + expect(xxh64.withSeed(seed).convert(input).hex(), "ac75fda2929b17ef"); + }); + + test('with a seed and a single letter', () { + final input = [data[0]]; + expect(xxh64.withSeed(seed).hex(input), "739840cb819fa723"); + }); + + test('with a seed and 14 letters', () { + final input = data.take(14).toList(); + expect(xxh64.withSeed(seed).convert(input).hex(), "5b9611585efcc9cb"); + }); + + test('with a seed and 101 letters', () { + expect(xxh64.withSeed(seed).convert(data).hex(), "caa65939306f1e21"); + }); + + test('with 32-byte message', () { + final input = "string of 32-bytes long for test"; + final output = "eb3f9d9890ca89b3"; + expect(xxh64sum(input), output); + }); + + test('with 64-byte message', () { + final input = "string of 64-bytes for test. " + "twice the size of 32-byte string."; + final output = "0f6ebfbce5c11a1b"; + expect(xxh64sum(input), output); + }); + }); +} diff --git a/hashlib/test/xxh_test.dart b/hashlib/test/xxh_test.dart new file mode 100644 index 0000000..53e8fe4 --- /dev/null +++ b/hashlib/test/xxh_test.dart @@ -0,0 +1,71 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +// ignore: library_annotations +@Tags(['vm-only']) + +import 'dart:io'; + +import 'package:hashlib/hashlib.dart'; +import 'package:test/test.dart'; + +List readLines(String filename) { + final file = File(Directory('test/fixures/$filename').absolute.path); + final text = file.readAsStringSync(); + return text.split(RegExp(r'(\r)?\n')); +} + +void main() { + group('XXH test with fixures', () { + const int maxLength = 1500; + final text = readLines('long.txt').join('\n').codeUnits; + + test('for xxh32', () { + var actual = readLines('xxh32.csv'); + for (var line in actual) { + var parts = line.split(','); + if (parts.length != 2) continue; + int len = int.parse(parts[0]); + if (len > maxLength) break; + var out = xxh32.hex(text.take(len).toList()); + expect(out, equals(parts[1]), reason: 'length: $len'); + } + }); + + test('for xxh64', () { + var actual = readLines('xxh64.csv'); + for (var line in actual) { + var parts = line.split(','); + if (parts.length != 2) continue; + int len = int.parse(parts[0]); + if (len > maxLength) break; + var out = xxh64.hex(text.take(len).toList()); + expect(out, equals(parts[1]), reason: 'length: $len'); + } + }); + + test('for xxh3-64', () { + var actual = readLines('xxh3_64.csv'); + for (var line in actual) { + var parts = line.split(','); + if (parts.length != 2) continue; + int len = int.parse(parts[0]); + if (len > maxLength) break; + var out = xxh3.hex(text.take(len).toList()); + expect(out, equals(parts[1]), reason: 'length: $len'); + } + }); + + test('for xxh3-128', () { + var actual = readLines('xxh3_128.csv'); + for (var line in actual) { + var parts = line.split(','); + if (parts.length != 2) continue; + int len = int.parse(parts[0]); + if (len > maxLength) break; + var out = xxh128.hex(text.take(len).toList()); + expect(out, equals(parts[1]), reason: 'length: $len'); + } + }); + }); +} diff --git a/hashlib_codecs/LICENSE b/hashlib_codecs/LICENSE new file mode 100644 index 0000000..f8437f8 --- /dev/null +++ b/hashlib_codecs/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2023, Sudipto Chandra +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/hashlib_codecs/lib/hashlib_codecs.dart b/hashlib_codecs/lib/hashlib_codecs.dart new file mode 100644 index 0000000..f835ad6 --- /dev/null +++ b/hashlib_codecs/lib/hashlib_codecs.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +/// Implementations of fast and error resilient codecs in pure Dart. +library; + +export 'src/codecs_base.dart'; diff --git a/hashlib_codecs/lib/src/base16.dart b/hashlib_codecs/lib/src/base16.dart new file mode 100644 index 0000000..8b5e013 --- /dev/null +++ b/hashlib_codecs/lib/src/base16.dart @@ -0,0 +1,53 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/base16.dart'; + +Base16Codec _codecFromParameters({ + bool upper = false, +}) { + if (upper) { + return Base16Codec.upper; + } else { + return Base16Codec.lower; + } +} + +/// Converts 8-bit integer sequence to 4-bit Base-16 character sequence. +/// +/// Parameters: +/// - [input] is a sequence of 8-bit integers. +/// - If [upper] is true, the uppercase standard alphabet is used. +/// - [codec] is the [Base16Codec] to use. It is derived from the other +/// parameters if not provided. +String toHex( + List input, { + Base16Codec? codec, + bool upper = false, +}) { + codec ??= _codecFromParameters(upper: upper); + var out = codec.encoder.convert(input); + return String.fromCharCodes(out); +} + +/// Converts 4-bit Base-16 character sequence to 8-bit integer sequence. +/// +/// Parameters: +/// - [input] should be a valid Base-16 (hexadecimal) string. +/// - [codec] is the [Base16Codec] to use. It is derived from the other +/// parameters if not provided. +/// +/// Throws: +/// - [FormatException] if the [input] contains invalid characters. +/// +/// This implementation can handle both uppercase and lowercase alphabets. If a +/// partial string is detected, the following bits are assumed to be zeros. +Uint8List fromHex( + String input, { + Base16Codec? codec, +}) { + codec ??= _codecFromParameters(); + return codec.decoder.convert(input.codeUnits); +} diff --git a/hashlib_codecs/lib/src/base2.dart b/hashlib_codecs/lib/src/base2.dart new file mode 100644 index 0000000..ef5c5f5 --- /dev/null +++ b/hashlib_codecs/lib/src/base2.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/base2.dart'; + +/// Converts 8-bit integer sequence to 2-bit Base-2 character sequence. +/// +/// Parameters: +/// - [input] is a sequence of 8-bit integers. +/// - [codec] is the [Base2Codec] to use. Default: [Base2Codec.standard]. +/// +/// **NOTE:**, This implementation is a bit-wise encoding of the input bytes. +/// To get the numeric representation of the [input] in binary: +/// ```dart +/// toBigInt(input).toRadixString(2) +/// ``` +String toBinary( + List input, { + Base2Codec codec = Base2Codec.standard, +}) { + var out = codec.encoder.convert(input); + return String.fromCharCodes(out); +} + +/// Converts 2-bit Base-2 character sequence to 8-bit integer sequence. +/// +/// Parameters: +/// - [input] should be a valid binary/base-2 encoded string. +/// - [codec] is the [Base2Codec] to use. Default: [Base2Codec.standard]. +/// +/// Throws: +/// - [FormatException] if the [input] contains invalid characters. +/// +/// If a partial string is detected, the following bits are assumed to be zeros. +/// +/// **NOTE:**, This implementation is a bit-wise decoding of the input bytes. +/// To get the bytes from the numeric representation of the [input]: +/// ```dart +/// fromBigInt(BigInt.parse(input, radix: 2)); +/// ``` +Uint8List fromBinary( + String input, { + Base2Codec codec = Base2Codec.standard, +}) { + return codec.decoder.convert(input.codeUnits); +} diff --git a/hashlib_codecs/lib/src/base32.dart b/hashlib_codecs/lib/src/base32.dart new file mode 100644 index 0000000..1d4a9dd --- /dev/null +++ b/hashlib_codecs/lib/src/base32.dart @@ -0,0 +1,80 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/base32.dart'; + +Base32Codec _codecFromParameters({ + bool lower = false, + bool padding = false, +}) { + if (lower && padding) { + return Base32Codec.lowercase; + } else if (lower) { + return Base32Codec.lowercaseNoPadding; + } else if (padding) { + return Base32Codec.standard; + } else { + return Base32Codec.standardNoPadding; + } +} + +const _codecsWithPadding = { + Base32Codec.standard, + Base32Codec.lowercase, + Base32Codec.hex, + Base32Codec.hexLower, + Base32Codec.geohash, + Base32Codec.wordSafe, +}; + +/// Converts 8-bit integer sequence to 5-bit Base-32 character sequence. +/// +/// Parameters: +/// - [input] is a sequence of 8-bit integers +/// - If [lower] is true, the [Base32Codec.lowercase] alphabet is used. +/// - If [padding] is true, the output will not have padding characters. +/// - [codec] is the [Base32Codec] to use. It is derived from the other +/// parameters if not provided. +String toBase32( + List input, { + Base32Codec? codec, + bool lower = false, + bool padding = true, +}) { + codec ??= _codecFromParameters( + lower: lower, + padding: padding, + ); + Iterable out = codec.encoder.convert(input); + if (!padding && _codecsWithPadding.contains(codec)) { + out = out.takeWhile((x) => x != codec!.encoder.padding); + } + return String.fromCharCodes(out); +} + +/// Converts 5-bit Base-32 character sequence to 8-bit integer sequence. +/// +/// Parameters: +/// - [input] should be a valid base-32 encoded string. +/// - If [padding] is true, the output will not have padding characters. +/// - [codec] is the [Base32Codec] to use. It is derived from the other +/// parameters if not provided. +/// +/// Throws: +/// - [FormatException] if the [input] contains invalid characters, and the +/// length is not valid for a base-32 encoded string. +/// +/// This implementation can handle both uppercase and lowercase alphabets. Any +/// letters appearing after the first padding character is observed are ignored. +/// If a partial string is detected, the following bits are assumed to be zeros. +Uint8List fromBase32( + String input, { + Base32Codec? codec, + bool padding = true, +}) { + codec ??= _codecFromParameters(padding: padding); + var out = codec.decoder.convert(input.codeUnits); + return Uint8List.fromList(out); +} diff --git a/hashlib_codecs/lib/src/base64.dart b/hashlib_codecs/lib/src/base64.dart new file mode 100644 index 0000000..e4ff33c --- /dev/null +++ b/hashlib_codecs/lib/src/base64.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/base64.dart'; + +Base64Codec _codecFromParameters({ + bool url = false, + bool padding = false, +}) { + if (url && padding) { + return Base64Codec.urlSafe; + } else if (url) { + return Base64Codec.urlSafeNoPadding; + } else if (padding) { + return Base64Codec.standard; + } else { + return Base64Codec.standardNoPadding; + } +} + +const _codecsWithPadding = { + Base64Codec.standard, + Base64Codec.urlSafe, +}; + +/// Converts 8-bit integer sequence to 6-bit Base-64 character sequence. +/// +/// Parameters: +/// - [input] is a sequence of 8-bit integers +/// - If [url] is true, URL and Filename-safe alphabet is used. +/// - If [padding] is true, the output will have padding characters. +/// - [codec] is the [Base64Codec] to use. It is derived from the other +/// parameters if not provided. +String toBase64( + List input, { + Base64Codec? codec, + bool url = false, + bool padding = true, +}) { + codec ??= _codecFromParameters( + url: url, + padding: padding, + ); + Iterable out = codec.encoder.convert(input); + if (!padding && _codecsWithPadding.contains(codec)) { + out = out.takeWhile((x) => x != codec!.encoder.padding); + } + return String.fromCharCodes(out); +} + +/// Converts 6-bit Base-64 character sequence to 8-bit integer sequence. +/// +/// Parameters: +/// - [input] should be a valid base-64 encoded string. +/// - If [padding] is true, the output will have padding characters. +/// - [codec] is the [Base64Codec] to use. It is derived from the other +/// parameters if not provided. +/// +/// Throws: +/// - [FormatException] if the [input] contains invalid characters, and the +/// length is not valid for a base-64 encoded string. +/// +/// This implementation can handle both the original and URL/filename-safe +/// alphabets. Any letters appearing after the first padding character is +/// observed are ignored. If a partial string is detected, the following bits +/// are assumed to be zeros. +Uint8List fromBase64( + String input, { + Base64Codec? codec, + bool padding = true, +}) { + codec ??= _codecFromParameters(padding: padding); + var out = codec.decoder.convert(input.codeUnits); + return Uint8List.fromList(out); +} diff --git a/hashlib_codecs/lib/src/base8.dart b/hashlib_codecs/lib/src/base8.dart new file mode 100644 index 0000000..3912924 --- /dev/null +++ b/hashlib_codecs/lib/src/base8.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/base8.dart'; + +/// Converts 8-bit integer sequence to 3-bit Base-8 character sequence. +/// +/// Parameters: +/// - [input] is a sequence of 8-bit integers. +/// - [codec] is the [Base8Codec] to use. Default: [Base8Codec.standard]. +/// +/// **NOTE:**, This implementation is a bit-wise encoding of the input bytes. +/// To get the numeric representation of the [input] in binary: +/// ```dart +/// toBigInt(input).toRadixString(8) +/// ``` +String toOctal( + List input, { + Base8Codec codec = Base8Codec.standard, +}) { + var out = codec.encoder.convert(input); + return String.fromCharCodes(out); +} + +/// Converts 3-bit Base-8 character sequence to 8-bit integer sequence. +/// +/// Parameters: +/// - [input] should be a valid octal/base-8 encoded string. +/// - [codec] is the [Base8Codec] to use. Default: [Base8Codec.standard]. +/// +/// Throws: +/// - [FormatException] if the [input] contains invalid characters. +/// +/// If a partial string is detected, the following bits are assumed to be zeros. +/// +/// **NOTE:**, This implementation is a bit-wise decoding of the input bytes. +/// To get the bytes from the numeric representation of the [input]: +/// ```dart +/// fromBigInt(BigInt.parse(input, radix: 8)); +/// ``` +Uint8List fromOctal( + String input, { + Base8Codec codec = Base8Codec.standard, +}) { + return codec.decoder.convert(input.codeUnits); +} diff --git a/hashlib_codecs/lib/src/bigint.dart b/hashlib_codecs/lib/src/bigint.dart new file mode 100644 index 0000000..4f0e453 --- /dev/null +++ b/hashlib_codecs/lib/src/bigint.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/bigint.dart'; + +BigIntCodec _codecFromParameters({ + bool msbFirst = false, +}) { + if (msbFirst) { + return BigIntCodec.msbFirst; + } else { + return BigIntCodec.lsbFirst; + } +} + +/// Converts 8-bit integer sequence to [BigInt]. +/// +/// Parameters: +/// - [input] is a sequence of 8-bit integers. +/// - If [msbFirst] is true, [input] bytes are read in big-endian order giving +/// the first byte the most significant value, otherwise the bytes are read as +/// little-endian order, giving the first byte the least significant value. +/// - [codec] is the [BigIntCodec] to use. It is derived from the other +/// parameters if not provided. +/// +/// Throws: +/// - [FormatException] when the [input] is empty. +BigInt toBigInt( + Iterable input, { + BigIntCodec? codec, + bool msbFirst = false, +}) { + codec ??= _codecFromParameters(msbFirst: msbFirst); + return codec.encoder.convert(input); +} + +/// Converts a [BigInt] to 8-bit integer sequence. +/// +/// Parameters: +/// - [input] is a non-negative [BigInt]. +/// - If [msbFirst] is true, [input] bytes are read in big-endian order giving +/// the first byte the most significant value, otherwise the bytes are read as +/// little-endian order, giving the first byte the least significant value. +/// - [codec] is the [BigIntCodec] to use. It is derived from the other +/// parameters if not provided. +/// +/// Raises: +/// - [FormatException] when the [input] is negative. +Uint8List fromBigInt( + BigInt input, { + BigIntCodec? codec, + bool msbFirst = false, +}) { + codec ??= _codecFromParameters(msbFirst: msbFirst); + var out = codec.decoder.convert(input); + return Uint8List.fromList(out as List); +} diff --git a/hashlib_codecs/lib/src/codecs/base16.dart b/hashlib_codecs/lib/src/codecs/base16.dart new file mode 100644 index 0000000..fc77b08 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/base16.dart @@ -0,0 +1,119 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib_codecs/src/core/byte.dart'; +import 'package:hashlib_codecs/src/core/codec.dart'; + +const int _zero = 0x30; +const int _bigA = 0x41; +const int _smallA = 0x61; + +extension on List { + @pragma('vm:prefer-inline') + int dec(int p) { + int x = this[p] & 0xFF; + if (x >= _smallA) { + x -= _smallA - 10; + } else if (x >= _bigA) { + x -= _bigA - 10; + } else { + x -= _zero; + } + if (x < 0 || x > 15) { + throw FormatException('Invalid character at $p'); + } + return x; + } +} + +// ======================================================== +// Base-16 Encoder and Decoder +// ======================================================== + +class _Base16Encoder extends ByteEncoder { + final int startCode; + + const _Base16Encoder._(this.startCode) : super(bits: 4); + + static const upper = _Base16Encoder._(_bigA - 10); + static const lower = _Base16Encoder._(_smallA - 10); + + @override + Uint8List convert(List input) { + int i, p, x, a, b; + var out = Uint8List(input.length << 1); + for (i = p = 0; p < input.length; p++, i += 2) { + x = input[p]; + a = (x >>> 4) & 0xF; + b = x & 0xF; + a += a < 10 ? _zero : startCode; + b += b < 10 ? _zero : startCode; + out[i] = a; + out[i + 1] = b; + } + return out; + } +} + +class _Base16Decoder extends ByteDecoder { + const _Base16Decoder() : super(bits: 4); + + @override + Uint8List convert(List encoded) { + int p, n; + + n = encoded.length; + p = (n >>> 1) + (n & 1); + var out = Uint8List(p); + + for (p--; n >= 2; n -= 2, p--) { + out[p] = encoded.dec(n - 1) ^ // + (encoded.dec(n - 2) << 4); + } + + if (n == 1) { + out[p] = encoded.dec(0); + } + + return out; + } +} + +// ======================================================== +// Base-16 Codec +// ======================================================== + +class Base16Codec extends IterableCodec { + @override + final ByteEncoder encoder; + + @override + final ByteDecoder decoder; + + const Base16Codec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode 8-bit integer sequence to 4-bit + /// Base-16 or Hexadecimal character sequence using the alphabet: + /// ``` + /// 0123456789ABCDEF + /// ``` + static const Base16Codec upper = Base16Codec._( + encoder: _Base16Encoder.upper, + decoder: _Base16Decoder(), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 4-bit + /// Base-16 or Hexadecimal character sequence using the alphabet: + /// ``` + /// 0123456789abcdef + /// ``` + static const Base16Codec lower = Base16Codec._( + encoder: _Base16Encoder.lower, + decoder: _Base16Decoder(), + ); +} diff --git a/hashlib_codecs/lib/src/codecs/base2.dart b/hashlib_codecs/lib/src/codecs/base2.dart new file mode 100644 index 0000000..9934fd7 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/base2.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib_codecs/src/core/byte.dart'; +import 'package:hashlib_codecs/src/core/codec.dart'; + +const int _zero = 0x30; + +extension on List { + @pragma('vm:prefer-inline') + int dec(int p) { + int x = this[p] - _zero; + if (x != 0 && x != 1) { + throw FormatException('Invalid character at $p'); + } + return x; + } +} + +// ======================================================== +// Base-2 Encoder & Decoder +// ======================================================== + +class _Base2Encoder extends ByteEncoder { + const _Base2Encoder() : super(bits: 2); + + @override + Uint8List convert(List input) { + int i, p, x, n; + n = input.length; + var out = Uint8List(n << 3); + + for (i = p = 0; i < n; i++, p += 8) { + x = input[i]; + out[p] = _zero + ((x >>> 7) & 1); + out[p + 1] = _zero + ((x >>> 6) & 1); + out[p + 2] = _zero + ((x >>> 5) & 1); + out[p + 3] = _zero + ((x >>> 4) & 1); + out[p + 4] = _zero + ((x >>> 3) & 1); + out[p + 5] = _zero + ((x >>> 2) & 1); + out[p + 6] = _zero + ((x >>> 1) & 1); + out[p + 7] = _zero + ((x) & 1); + } + + return out; + } +} + +class _Base2Decoder extends ByteDecoder { + const _Base2Decoder() : super(bits: 2); + + @override + Uint8List convert(List encoded) { + int i, p, n, x; + + n = encoded.length; + p = (n + ((8 - (n & 7)) & 7)) >>> 3; + var out = Uint8List(p); + + for (p--; n >= 8; n -= 8, p--) { + out[p] = encoded.dec(n - 1) ^ + (encoded.dec(n - 2) << 1) ^ + (encoded.dec(n - 3) << 2) ^ + (encoded.dec(n - 4) << 3) ^ + (encoded.dec(n - 5) << 4) ^ + (encoded.dec(n - 6) << 5) ^ + (encoded.dec(n - 7) << 6) ^ + (encoded.dec(n - 8) << 7); + } + + if (n > 0) { + x = 0; + for (i = n; i > 0; i--) { + x = (x << 1) ^ encoded.dec(n - i); + } + out[p] = x; + } + + return out; + } +} + +// ======================================================== +// Base-2 Codec +// ======================================================== + +class Base2Codec extends IterableCodec { + @override + final ByteEncoder encoder; + + @override + final ByteDecoder decoder; + + const Base2Codec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode 8-bit integer sequence to 2-bit + /// Base-2 or Binary character sequence using the alphabet: + /// ``` + /// 01 + /// ``` + static const Base2Codec standard = Base2Codec._( + encoder: _Base2Encoder(), + decoder: _Base2Decoder(), + ); +} diff --git a/hashlib_codecs/lib/src/codecs/base32.dart b/hashlib_codecs/lib/src/codecs/base32.dart new file mode 100644 index 0000000..7ba4914 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/base32.dart @@ -0,0 +1,383 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib_codecs/src/core/alphabet.dart'; +import 'package:hashlib_codecs/src/core/codec.dart'; + +// ======================================================== +// Base-32 Alphabets +// ======================================================== + +const int _padding = 0x3d; + +// ignore: constant_identifier_names +const int __ = -1; + +// RFC-4648 +const _base32EncodingRfc4648 = [ + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +]; + +// RFC-4648 Lowercase +const _base32EncodingRfc4648Lower = [ + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, // + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +]; + +// RFC-4648 and Lowercase Reversed +const _base32DecodingRfc4648 = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, 26, 27, 28, 29, 30, 31, __, + __, __, __, __, __, __, __, __, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, __, __, __, __, + __, __, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, __, __, __, __, __, __, __, __, __, __, +]; + +// Base32Hex Uppercase +const _base32EncodingHexUpper = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, +]; + +// Base32Hex Lowercase +const _base32EncodingHexLower = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, +]; + +// Base32Hex Uppercase + Lowercase Reversed +const _base32DecodingHex = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, 00, 01, 02, 03, 04, 05, 06, 07, 08, + 09, __, __, __, __, __, __, __, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, __, __, __, __, __, __, __, __, + __, __, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, __, __, __, __, __, __, __, __, __, __, __, __, __, __, +]; + +// Crockford's Base32 +const _base32EncodingCrockford = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a, +]; + +// Crockford's Base32 Reversed +const _base32DecodingCrockford = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, 00, 01, 02, 03, 04, 05, 06, 07, 08, + 09, __, __, __, __, __, __, __, 10, 11, 12, 13, 14, 15, 16, 17, __, 18, 19, + __, 20, 21, __, 22, 23, 24, 25, 26, __, 27, 28, 29, 30, 31, __, __, __, __, +]; + +// GeoHash's Base32 +const _base32EncodingGeoHash = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // + 0x38, 0x39, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x6a, 0x6b, 0x6d, 0x6e, 0x70, 0x71, 0x72, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, +]; + +// GeoHash's Base32 Reversed +const _base32DecodingGeoHash = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, 00, 01, 02, 03, 04, 05, 06, 07, 08, + 09, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, 10, 11, 12, 13, 14, 15, 16, __, 17, 18, __, 19, 20, __, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, __, __, __, __, __, __, __, __, __, __, +]; + +// Z Base32 +const _base32EncodingZ = [ + 0x79, 0x62, 0x6e, 0x64, 0x72, 0x66, 0x67, 0x38, // + 0x65, 0x6a, 0x6b, 0x6d, 0x63, 0x70, 0x71, 0x78, + 0x6f, 0x74, 0x31, 0x75, 0x77, 0x69, 0x73, 0x7a, + 0x61, 0x33, 0x34, 0x35, 0x68, 0x37, 0x36, 0x39, +]; + +// Z Base32 Reversed +const _base32DecodingZ = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, 18, __, 25, 26, 27, 30, 29, 07, + 31, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, 24, 01, 12, 03, 08, 05, 06, 28, 21, 09, 10, __, 11, 02, 16, 13, 14, + 04, 22, 17, 19, __, 20, 15, 00, 23, __, __, __, __, __, __, __, __, __, __, +]; + +// WordSafe Base32 +const _base32EncodingWordSafe = [ + 0x79, 0x62, 0x6e, 0x64, 0x72, 0x66, 0x67, 0x38, // + 0x65, 0x6a, 0x6b, 0x6d, 0x63, 0x70, 0x71, 0x78, + 0x6f, 0x74, 0x31, 0x75, 0x77, 0x69, 0x73, 0x7a, + 0x61, 0x33, 0x34, 0x35, 0x68, 0x37, 0x36, 0x39, +]; + +// WordSafe Base32 Reversed +const _base32DecodingWordSafe = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, 18, __, 25, 26, 27, 30, 29, 07, + 31, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, 24, 01, 12, 03, 08, 05, 06, 28, 21, 09, 10, __, 11, 02, 16, 13, 14, + 04, 22, 17, 19, __, 20, 15, 00, 23, __, __, __, __, __, __, __, __, __, __, +]; + +// ======================================================== +// Base-32 Codec +// ======================================================== + +class Base32Codec extends IterableCodec { + @override + final AlphabetEncoder encoder; + + @override + final AlphabetDecoder decoder; + + const Base32Codec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet described in + /// [RFC-4648](https://www.ietf.org/rfc/rfc4648.html): + /// ``` + /// ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 + /// ``` + /// + /// It is padded with `=` + static const Base32Codec standard = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + padding: _padding, + alphabet: _base32EncodingRfc4648, + ), + decoder: AlphabetDecoder( + bits: 5, + padding: _padding, + alphabet: _base32DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet described in + /// [RFC-4648](https://www.ietf.org/rfc/rfc4648.html): + /// ``` + /// ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 + /// ``` + /// + /// This algorithm is a variant of the [standard] from the + /// [RFC-4648](https://datatracker.ietf.org/doc/html/rfc4648) + /// that does not append any padding characters to the output. + /// + /// It is not padded. + static const Base32Codec standardNoPadding = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + alphabet: _base32EncodingRfc4648, + ), + decoder: AlphabetDecoder( + bits: 5, + alphabet: _base32DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet: + /// ``` + /// abcdefghijklmnopqrstuvwxyz234567 + /// ``` + /// + /// This alphabet is a variant of the standard alphabet from + /// [RFC-4648](https://datatracker.ietf.org/doc/html/rfc4648) + /// using the lowercase characters. + /// + /// It is padded with `=` + static const Base32Codec lowercase = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + padding: _padding, + alphabet: _base32EncodingRfc4648Lower, + ), + decoder: AlphabetDecoder( + bits: 5, + padding: _padding, + alphabet: _base32DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet: + /// ``` + /// abcdefghijklmnopqrstuvwxyz234567 + /// ``` + /// + /// This algorithm is a variant of the [lowercase] that does + /// not append any padding characters to the output. + /// + /// It is not padded. + static const Base32Codec lowercaseNoPadding = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + alphabet: _base32EncodingRfc4648Lower, + ), + decoder: AlphabetDecoder( + bits: 5, + alphabet: _base32DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet of + /// [base32hex](https://en.wikipedia.org/wiki/Base32#base32hex): + /// : + /// ``` + /// 0123456789ABCDEFGHIJKLMNOPQRSTUV + /// ``` + /// + /// It is padded with `=` + static const Base32Codec hex = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + padding: _padding, + alphabet: _base32EncodingHexUpper, + ), + decoder: AlphabetDecoder( + bits: 5, + padding: _padding, + alphabet: _base32DecodingHex, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet of lowercase + /// [base32hex](https://en.wikipedia.org/wiki/Base32#base32hex): + /// ``` + /// 0123456789abcdefghijklmnopqrstuv + /// ``` + /// + /// It is padded with `=` + static const Base32Codec hexLower = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + padding: _padding, + alphabet: _base32EncodingHexLower, + ), + decoder: AlphabetDecoder( + bits: 5, + padding: _padding, + alphabet: _base32DecodingHex, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet of + /// [Crockford's Base32](https://en.wikipedia.org/wiki/Base32#Crockford's_Base32): + /// ``` + /// 0123456789ABCDEFGHJKMNPQRSTVWXYZ + /// ``` + /// + /// This alphabet uses additional characters for a mod-37 checksum, and avoid + /// the character U to reduce the likelihood of accidental obscenity. + /// + /// It is not padded. + static const Base32Codec crockford = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + alphabet: _base32EncodingCrockford, + ), + decoder: AlphabetDecoder( + bits: 5, + alphabet: _base32DecodingCrockford, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet of + /// [Geohash's Base32](https://en.wikipedia.org/wiki/Base32#Geohash): + /// ``` + /// 0123456789bcdefghjkmnpqrstuvwxyz + /// ``` + /// + /// This is used by the Geohash algorithm to represent latitude and + /// longitude values in one (bit-interlaced) positive integer. + /// + /// It is padded with `=` + static const Base32Codec geohash = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + padding: _padding, + alphabet: _base32EncodingGeoHash, + ), + decoder: AlphabetDecoder( + bits: 5, + padding: _padding, + alphabet: _base32DecodingGeoHash, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the alphabet of + /// [z-base-32](https://en.wikipedia.org/wiki/Base32#z-base-32): + /// ``` + /// ybndrfg8ejkmcpqxot1uwisza345h769 + /// ``` + /// + /// The alphabet designed in a way so that the easier characters occur + /// more frequently, thus making it more human readable. + /// + /// It is not padded. + static const Base32Codec z = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + alphabet: _base32EncodingZ, + ), + decoder: AlphabetDecoder( + bits: 5, + alphabet: _base32DecodingZ, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 5-bit + /// Base-32 character sequence using the + /// [Word-safe alphabet](https://en.wikipedia.org/wiki/Base32#Word-safe_alphabet): + /// ``` + /// 23456789CFGHJMPQRVWXcfghjmpqrvwx + /// ``` + /// + /// That alphabet uses 8 numeric digits and 12 case-sensitive letter digits + /// chosen to avoid accidentally forming words. + /// + /// It is padded with `=` + static const Base32Codec wordSafe = Base32Codec._( + encoder: AlphabetEncoder( + bits: 5, + padding: _padding, + alphabet: _base32EncodingWordSafe, + ), + decoder: AlphabetDecoder( + bits: 5, + padding: _padding, + alphabet: _base32DecodingWordSafe, + ), + ); +} diff --git a/hashlib_codecs/lib/src/codecs/base64.dart b/hashlib_codecs/lib/src/codecs/base64.dart new file mode 100644 index 0000000..5653f04 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/base64.dart @@ -0,0 +1,182 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib_codecs/src/core/alphabet.dart'; +import 'package:hashlib_codecs/src/core/codec.dart'; + +// ======================================================== +// Base-64 Alphabets +// ======================================================== + +const int _padding = 0x3d; + +// ignore: constant_identifier_names +const int __ = -1; + +const _base64EncodingRfc4648 = [ + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f, +]; +const _base64EncodingRfc4648UrlSafe = [ + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2d, 0x5f, +]; +const _base64DecodingRfc4648 = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, 62, __, 62, __, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, __, __, __, __, __, __, __, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, __, __, __, __, + 63, __, 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, __, __, __, __, __, __, __, __, __, __, +]; + +const _base64EncodingBcrypt = [ + 0x2e, 0x2f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, +]; +const _base64DecodingBcrypt = [ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, 00, 01, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, __, __, __, __, __, __, __, 02, 03, 04, 05, 06, 07, 08, 09, 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, __, __, __, __, __, __, __, __, __, __, +]; + +// ======================================================== +// Base-64 Codec +// ======================================================== + +class Base64Codec extends IterableCodec { + @override + final AlphabetEncoder encoder; + + @override + final AlphabetDecoder decoder; + + const Base64Codec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode 8-bit integer sequence to 6-bit + /// Base-64 character sequence using the alphabet described in + /// [RFC-4648](https://www.ietf.org/rfc/rfc4648.html): + /// ``` + /// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ + /// ``` + /// + /// It is padded with `=` + static const Base64Codec standard = Base64Codec._( + encoder: AlphabetEncoder( + bits: 6, + padding: _padding, + alphabet: _base64EncodingRfc4648, + ), + decoder: AlphabetDecoder( + bits: 6, + padding: _padding, + alphabet: _base64DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 6-bit + /// Base-64 character sequence using the alphabet described in + /// [RFC-4648](https://www.ietf.org/rfc/rfc4648.html): + /// ``` + /// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ + /// ``` + /// + /// It is not padded. + static const Base64Codec standardNoPadding = Base64Codec._( + encoder: AlphabetEncoder( + bits: 6, + alphabet: _base64EncodingRfc4648, + ), + decoder: AlphabetDecoder( + bits: 6, + alphabet: _base64DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 6-bit + /// Base-64 character sequence using the alphabet described in + /// [RFC-4648](https://www.ietf.org/rfc/rfc4648.html) considering the + /// URL and filename safety: + /// ``` + /// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_ + /// ``` + /// + /// It is padded with `=` + static const Base64Codec urlSafe = Base64Codec._( + encoder: AlphabetEncoder( + bits: 6, + padding: _padding, + alphabet: _base64EncodingRfc4648UrlSafe, + ), + decoder: AlphabetDecoder( + bits: 6, + padding: _padding, + alphabet: _base64DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 6-bit + /// Base-64 character sequence using the alphabet described in + /// [RFC-4648](https://www.ietf.org/rfc/rfc4648.html) considering the + /// URL and filename safety: + /// ``` + /// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_ + /// ``` + /// + /// It is not padded. + static const Base64Codec urlSafeNoPadding = Base64Codec._( + encoder: AlphabetEncoder( + bits: 6, + alphabet: _base64EncodingRfc4648UrlSafe, + ), + decoder: AlphabetDecoder( + bits: 6, + alphabet: _base64DecodingRfc4648, + ), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to 6-bit + /// Base-64 character sequence using the alphabet described in + /// [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt#base64_encoding_alphabet): + /// ``` + /// ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + /// ``` + /// + /// It is not padded. + static const Base64Codec bcrypt = Base64Codec._( + encoder: AlphabetEncoder( + bits: 6, + alphabet: _base64EncodingBcrypt, + ), + decoder: AlphabetDecoder( + bits: 6, + alphabet: _base64DecodingBcrypt, + ), + ); +} diff --git a/hashlib_codecs/lib/src/codecs/base8.dart b/hashlib_codecs/lib/src/codecs/base8.dart new file mode 100644 index 0000000..8199f8c --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/base8.dart @@ -0,0 +1,149 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib_codecs/src/core/byte.dart'; +import 'package:hashlib_codecs/src/core/codec.dart'; + +const int _zero = 0x30; + +extension on List { + @pragma('vm:prefer-inline') + int enc(int n) => + (this[n - 1] & 0xFF) ^ + ((this[n - 2] & 0xFF) << 8) ^ + ((this[n - 3] & 0xFF) << 16); + + @pragma('vm:prefer-inline') + int dec(int p) { + int x = (this[p] & 0xFF) - _zero; + if (x < 0 || x > 7) { + throw FormatException('Invalid character at $p'); + } + return x; + } +} + +// ======================================================== +// Base-8 Encoder & Decoder +// ======================================================== + +class _Base8Encoder extends ByteEncoder { + const _Base8Encoder() : super(bits: 3); + + @override + Uint8List convert(List input) { + int p, x, n, nb; + n = input.length; + nb = n << 3; + p = nb ~/ 3; + if ((3 * p) != nb) p++; + var out = Uint8List(p); + + for (; n >= 3; n -= 3, p -= 8) { + x = input.enc(n); + out[p - 1] = _zero + ((x) & 7); + out[p - 2] = _zero + ((x >>> 3) & 7); + out[p - 3] = _zero + ((x >>> 6) & 7); + out[p - 4] = _zero + ((x >>> 9) & 7); + out[p - 5] = _zero + ((x >>> 12) & 7); + out[p - 6] = _zero + ((x >>> 15) & 7); + out[p - 7] = _zero + ((x >>> 18) & 7); + out[p - 8] = _zero + ((x >>> 21) & 7); + } + + if (n == 2) { + x = (input[1] & 0xFF) ^ ((input[0] & 0xFF) << 8); + out[p - 1] = _zero + ((x) & 7); + out[p - 2] = _zero + ((x >>> 3) & 7); + out[p - 3] = _zero + ((x >>> 6) & 7); + out[p - 4] = _zero + ((x >>> 9) & 7); + out[p - 5] = _zero + ((x >>> 12) & 7); + out[p - 6] = _zero + ((x >>> 15) & 7); + } else if (n == 1) { + x = input[0] & 0xFF; + out[p - 1] = _zero + ((x) & 7); + out[p - 2] = _zero + ((x >>> 3) & 7); + out[p - 3] = _zero + ((x >>> 6) & 7); + } + + return out; + } +} + +class _Base8Decoder extends ByteDecoder { + const _Base8Decoder() : super(bits: 3); + + @override + Uint8List convert(List encoded) { + int i, p, x, n, z; + + n = encoded.length; + p = 3 * (n >>> 3); + x = n & 7; + z = 0; + if (x > 0) { + for (i = 0; i < x; i++) { + z = (z << 3) ^ encoded.dec(i); + } + p++; + if (x > 3 || z > 0xFF) p++; + if (z > 0xFFFF) p++; + } + var out = Uint8List(p); + + for (; n >= 8; n -= 8, p -= 3) { + x = encoded.dec(n - 1) ^ + (encoded.dec(n - 2) << 3) ^ + (encoded.dec(n - 3) << 6) ^ + (encoded.dec(n - 4) << 9) ^ + (encoded.dec(n - 5) << 12) ^ + (encoded.dec(n - 6) << 15) ^ + (encoded.dec(n - 7) << 18) ^ + (encoded.dec(n - 8) << 21); + out[p - 1] = x; + out[p - 2] = x >>> 8; + out[p - 3] = x >>> 16; + } + + if (z > 0) { + out[p - 1] = z; + if (z > 0xFF) { + out[p - 2] = z >>> 8; + if (z > 0xFFFF) { + out[p - 3] = z >>> 16; + } + } + } + + return out; + } +} + +// ======================================================== +// Base-8 Codec +// ======================================================== + +class Base8Codec extends IterableCodec { + @override + final ByteEncoder encoder; + + @override + final ByteDecoder decoder; + + const Base8Codec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode 8-bit integer sequence to 3-bit + /// Base-8 or Octal character sequence using the alphabet: + /// ``` + /// 012345678 + /// ``` + static const Base8Codec standard = Base8Codec._( + encoder: _Base8Encoder(), + decoder: _Base8Decoder(), + ); +} diff --git a/hashlib_codecs/lib/src/codecs/bigint.dart b/hashlib_codecs/lib/src/codecs/bigint.dart new file mode 100644 index 0000000..bfaa306 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/bigint.dart @@ -0,0 +1,165 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert' show Codec, Converter; + +const int _zero = 0x30; +const int _smallA = 0x61; + +typedef BigIntEncoder = Converter, BigInt>; +typedef BigIntDecoder = Converter>; + +// ======================================================== +// LSB First Encoder and Decoder +// ======================================================== + +class _BigIntLSBFirstEncoder extends BigIntEncoder { + const _BigIntLSBFirstEncoder(); + + @override + BigInt convert(Iterable input) { + int a, b, i, j; + List out = []; + for (int x in input) { + a = (x >>> 4) & 0xF; + b = x & 0xF; + a += a < 10 ? _zero : _smallA - 10; + b += b < 10 ? _zero : _smallA - 10; + out.add(b); + out.add(a); + } + if (out.isEmpty) { + throw FormatException('Empty input'); + } + for (j = out.length - 1; j > 0; j--) { + if (out[j] != _zero) break; + } + var hex = out.take(j + 1); + for (i = 0; i < j; i++, j--) { + a = out[i]; + out[i] = out[j]; + out[j] = a; + } + return BigInt.parse(String.fromCharCodes(hex), radix: 16); + } +} + +class _BigIntLSBFirstDecoder extends BigIntDecoder { + const _BigIntLSBFirstDecoder(); + + @override + Iterable convert(BigInt input) { + if (input.isNegative) { + throw FormatException('Negative numbers are not supported'); + } + if (input == BigInt.zero) { + return [0]; + } + int i, a, b; + List out = []; + var bytes = input.toRadixString(16).codeUnits; + for (i = bytes.length - 2; i >= 0; i -= 2) { + a = bytes[i]; + b = bytes[i + 1]; + a -= a < _smallA ? _zero : _smallA - 10; + b -= b < _smallA ? _zero : _smallA - 10; + out.add((a << 4) | b); + } + if (i == -1) { + a = bytes[0]; + a -= a < _smallA ? _zero : _smallA - 10; + out.add(a); + } + return out; + } +} + +// ======================================================== +// MSB First Encoder and Decoder +// ======================================================== + +class _BigIntMSBFirstEncoder extends BigIntEncoder { + const _BigIntMSBFirstEncoder(); + + @override + BigInt convert(Iterable input) { + int a, b; + List out = []; + for (int x in input) { + a = (x >>> 4) & 0xF; + b = x & 0xF; + a += a < 10 ? _zero : _smallA - 10; + b += b < 10 ? _zero : _smallA - 10; + out.add(a); + out.add(b); + } + if (out.isEmpty) { + throw FormatException('Empty input'); + } + return BigInt.parse(String.fromCharCodes(out), radix: 16); + } +} + +class _BigIntMSBFirstDecoder extends BigIntDecoder { + const _BigIntMSBFirstDecoder(); + + @override + Iterable convert(BigInt input) { + if (input.isNegative) { + throw FormatException('Negative numbers are not supported'); + } + if (input == BigInt.zero) { + return [0]; + } + int i, a, b, n; + List out = []; + var bytes = input.toRadixString(16).codeUnits; + n = bytes.length; + i = 1; + if (n & 1 == 1) { + a = bytes[0]; + a -= a < _smallA ? _zero : _smallA - 10; + out.add(a); + i++; + } + for (; i < n; i += 2) { + a = bytes[i - 1]; + b = bytes[i]; + a -= a < _smallA ? _zero : _smallA - 10; + b -= b < _smallA ? _zero : _smallA - 10; + out.add((a << 4) | b); + } + return out; + } +} + +// ======================================================== +// BigInt Codec +// ======================================================== + +class BigIntCodec extends Codec, BigInt> { + @override + final BigIntEncoder encoder; + + @override + final BigIntDecoder decoder; + + const BigIntCodec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode 8-bit integer sequence to [BigInt] + /// number treating the input bytes in big-endian order. + static const BigIntCodec msbFirst = BigIntCodec._( + encoder: _BigIntMSBFirstEncoder(), + decoder: _BigIntMSBFirstDecoder(), + ); + + /// Codec instance to encode and decode 8-bit integer sequence to [BigInt] + /// number treating the input bytes in little-endian order. + static const BigIntCodec lsbFirst = BigIntCodec._( + encoder: _BigIntLSBFirstEncoder(), + decoder: _BigIntLSBFirstDecoder(), + ); +} diff --git a/hashlib_codecs/lib/src/codecs/crypt/crypt.dart b/hashlib_codecs/lib/src/codecs/crypt/crypt.dart new file mode 100644 index 0000000..4c906a9 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/crypt/crypt.dart @@ -0,0 +1,6 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'crypt_codec.dart'; +export 'crypt_data.dart'; +export 'crypt_builder.dart'; diff --git a/hashlib_codecs/lib/src/codecs/crypt/crypt_builder.dart b/hashlib_codecs/lib/src/codecs/crypt/crypt_builder.dart new file mode 100644 index 0000000..1dbf5f0 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/crypt/crypt_builder.dart @@ -0,0 +1,87 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'package:hashlib_codecs/src/base64.dart'; + +import 'crypt_data.dart'; + +/// Convenient builder for [CryptData]. +class CryptDataBuilder { + final String id; + String? _version; + String? _salt; + String? _hash; + final _params = {}; + + /// Creates a new builder for [CryptData]. + /// + /// Parameters: + /// - [id] : The identifier name, which must not exceed 32 characters in + /// length and must be a sequence of characters in `[a-z0-9-]`. + /// + /// Good identifiers should be should be explicit (human readable, not a + /// single digit), with a length of about 5 to 10 characters. + CryptDataBuilder(this.id); + + /// Set the algorithm version. + /// + /// The value for the version must be a sequence of characters in: `[0-9]`. + /// + /// It is recommended to use a default version. + CryptDataBuilder version(String v) { + _version = v; + return this; + } + + /// Set the salt. + CryptDataBuilder salt(String v) { + _salt = v; + return this; + } + + /// Set the output hash. + CryptDataBuilder hash(String v) { + _hash = v; + return this; + } + + /// Set the salt bytes using standard Base-64 codecs without padding. + CryptDataBuilder saltBytes(List v) { + _salt = toBase64(v, padding: false); + return this; + } + + /// Set the output hash bytes using standard Base-64 codecs without padding. + CryptDataBuilder hashBytes(List v) { + _hash = toBase64(v, padding: false); + return this; + } + + /// Set a parameter value. + /// + /// The parameter [name] must not exceed 32 characters in length and must be a + /// sequence of characters in: `[a-z0-9-]`. + /// + /// If [value] is not a [String], it will be converted to one with [toString]. + /// As a string, it must be a sequence of characters in `[a-zA-Z0-9/+.-]`. + CryptDataBuilder param(String name, dynamic value) { + _params[name] = value == null ? value : value.toString(); + return this; + } + + /// Creates the [CryptData] instance. + /// + /// This also validates the parameters, and throws [ArgumentError] if + /// something is wrong. + CryptData build() { + var data = CryptData( + id, + version: _version, + salt: _salt, + hash: _hash, + params: _params.isEmpty ? null : _params, + ); + data.validate(); + return data; + } +} diff --git a/hashlib_codecs/lib/src/codecs/crypt/crypt_codec.dart b/hashlib_codecs/lib/src/codecs/crypt/crypt_codec.dart new file mode 100644 index 0000000..2e604f7 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/crypt/crypt_codec.dart @@ -0,0 +1,135 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert'; + +import 'crypt_data.dart'; + +/// Provides encoding and decoding of [PHC string format][phc] data. +/// +/// **PHC string format** is a standardized way to represent password hashes +/// generated by the competing password hashing algorithms. This format is +/// designed to ensure consistency and interoperability between different +/// password hashing implementations. +/// +/// The string format specifiction: +/// ``` +/// $[$v=][$=(,=)*][$[$]] +/// ``` +/// +/// [phc]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +class CryptFormat extends Codec { + const CryptFormat(); + + @override + final encoder = const CryptEncoder(); + + @override + final decoder = const CryptDecoder(); +} + +/// The encoder used by the [CryptFormat] codec +class CryptEncoder extends Converter { + const CryptEncoder(); + + @override + String convert(CryptData input) { + input.validate(); + String result = '\$${input.id}'; + if (input.version != null && input.version!.isNotEmpty) { + result += '\$v=${input.version!}'; + } + if (input.params != null && input.params!.isNotEmpty) { + result += '\$'; + result += input.params!.entries + .map((entry) => '${entry.key}=${entry.value}') + .join(','); + } + if (input.salt != null && input.salt!.isNotEmpty) { + result += '\$'; + result += input.salt!; + } + if (input.hash != null && input.hash!.isNotEmpty) { + result += '\$'; + result += input.hash!; + } + return result; + } +} + +/// The decoder used by the [CryptFormat] codec +class CryptDecoder extends Converter { + const CryptDecoder(); + + @override + CryptData convert(String input) { + if (input.isEmpty) { + throw FormatException('Empty string'); + } + + String id, val; + List pair; + Iterable parts; + String? version, salt, hash; + Map? params; + + parts = input.split(r'$'); + if (parts.first.isNotEmpty) { + throw FormatException(r'Does not start with "$"'); + } + + parts = parts.skip(1); + id = parts.first; + + parts = parts.skip(1); + if (parts.isNotEmpty) { + val = parts.first; + if (val.startsWith('v=')) { + version = val.substring(2); + parts = parts.skip(1); + } + } + + if (parts.isNotEmpty) { + val = parts.first; + if (val.contains('=') || val.contains(',')) { + params = {}; + for (final kv in parts.first.split(',')) { + pair = kv.split('='); + if (pair.length != 2) { + throw FormatException('Invalid parameter: "$kv"'); + } + if (params.containsKey(pair[0])) { + throw FormatException('Duplicate parameter key: "${pair[0]}"'); + } + params[pair[0]] = pair[1]; + } + parts = parts.skip(1); + } + } + + if (parts.isNotEmpty) { + salt = parts.first; + parts = parts.skip(1); + } + + if (parts.isNotEmpty) { + hash = parts.first; + parts = parts.skip(1); + } + + if (parts.isNotEmpty) { + throw FormatException('Extra characters at the end'); + } + + var data = CryptData( + id, + version: version, + salt: salt, + hash: hash, + params: params, + ); + data.validate(); + return data; + } +} diff --git a/hashlib_codecs/lib/src/codecs/crypt/crypt_data.dart b/hashlib_codecs/lib/src/codecs/crypt/crypt_data.dart new file mode 100644 index 0000000..db4156a --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/crypt/crypt_data.dart @@ -0,0 +1,134 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib_codecs/src/base64.dart'; + +import 'crypt_builder.dart'; + +/// The PHC string format data +class CryptData { + /// The symbolic name for the hash function. + final String id; + + /// (Optional) The algorithm version. + final String? version; + + /// (Optional) The salt. + final String? salt; + + /// (Optional) The output hash. + final String? hash; + + /// (Optional) The algorithm parameters. + final Map? params; + + /// Creates an instance of [CryptData]. + /// + /// Paramaters: + /// - [id] The identifier name, must not exceed 32 characters in length and + /// must be a sequence of characters in: `[a-z0-9-]`. + /// - [version] (Optional) The value for the version must be a sequence of + /// characters in: `[0-9]`. + /// - [params] (Optional) A map containing name, value pairs of algorithm + /// parameters. The names must not exceed 32 characters in length and must + /// be a sequence of characters in: `[a-z0-9-]`, the values must be a + /// sequence of characters in: `[a-zA-Z0-9/+.-]`. + /// - [salt] (Optional) The salt bytes. + /// - [hash] (Optional) The output hash bytes. + const CryptData( + this.id, { + this.salt, + this.hash, + this.version, + this.params, + }); + + /// Returns a [CryptDataBuilder] instance for [id]. + /// + /// Parameters: + /// - [id] : The identifier name, which must not exceed 32 characters in + /// length and must be a sequence of characters in `[a-z0-9-]`. + /// + /// Good identifiers should be should be explicit (human readable, not a + /// single digit), with a length of about 5 to 10 characters. + static CryptDataBuilder builder(String id) => CryptDataBuilder(id); + + /// Parse the [salt] using standard Base-64 codec + Uint8List? saltBytes() => + salt == null ? null : fromBase64(salt!, padding: false); + + /// Parse the [hash] using standard Base-64 codec + Uint8List? hashBytes() => + hash == null ? null : fromBase64(hash!, padding: false); + + /// Get the version as integer + int? versionInt() => version == null ? null : int.tryParse(version!); + + /// Check if the [key] parameter exists + bool hasParam(String key) => + params == null ? false : params!.containsKey(key); + + /// Get the value of a paramter by [key] + String? getParam(String key) => params?[key]; + + /// Get the value of a paramter by [key] as integer + int? getIntParam(String key) { + var val = getParam(key); + return val == null ? null : int.tryParse(val); + } + + /// Validate this PHC string. + /// Throws [ArgumentError] when any field is invalid. + void validate() { + final digitRe = RegExp(r'^[0-9]+$'); + final alnumRe = RegExp(r'^[a-z0-9-]{1,32}$'); + final base64Re = RegExp(r'^[a-zA-Z0-9/+.-]+$'); + + // id + if (!alnumRe.hasMatch(id)) { + throw ArgumentError.value( + id, 'id', 'must be [a-z0-9-] and under 32 characters'); + } + + // version (optional) + if (version != null && !digitRe.hasMatch(version!)) { + throw ArgumentError.value(version, 'version', 'must be decimal digits'); + } + + // params (optional) + if (params != null) { + for (final e in params!.entries) { + final k = e.key; + final v = e.value; + if (!alnumRe.hasMatch(k)) { + throw ArgumentError.value( + k, 'params.key', 'must be [a-z0-9-] and under 32 chars'); + } + if (k == 'v') { + throw ArgumentError.value( + k, 'params.key', 'reserved; use version field instead'); + } + if (v.isEmpty) { + throw ArgumentError.value(v, 'params[$k]', 'value is empty'); + } else if (!base64Re.hasMatch(v)) { + throw ArgumentError.value( + v, 'params[$k]', 'value has invalid characters'); + } + } + } + + // salt (optional) + if (salt != null && !base64Re.hasMatch(salt!)) { + throw ArgumentError.value( + salt, 'salt', 'expected base64 string without padding'); + } + + // hash (optional) + if (hash != null && !base64Re.hasMatch(hash!)) { + throw ArgumentError.value( + hash, 'hash', 'expected base64 string without padding'); + } + } +} diff --git a/hashlib_codecs/lib/src/codecs/utf8.dart b/hashlib_codecs/lib/src/codecs/utf8.dart new file mode 100644 index 0000000..df2e34c --- /dev/null +++ b/hashlib_codecs/lib/src/codecs/utf8.dart @@ -0,0 +1,219 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'package:hashlib_codecs/hashlib_codecs.dart'; + +/* + Char. number range | UTF-8 octet sequence + --------------------+------------------------------------ + 0000 0000-0000 007F | 0xxxxxxx + 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx +*/ + +const int _range1 = 0x0000007F; +const int _range2 = 0x000007FF; +const int _range3 = 0x0000FFFF; +const int _range4 = 0x0010FFFF; + +// ======================================================== +// UTF-8 Encoder and Decoder +// ======================================================== + +class _UTF8Encoder extends BitEncoder { + const _UTF8Encoder(); + + @override + int get source => 32; + + @override + int get target => 8; + + @override + Uint8List convert(List input) { + List out = []; + int len = input.length; + for (int x, y, p = 0; p < len; ++p) { + x = input[p]; + // check negative code + if (x < 0) { + throw FormatException('Negative code $x at $p'); + } + // UTF-16 surrogate pairs + if (x >= 0xD800 && x <= 0xDBFF) { + if (p + 1 >= len) { + throw FormatException('Unpaired high surrogate $x at $p'); + } + y = input[++p]; + if (y < 0xDC00 || y > 0xDFFF) { + throw FormatException('Invalid surrogate pair $x,$y at ${p - 1}'); + } + x = 0x10000 + (((x - 0xD800) << 10) | (y - 0xDC00)); + } else if (x >= 0xDC00 && x <= 0xDFFF) { + throw FormatException('Unpaired low surrogate $x at $p'); + } + // extract bytes + if (x <= _range1) { + out.add(x & 0x7F); + } else if (x <= _range2) { + out.add(0xC0 | ((x >>> 6) & 0x1F)); + out.add(0x80 | (x & 0x3F)); + } else if (x <= _range3) { + out.add(0xE0 | ((x >>> 12) & 0xF)); + out.add(0x80 | ((x >>> 6) & 0x3F)); + out.add(0x80 | (x & 0x3F)); + } else if (x <= _range4) { + out.add(0xF0 | ((x >>> 18) & 0x7)); + out.add(0x80 | ((x >>> 12) & 0x3F)); + out.add(0x80 | ((x >>> 6) & 0x3F)); + out.add(0x80 | (x & 0x3F)); + } else { + throw FormatException('Invalid code $x at $p'); + } + } + return Uint8List.fromList(out); + } +} + +class _UTF8Decoder extends BitDecoder { + const _UTF8Decoder(); + + @override + int get source => 8; + + @override + int get target => 32; + + @override + List convert(List encoded) { + List out = []; + int len = encoded.length; + for (int x, y, z, p = 0; p < len; ++p) { + x = encoded[p]; + + // Case: 1-byte + if (x <= 0x7F) { + out.add(x); + } + // Case: 2-bytes + else if ((x & 0xE0) == 0xC0) { + if (x < 0xC2) { + throw FormatException('Overlong 2-byte sequence at $p'); + } + if (p + 1 >= len) { + throw FormatException('Insufficient input'); + } + + z = encoded[++p]; + if (((z & 0xC0) != 0x80)) { + throw FormatException('Invalid continuation byte $z at $p'); + } + + y = ((x & 0x1F) << 6) | z; + out.add(y); + } + // Case: 3-bytes + else if ((x & 0xF0) == 0xE0) { + if (p + 2 >= len) { + throw FormatException('Insufficient input'); + } + + z = encoded[++p]; + if (((z & 0xC0) != 0x80)) { + throw FormatException('Invalid continuation byte $z at $p'); + } else if (x == 0xE0 && z < 0xA0) { + throw FormatException('Overlong 3-byte sequence at ${p - 1}'); + } + + y = (x & 0xF) << 12; + y |= (z & 0x3F) << 6; + + z = encoded[++p]; + if (((z & 0xC0) != 0x80)) { + throw FormatException('Invalid continuation byte $z at $p'); + } + + y |= z & 0x3F; + if (y >= 0xD800 && y <= 0xDFFF) { + throw FormatException('Invalid surrogate $y at ${p - 2}'); + } + + out.add(y); + } + // Case: 4-byte + else if ((x & 0xF8) == 0xF0) { + if (x > 0xF4) { + throw FormatException('Invalid 4-byte lead $x at $p'); + } + if (p + 3 >= len) { + throw FormatException('Insufficient input'); + } + + z = encoded[++p]; + if (((z & 0xC0) != 0x80)) { + throw FormatException('Invalid continuation byte $z at $p'); + } else if (x == 0xF0 && z < 0x90) { + throw FormatException('Overlong 4-byte sequence at ${p - 1}'); + } + + y = (x & 0x7) << 18; + y |= (z & 0x3F) << 12; + + z = encoded[++p]; + if (((z & 0xC0) != 0x80)) { + throw FormatException('Invalid continuation byte $z at $p'); + } + + y |= (z & 0x3F) << 6; + + z = encoded[++p]; + if (((z & 0xC0) != 0x80)) { + throw FormatException('Invalid continuation byte $z at $p'); + } + + y |= z & 0x3F; + if (y > _range4) { + throw FormatException('Above U+10FFFF at ${p - 3}'); + } + + out.add(y); + } + // Case: 5 or more bytes + else { + throw FormatException('Invalid code $x at $p'); + } + } + return out; + } +} + +// ======================================================== +// UTF-8 Codec +// ======================================================== + +class UTF8Codec extends IterableCodec { + @override + final BitEncoder encoder; + + @override + final BitDecoder decoder; + + const UTF8Codec._({ + required this.encoder, + required this.decoder, + }); + + /// Codec instance to encode and decode UTF-8 character code units to 8-bit + /// UTF-8 octet sequence. + /// + /// This implementation is based on [RFC-3629][rfc] + /// + /// [rfc]: https://datatracker.ietf.org/doc/html/rfc3629 + static const UTF8Codec standard = UTF8Codec._( + encoder: _UTF8Encoder(), + decoder: _UTF8Decoder(), + ); +} diff --git a/hashlib_codecs/lib/src/codecs_base.dart b/hashlib_codecs/lib/src/codecs_base.dart new file mode 100644 index 0000000..1a421d1 --- /dev/null +++ b/hashlib_codecs/lib/src/codecs_base.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +export 'base16.dart'; +export 'base2.dart'; +export 'base32.dart'; +export 'base64.dart'; +export 'base8.dart'; +export 'bigint.dart'; +export 'codecs/base16.dart'; +export 'codecs/base2.dart'; +export 'codecs/base32.dart'; +export 'codecs/base64.dart'; +export 'codecs/base8.dart'; +export 'codecs/bigint.dart'; +export 'codecs/utf8.dart'; +export 'core/codec.dart'; +export 'core/decoder.dart'; +export 'core/encoder.dart'; +export 'crypt.dart'; +export 'utf8.dart'; diff --git a/hashlib_codecs/lib/src/core/alphabet.dart b/hashlib_codecs/lib/src/core/alphabet.dart new file mode 100644 index 0000000..1d0fb7a --- /dev/null +++ b/hashlib_codecs/lib/src/core/alphabet.dart @@ -0,0 +1,100 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'byte.dart'; +import 'decoder.dart'; + +class AlphabetEncoder extends ByteEncoder { + final List alphabet; + + /// The padding character. + /// + /// The output array will be padded with this character to make the length + /// of the array to be divisible by [source]. + final int? padding; + + /// Creates a new [AlphabetEncoder] instance. + /// + /// Parameters: + /// - [bits] is bit-length of a single word in the output + /// - The [alphabet] contains mapping from input word to output word. + /// - The output array will be padded with the [padding] to make the length of + /// the array to be divisible by [source]. + const AlphabetEncoder({ + required int bits, + required this.alphabet, + this.padding, + }) : super(bits: bits); + + @override + int get target => bits; + + @override + Uint8List convert(List input) { + int i, n; + var encoded = super.convert(input) as Uint8List; + n = encoded.length; + for (i = 0; i < n; ++i) { + encoded[i] = alphabet[encoded[i]]; + } + if (padding == null) { + return encoded; + } + + n = encoded.length; + for (i = n * target; (i & 7) != 0; i += target) { + n++; + } + var out = Uint8List(n); + for (i = 0; i < encoded.length; ++i) { + out[i] = encoded[i]; + } + for (; i < n; ++i) { + out[i] = padding!; + } + return out; + } +} + +class AlphabetDecoder extends BitDecoder { + final int bits; + final List alphabet; + + @override + final int target = 8; + + /// The padding character. + /// + /// The conversion will stop immediately upon encountering this character. + final int? padding; + + /// Creates a new [AlphabetDecoder] instance. + /// + /// Parameters: + /// - [bits] is bit-length of a single word in the output + /// - The [alphabet] contains mapping from input word to output word. + /// - If [padding] is not null, conversion will stop immediately upon + /// encountering this character. + const AlphabetDecoder({ + required this.bits, + required this.alphabet, + this.padding, + }); + + @override + int get source => bits; + + @override + List convert(List encoded) { + int x; + return super.convert(encoded.map((y) { + if (y == padding) return -1; + if (y < 0 || y >= alphabet.length || (x = alphabet[y]) < 0) { + throw FormatException('Invalid character $y'); + } + return x; + }).toList()); + } +} diff --git a/hashlib_codecs/lib/src/core/byte.dart b/hashlib_codecs/lib/src/core/byte.dart new file mode 100644 index 0000000..8b4ffb0 --- /dev/null +++ b/hashlib_codecs/lib/src/core/byte.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'decoder.dart'; +import 'encoder.dart'; + +abstract class ByteEncoder extends BitEncoder { + final int bits; + + /// Creates a new [ByteEncoder] instance. + /// + /// Parameters: + /// - [bits] is bit-length of a single word in the output + const ByteEncoder({ + required this.bits, + }); + + @override + final int source = 8; + + @override + int get target => bits; + + @override + Uint8List convert(List input); +} + +abstract class ByteDecoder extends BitDecoder { + final int bits; + + /// Creates a new [ByteDecoder] instance. + /// + /// Parameters: + /// - [bits] is bit-length of a single word in the output + const ByteDecoder({ + required this.bits, + }); + + @override + int get source => bits; + + @override + final int target = 8; + + @override + Uint8List convert(List encoded); +} diff --git a/hashlib_codecs/lib/src/core/codec.dart b/hashlib_codecs/lib/src/core/codec.dart new file mode 100644 index 0000000..3a142e4 --- /dev/null +++ b/hashlib_codecs/lib/src/core/codec.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:convert' show Codec, Converter; +import 'dart:typed_data'; + +import 'decoder.dart'; +import 'encoder.dart'; + +/// Base class for encoding from and to 8-bit integer sequence +abstract class IterableCodec extends Codec, Iterable> { + /// Creates a new [IterableCodec] instance. + const IterableCodec(); + + @override + BitEncoder get encoder; + + @override + BitDecoder get decoder; + + /// Encodes an [input] string using this codec + @pragma('vm:prefer-inline') + Iterable encodeString(String input) => encode(input.codeUnits); + + /// Decodes an [encoded] string using this codec + @pragma('vm:prefer-inline') + Iterable decodeString(String encoded) => decode(encoded.codeUnits); + + /// Encodes an [input] buffer using this codec + @pragma('vm:prefer-inline') + Iterable encodeBuffer(ByteBuffer input) => encode(input.asUint8List()); + + /// Decodess an [encoded] buffer using this codec + @pragma('vm:prefer-inline') + Iterable decodeBuffer(ByteBuffer encoded) => + decode(encoded.asUint8List()); +} + +/// Base class for bit-wise encoder and decoder implementation +abstract class HashlibConverter + extends Converter, Iterable> { + /// Creates a new [HashlibConverter] instance. + const HashlibConverter(); + + /// The bit-length of the input array elements. + /// The value should be between 2 to 64. + int get source; + + /// The bit-length of the output array elements. + /// The value should be between 2 to 64. + int get target; + + /// Converts [input] array of numbers with bit-length of [source] to an array + /// of numbers with bit-length of [target]. The [input] array will be treated + /// as a sequence of bits to convert. + @override + Iterable convert(Iterable input); +} diff --git a/hashlib_codecs/lib/src/core/decoder.dart b/hashlib_codecs/lib/src/core/decoder.dart new file mode 100644 index 0000000..999c612 --- /dev/null +++ b/hashlib_codecs/lib/src/core/decoder.dart @@ -0,0 +1,63 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codec.dart'; + +abstract class BitDecoder extends HashlibConverter { + /// Creates a new [BitDecoder] instance. + const BitDecoder(); + + /// Converts [encoded] array of numbers with bit-length of [source] to an array + /// of numbers with bit-length of [target]. The [encoded] array will be treated + /// as a sequence of bits to convert. + /// + /// If the [encoded] array contains negative numbers or numbers having more than + /// the [source] bits, it will be treated as the end of the input sequence. + /// + /// After consuming all of input sequence, if there are some non-zero partial + /// word remains, it will throw [FormatException]. + @override + List convert(covariant List encoded) { + int x, p, s, t, l, n, sb, tb; + sb = source; + tb = target; + if (sb < 2 || sb > 64) { + throw ArgumentError('The source bit length should be between 2 to 64'); + } + if (tb < 2 || tb > 64) { + throw ArgumentError('The target bit length should be between 2 to 64'); + } + + l = encoded.length * sb; + var out = Uint8List(l ~/ tb); + + // generate words from the input bits + p = n = t = l = 0; + s = 1 << (sb - 1); + s = s ^ (s - 1); + for (x in encoded) { + if (x < 0 || x > s) break; + p = (p << sb) ^ x; + t = (t << sb) ^ s; + n += sb; + while (n >= tb) { + n -= tb; + out[l++] = p >>> n; + t >>>= tb; + p &= t; + } + } + + // p > 0 means that there is a non-zero partial word remaining + if (p > 0) { + throw FormatException('Invalid length'); + } + + if (l < out.length) { + return out.sublist(0, l); + } + return out; + } +} diff --git a/hashlib_codecs/lib/src/core/encoder.dart b/hashlib_codecs/lib/src/core/encoder.dart new file mode 100644 index 0000000..db57f0a --- /dev/null +++ b/hashlib_codecs/lib/src/core/encoder.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codec.dart'; + +abstract class BitEncoder extends HashlibConverter { + /// Creates a new [BitEncoder] instance. + const BitEncoder(); + + /// Converts [input] array of numbers with bit-length of [source] to an array + /// of numbers with bit-length of [target]. The [input] array will be treated + /// as a sequence of bits to convert. + /// + /// After consuming all of input sequence, if there are some non-zero partial + /// word remains, 0 will be padded on the right to make the final word. + @override + List convert(covariant List input) { + int x, p, s, t, l, n, sb, tb; + sb = source; + tb = target; + if (sb < 2 || sb > 64) { + throw ArgumentError('The source bit length should be between 2 to 64'); + } + if (tb < 2 || tb > 64) { + throw ArgumentError('The target bit length should be between 2 to 64'); + } + + l = input.length * sb; + n = l ~/ tb; + if (n * tb < l) n++; + var out = Uint8List(n); + + // generate words from the input bits + p = n = l = t = 0; + s = 1 << (sb - 1); + s = s ^ (s - 1); + for (x in input) { + p = (p << sb) ^ (x & s); + t = (t << sb) ^ s; + n += sb; + while (n >= tb) { + n -= tb; + out[l++] = p >>> n; + t >>>= tb; + p &= t; + } + } + + // n > 0 means that there is a partial word remaining. + if (n > 0) { + // pad the word with 0 on the right to make the final word + out[l++] = p << (tb - n); + } + + return out; + } +} diff --git a/hashlib_codecs/lib/src/crypt.dart b/hashlib_codecs/lib/src/crypt.dart new file mode 100644 index 0000000..8666d03 --- /dev/null +++ b/hashlib_codecs/lib/src/crypt.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2023, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'codecs/crypt/crypt.dart'; + +export 'codecs/crypt/crypt.dart'; + +/// An instance of [CryptFormat] for encoding and decoding hash algorithm output +/// with [PHC string format][phc] +/// +/// [phc]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +const crypt = CryptFormat(); + +/// Encodes a hash algorithm output to string following PHC string format. +String toCrypt(CryptData input) { + return crypt.encoder.convert(input); +} + +/// Decodes a string to an hash algorithm config following PHC string format. +CryptData fromCrypt(String input) { + return crypt.decoder.convert(input); +} diff --git a/hashlib_codecs/lib/src/utf8.dart b/hashlib_codecs/lib/src/utf8.dart new file mode 100644 index 0000000..f2e4e23 --- /dev/null +++ b/hashlib_codecs/lib/src/utf8.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2024, Sudipto Chandra +// All rights reserved. Check LICENSE file for details. + +import 'dart:typed_data'; + +import 'codecs/utf8.dart'; + +/// Converts UTF-8 character code points to 8-bit UTF-8 octet sequence. +/// +/// Parameters: +/// - [input] is a sequence of UTF-8 character code points. +/// - [codec] is the [UTF8Codec] to use. +Uint8List toUtf8( + String input, { + UTF8Codec codec = UTF8Codec.standard, +}) { + var out = codec.encoder.convert(input.codeUnits); + return Uint8List.fromList(out); +} + +/// Converts 8-bit UTF-8 octet sequence to UTF-8 character code points. +/// +/// Parameters: +/// - [input] should be a valid UTF-8 octet sequence. +/// - [codec] is the [UTF8Codec] to use. +/// +/// Throws: +/// - [FormatException] if the [input] contains invalid characters. +/// +/// This implementation can handle both uppercase and lowercase alphabets. If a +/// partial string is detected, the following bits are assumed to be zeros. +String fromUtf8( + List input, { + UTF8Codec codec = UTF8Codec.standard, +}) { + var out = codec.decoder.convert(input); + return String.fromCharCodes(out); +} diff --git a/hashlib_codecs/pubspec.yaml b/hashlib_codecs/pubspec.yaml new file mode 100644 index 0000000..946c943 --- /dev/null +++ b/hashlib_codecs/pubspec.yaml @@ -0,0 +1,25 @@ +name: hashlib_codecs +description: Fast and error resilient codecs. Currently supporting Binary(Base2), Hexadecimal(Base16), Base32, Base64, BigInt. +homepage: https://github.com/bitanon/hashlib_codecs +version: 3.0.1 + +environment: + sdk: '>=2.19.0 <4.0.0' + +platforms: + android: + ios: + linux: + macos: + web: + windows: + +dev_dependencies: + lints: ^1.0.1 + test: ^1.21.4 + benchmark_harness: ^2.2.1 + base_codecs: ^1.0.1 + base32: ^2.1.3 + +funding: + - https://paypal.me/sd1pu diff --git a/hashlib_codecs/test/base16_test.dart b/hashlib_codecs/test/base16_test.dart new file mode 100644 index 0000000..75594a4 --- /dev/null +++ b/hashlib_codecs/test/base16_test.dart @@ -0,0 +1,173 @@ +import 'package:base_codecs/base_codecs.dart' as base_codecs; +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test base16', () { + test('parameter overrides', () { + var a = toHex([12]); + expect(a, "0c"); + a = toHex( + [12], + codec: Base16Codec.upper, + ); + expect(a, "0C"); + a = toHex( + [12], + codec: Base16Codec.lower, + upper: true, + ); + expect(a, "0c"); + }); + + test('encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toHex(b); + expect(fromHex(r), equals(b), reason: 'length $i'); + } + }); + + test('encoding <-> decoding uppercase', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toHex(b, upper: true); + expect(fromHex(r), equals(b), reason: 'length $i'); + } + }); + + group("encoding", () { + test('[] => empty string', () { + expect(toHex([]), ""); + }); + test('[5] => 05', () { + expect(toHex([5]), "05"); + }); + test('[12] => 0c', () { + expect(toHex([12]), "0c"); + }); + test('[16] => 10', () { + expect(toHex([16]), "10"); + }); + test('[0,0,0] => 000000 ', () { + var inp = [0, 0, 0]; + var out = "000000"; + expect(toHex(inp), equals(out)); + }); + test('random', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var hex = b.map((x) => x.toRadixString(16).padLeft(2, '0')).join(); + expect(toHex(b), hex, reason: 'length $i'); + } + }); + group('buffer', () { + var buf = [ + 244, 11, 21, 63, 222, 56, 63, 111, 57, 64, 22, 56, 32, // + 55, 115, 178, 138, 230, 251 + ]; + var lowerHex = "f40b153fde383f6f39401638203773b28ae6fb"; + var upperHex = "F40B153FDE383F6F39401638203773B28AE6FB"; + test("lower", () { + expect(toHex(buf), lowerHex); + }); + test("upper", () { + expect(toHex(buf, upper: true), upperHex); + }); + }); + }); + + group("decoding", () { + test('empty string => []', () { + expect(fromHex(""), []); + }); + test('5 => [5]', () { + expect(fromHex("5"), [5]); + }); + test('c => [12]', () { + expect(fromHex("c"), [12]); + }); + test('0c => [12]', () { + expect(fromHex("0c"), [12]); + }); + test('00c => [0, 12]', () { + expect(fromHex("00c"), [0, 12]); + }); + test('000c => [0, 12]', () { + expect(fromHex("000c"), [0, 12]); + }); + test('0000c => [0, 0, 12]', () { + expect(fromHex("0000c"), [0, 0, 12]); + }); + test('000000 => [0,0,0]', () { + var inp = [0, 0, 0]; + var out = "000000"; + expect(fromHex(out), equals(inp)); + }); + test('random', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var hex = b.map((x) => x.toRadixString(16).padLeft(2, '0')).join(); + expect(fromHex(hex), equals(b), reason: 'length $i'); + } + }); + + group('buffer', () { + var buf = [ + 244, 11, 21, 63, 222, 56, 63, 111, 57, 64, 22, 56, 32, // + 55, 115, 178, 138, 230, 251 + ]; + var lowerHex = "f40b153fde383f6f39401638203773b28ae6fb"; + var upperHex = "F40B153FDE383F6F39401638203773B28AE6FB"; + test("lower", () { + expect(fromHex(lowerHex), equals(buf)); + }); + test("upper", () { + expect(fromHex(upperHex), equals(buf)); + }); + }); + group('with invalid chars', () { + test('Error', () { + expect(() => fromHex("Error"), throwsFormatException); + }); + test('-10', () { + expect(() => fromHex("-10"), throwsFormatException); + }); + test('something', () { + expect(() => fromHex("something"), throwsFormatException); + }); + }); + }); + + group('compare against package: base_codecs', () { + test('encoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var hashlib = toHex(b, upper: true); + var base = base_codecs.base16.encode(b); + expect(base, hashlib, reason: 'length $i'); + } + }); + test('decoding (lowercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var h = toHex(b); + var hashlib = fromHex(h); + var base = base_codecs.base16.decode(h); + expect(base, hashlib, reason: 'length $i'); + } + }); + test('decoding (uppercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var h = toHex(b, upper: true); + var hashlib = fromHex(h); + var base = base_codecs.base16.decode(h); + expect(base, hashlib, reason: 'length $i'); + } + }); + }); + }); +} diff --git a/hashlib_codecs/test/base2_test.dart b/hashlib_codecs/test/base2_test.dart new file mode 100644 index 0000000..fd75d11 --- /dev/null +++ b/hashlib_codecs/test/base2_test.dart @@ -0,0 +1,87 @@ +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test base2', () { + group("encoding", () { + test('[] => empty string', () { + expect(toBinary([]), ""); + }); + test('[1] => 00000001', () { + expect(toBinary([1]), "00000001"); + }); + test('[7] => 00000111', () { + expect(toBinary([7]), "00000111"); + }); + test('[10] => 00001010', () { + expect(toBinary([10]), "00001010"); + }); + test('[0,10] => 00001010', () { + expect(toBinary([0, 10]), "0000000000001010"); + }); + test('random', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = b.map((x) => x.toRadixString(2).padLeft(8, '0')).join(); + expect(toBinary(b), equals(r), reason: 'length $i'); + } + }); + }); + group("decoding", () { + test('empty string => []', () { + expect(fromBinary(""), []); + }); + test('1010 => [10]', () { + expect(fromBinary("1010"), [10]); + }); + test('01010 => [10]', () { + expect(fromBinary("01010"), [10]); + }); + test('0001010 => [10]', () { + expect(fromBinary("0001010"), [10]); + }); + test('00001010 => [10]', () { + expect(fromBinary("00001010"), [10]); + }); + test('000001010 => [0, 10]', () { + expect(fromBinary("000001010"), [0, 10]); + }); + test('0000000001010 => [0, 10]', () { + expect(fromBinary("0000000001010"), [0, 10]); + }); + test('100001010 => [1, 10]', () { + expect(fromBinary("100001010"), [1, 10]); + }); + test('10000001010 => [4, 10]', () { + expect(fromBinary("10000001010"), [4, 10]); + }); + test('random', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = b.map((x) => x.toRadixString(2).padLeft(8, '0')).join(); + expect(fromBinary(r), equals(b), reason: 'length $i'); + } + }); + }); + test('encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBinary(b); + expect(fromBinary(r), equals(b), reason: 'length $i'); + } + }); + group('decoding with invalid chars', () { + test('0158', () { + expect(() => fromBinary("0158"), throwsFormatException); + }); + test('-10', () { + expect(() => fromBinary("-10"), throwsFormatException); + }); + test('01a1', () { + expect(() => fromBinary("01a1"), throwsFormatException); + }); + }); + }); +} diff --git a/hashlib_codecs/test/base32_test.dart b/hashlib_codecs/test/base32_test.dart new file mode 100644 index 0000000..38da483 --- /dev/null +++ b/hashlib_codecs/test/base32_test.dart @@ -0,0 +1,457 @@ +import 'package:base32/base32.dart' as base32; +import 'package:base32/encodings.dart'; +import 'package:base_codecs/base_codecs.dart' as base_codecs; +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test base32', () { + // source: https://github.com/daegalus/dart-base32 + test('parameter overrides', () { + var s = 'foobar'; + var r = 'MZXW6YTBOI======'; + var np = 'MZXW6YTBOI'; + var a = toBase32(s.codeUnits); + expect(a, equals(r)); + a = toBase32( + s.codeUnits, + codec: Base32Codec.standard, + padding: false, + ); + expect(a, equals(np)); + a = toBase32( + s.codeUnits, + codec: Base32Codec.standard, + lower: true, + ); + expect(a, equals(r)); + a = toBase32( + s.codeUnits, + codec: Base32Codec.standard, + padding: false, + lower: true, + ); + expect(a, equals(np)); + }); + + group('encoding <-> decoding', () { + test('standard', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b); + expect(r.toUpperCase(), equals(r), reason: 'length $i'); + var a = fromBase32(r); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('lowercase', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, lower: true); + expect(r.toLowerCase(), equals(r), reason: 'length $i'); + var a = fromBase32(r); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('standard no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, padding: false); + expect(r.toUpperCase(), equals(r), reason: 'length $i'); + expect(r, isNot(endsWith('=')), reason: 'length $i'); + var a = fromBase32(r); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('hex uppercase', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.hex); + var a = fromBase32(r, codec: Base32Codec.hex); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('hex lowercase', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.hexLower); + var a = fromBase32(r, codec: Base32Codec.hexLower); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('crockford', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.crockford); + expect(r, isNot(endsWith('=')), reason: 'length $i'); + var a = fromBase32(r, codec: Base32Codec.crockford); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('geohash', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.geohash); + expect(r.toLowerCase(), equals(r), reason: 'length $i'); + var a = fromBase32(r, codec: Base32Codec.geohash); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('geohash no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.geohash, padding: false); + expect(r, isNot(endsWith('=')), reason: 'length $i'); + var a = fromBase32(r, codec: Base32Codec.geohash); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('word-safe', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.wordSafe); + var a = fromBase32(r, codec: Base32Codec.wordSafe); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('word-safe no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.wordSafe, padding: false); + expect(r, isNot(endsWith('=')), reason: 'length $i'); + var a = fromBase32(r, codec: Base32Codec.wordSafe); + expect(a, equals(b), reason: 'length $i'); + } + }); + test('z-base-32', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase32(b, codec: Base32Codec.z); + expect(r, isNot(endsWith('=')), reason: 'length $i'); + var a = fromBase32(r, codec: Base32Codec.z); + expect(a, equals(b), reason: 'length $i'); + } + }); + }); + + group('encoding', () { + group('no padding', () { + test('"" -> ""', () { + var s = ''; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('')); + }); + test('f -> MY', () { + var s = 'f'; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('MY')); + }); + test('fo -> MZXQ', () { + var s = 'fo'; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('MZXQ')); + }); + test('foo -> MZXW6', () { + var s = 'foo'; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('MZXW6')); + }); + test('foob -> MZXW6YQ', () { + var s = 'foob'; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('MZXW6YQ')); + }); + test('fooba -> MZXW6YTB', () { + var s = 'fooba'; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('MZXW6YTB')); + }); + test('foobar -> MZXW6YTBOI', () { + var s = 'foobar'; + var a = toBase32(s.codeUnits, padding: false); + expect(a, equals('MZXW6YTBOI')); + }); + test('[0, 0, 0] => AAAAA', () { + var inp = [0, 0, 0]; + var out = "AAAAA"; + var act = toBase32(inp, padding: false); + expect(act, equals(out)); + }); + test('48656c6c6f21deadbeef -> JBSWY3DPEHPK3PXP', () { + var encoded = fromHex('48656c6c6f21deadbeef'); + var actual = toBase32(encoded, padding: false); + expect(actual, equals('JBSWY3DPEHPK3PXP')); + }); + test('48656c6c6f21deadbe -> JBSWY3DPEHPK3PQ', () { + var encoded = fromHex('48656c6c6f21deadbe'); + var actual = toBase32(encoded, padding: false); + expect(actual, equals('JBSWY3DPEHPK3PQ')); + }); + test('foobar --lower--> mzxw6ytboi', () { + var text = 'foobar'; + var actual = toBase32(text.codeUnits, padding: false, lower: true); + expect(actual, equals('mzxw6ytboi')); + }); + test('48656c6c6f21deadbeef --lower--> jbswy3dpehpk3pxp', () { + var text = fromHex('48656c6c6f21deadbeef'); + var actual = toBase32(text, padding: false, lower: true); + expect(actual, equals('jbswy3dpehpk3pxp')); + }); + }); + group('with padding', () { + test('f -> MY======', () { + var s = 'f'; + var r = 'MY======'; + expect(toBase32(s.codeUnits), equals(r)); + }); + test('fo -> MZXQ====', () { + var s = 'fo'; + var r = 'MZXQ===='; + expect(toBase32(s.codeUnits), equals(r)); + }); + test('foo -> MZXW6===', () { + var s = 'foo'; + var r = 'MZXW6==='; + expect(toBase32(s.codeUnits), equals(r)); + }); + test('foob -> MZXW6YQ=', () { + var s = 'foob'; + var r = 'MZXW6YQ='; + expect(toBase32(s.codeUnits), equals(r)); + }); + test('foobar -> MZXW6YTBOI======', () { + var s = 'foobar'; + var r = 'MZXW6YTBOI======'; + expect(toBase32(s.codeUnits), equals(r)); + }); + test('48656c6c6f21deadbe -> JBSWY3DPEHPK3PQ=', () { + var s = String.fromCharCodes(fromHex('48656c6c6f21deadbe')); + var r = 'JBSWY3DPEHPK3PQ='; + expect(toBase32(s.codeUnits), equals(r)); + }); + test('[0, 0, 0] => AAAAA===', () { + var inp = [0, 0, 0]; + var out = "AAAAA==="; + expect(toBase32(inp), equals(out)); + }); + }); + }); + + group('decoding', () { + group('no padding', () { + test('"" -> ""', () { + var s = ''; + expect(fromBase32(''), equals(s.codeUnits)); + }); + test('MY -> f', () { + var s = 'f'; + expect(fromBase32('MY'), equals(s.codeUnits)); + }); + test('MZXQ -> fo', () { + var s = 'fo'; + expect(fromBase32('MZXQ'), equals(s.codeUnits)); + }); + test('MZXW6 -> foo', () { + var s = 'foo'; + expect(fromBase32('MZXW6'), equals(s.codeUnits)); + }); + test('MZXW6YQ -> foob', () { + var s = 'foob'; + expect(fromBase32('MZXW6YQ'), equals(s.codeUnits)); + }); + test('MZXW6YTB -> fooba', () { + var s = 'fooba'; + expect(fromBase32('MZXW6YTB'), equals(s.codeUnits)); + }); + test('MZXW6YTBOI -> foobar', () { + var s = 'foobar'; + expect(fromBase32('MZXW6YTBOI'), equals(s.codeUnits)); + }); + test('JBSWY3DPEHPK3PXP -> 48656c6c6f21deadbeef', () { + var decoded = fromBase32('JBSWY3DPEHPK3PXP'); + expect(toHex(decoded), equals('48656c6c6f21deadbeef')); + }); + test('JBSWY3DPEHPK3PQ -> 48656c6c6f21deadbe', () { + var decoded = fromBase32('JBSWY3DPEHPK3PQ'); + expect(toHex(decoded), equals('48656c6c6f21deadbe')); + }); + test('mzxw6ytboi -> foobar', () { + var s = 'foobar'; + expect(fromBase32('mzxw6ytboi'), equals(s.codeUnits)); + }); + test('jbswy3dpehpk3pxp -> 48656c6c6f21deadbeef', () { + var decoded = fromBase32('jbswy3dpehpk3pxp'); + expect(toHex(decoded), equals('48656c6c6f21deadbeef')); + }); + test('jbswy3dpehpk3pq -> 48656c6c6f21deadbe', () { + var decoded = fromBase32('jbswy3dpehpk3pq'); + expect(toHex(decoded), equals('48656c6c6f21deadbe')); + }); + }); + group('with padding', () { + test('MY====== -> f', () { + var s = 'MY======'; + var r = 'f'; + expect(fromBase32(s), equals(r.codeUnits)); + }); + test('MZXQ==== -> fo', () { + var s = 'MZXQ===='; + var r = 'fo'; + expect(fromBase32(s), equals(r.codeUnits)); + }); + test('MZXW6=== -> foo', () { + var s = 'MZXW6==='; + var r = 'foo'; + expect(fromBase32(s), equals(r.codeUnits)); + }); + test('MZXW6YQ= -> foob', () { + var s = 'MZXW6YQ='; + var r = 'foob'; + expect(fromBase32(s), equals(r.codeUnits)); + }); + test('MZXW6YTBOI====== -> foobar', () { + var s = 'MZXW6YTBOI======'; + var r = 'foobar'; + expect(fromBase32(s), equals(r.codeUnits)); + }); + test('JBSWY3DPEHPK3PQ= -> 48656c6c6f21deadbe', () { + var s = 'JBSWY3DPEHPK3PQ='; + var r = String.fromCharCodes(fromHex('48656c6c6f21deadbe')); + expect(fromBase32(s), equals(r.codeUnits)); + }); + test('AAAA => [0, 0, 0]', () { + var inp = [0, 0, 0]; + var out = "AAAAA==="; + expect(fromBase32(out), equals(inp)); + }); + }); + group(' with invalid chars', () { + test('"Error!"', () { + expect(() => fromBase32("Error!"), throwsFormatException); + }); + test('"-10"', () { + expect(() => fromBase32("-10"), throwsFormatException); + }); + test('"s*mething"', () { + expect(() => fromBase32("s*mething"), throwsFormatException); + }); + }); + group('with invalid length', () { + test('"1"', () { + expect(() => fromBase32("1"), throwsFormatException); + }); + test('"12"', () { + expect(() => fromBase32("12"), throwsFormatException); + }); + test('"123"', () { + expect(() => fromBase32("123"), throwsFormatException); + }); + test('"1234"', () { + expect(() => fromBase32("1234"), throwsFormatException); + }); + test('"12345"', () { + expect(() => fromBase32("12345"), throwsFormatException); + }); + test('"123456"', () { + expect(() => fromBase32("123456"), throwsFormatException); + }); + test('"1234567"', () { + expect(() => fromBase32("1234567"), throwsFormatException); + }); + test('"123456789"', () { + expect(() => fromBase32("123456789"), throwsFormatException); + }); + test('"1234567890"', () { + expect(() => fromBase32("1234567890"), throwsFormatException); + }); + test('"12345678901"', () { + expect(() => fromBase32("12345678901"), throwsFormatException); + }); + test('"123456789012"', () { + expect(() => fromBase32("123456789012"), throwsFormatException); + }); + test('"1234567890123"', () { + expect(() => fromBase32("1234567890123"), throwsFormatException); + }); + test('"12345678901234"', () { + expect(() => fromBase32("12345678901234"), throwsFormatException); + }); + test('"123456789012345"', () { + expect(() => fromBase32("123456789012345"), throwsFormatException); + }); + }); + }); + + group('compare against package: base_codecs', () { + test('encoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var hashlib = toBase32(b); + var other = base_codecs.base32RfcEncode(b); + expect(hashlib, other, reason: 'length $i'); + } + }); + test('decoding (uppercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var h = toBase32(b); + var hashlib = fromBase32(h); + var other = base_codecs.base32RfcDecode(h); + expect(hashlib, other, reason: 'length $i'); + } + }); + test('decoding (lowercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var h = toBase32(b, lower: true); + var hashlib = fromBase32(h); + var other = base_codecs.base32RfcDecode(h); + expect(hashlib, other, reason: 'length $i'); + } + }); + }); + + group('compare against package: base32', () { + test('encoding (uppercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var hashlib = toBase32(b); + var other = base32.base32.encodeString(String.fromCharCodes(b)); + expect(hashlib, other, reason: 'length $i'); + } + }); + test('encoding (lowercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var hashlib = toBase32(b, lower: true); + var other = base32.base32.encodeString(String.fromCharCodes(b), + encoding: Encoding.nonStandardRFC4648Lower); + expect(hashlib, other, reason: 'length $i'); + } + }); + test('decoding (uppercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var h = toBase32(b); + var hashlib = fromBase32(h); + var other = base32.base32.decode(h); + expect(hashlib, other, reason: 'length $i'); + } + }); + test('decoding (lowercase)', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var h = toBase32(b, lower: true); + var hashlib = fromBase32(h); + var other = base32.base32.decode( + h, + encoding: Encoding.nonStandardRFC4648Lower, + ); + expect(hashlib, other, reason: 'length $i'); + } + }); + }); + }); +} diff --git a/hashlib_codecs/test/base64_test.dart b/hashlib_codecs/test/base64_test.dart new file mode 100644 index 0000000..c5a5763 --- /dev/null +++ b/hashlib_codecs/test/base64_test.dart @@ -0,0 +1,173 @@ +import 'dart:convert' as cvt; + +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test base64', () { + test('parameter overrides', () { + var inp = [0x3, 0xF1]; + var out = "A/E="; + var npo = "A/E"; + var act = toBase64(inp); + expect(act, equals(out)); + act = toBase64( + inp, + codec: Base64Codec.standard, + ); + expect(act, equals(out)); + act = toBase64( + inp, + codec: Base64Codec.standard, + padding: false, + ); + expect(act, equals(npo)); + act = toBase64( + inp, + codec: Base64Codec.standard, + url: true, + ); + expect(act, equals(out)); + act = toBase64( + inp, + codec: Base64Codec.standard, + padding: false, + url: true, + ); + expect(act, equals(npo)); + }); + test('encoding [0, 0, 0, 0] => AAAAAA==', () { + var inp = [0, 0, 0, 0]; + var out = "AAAAAA=="; + expect(toBase64(inp), equals(out)); + }); + test('decoding AAAAAA== => [0, 0, 0, 0]', () { + var inp = [0, 0, 0, 0]; + var out = "AAAAAA=="; + expect(fromBase64(out), equals(inp)); + }); + test('encoding no padding [0, 0, 0, 0] => AAAAAA', () { + var inp = [0, 0, 0, 0]; + var out = "AAAAAA"; + var act = toBase64(inp, padding: false); + expect(act, equals(out)); + }); + test('decoding no padding AAAAAA => [0, 0, 0, 0]', () { + var inp = [0, 0, 0, 0]; + var out = "AAAAAA"; + expect(fromBase64(out), equals(inp)); + }); + test('encoding no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = cvt.base64Encode(b).replaceAll('=', ''); + var a = toBase64(b, padding: false); + expect(a, r, reason: 'length $i'); + } + }); + test('decoding no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = cvt.base64Encode(b).replaceAll('=', ''); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('encoding with padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = cvt.base64Encode(b); + expect(toBase64(b), r, reason: 'length $i'); + } + }); + test('decoding with padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = cvt.base64Encode(b); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('encoding <-> decoding no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase64(b, padding: false); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('encoding <-> decoding with padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase64(b); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('[bcrypt] encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase64(b, codec: Base64Codec.bcrypt); + var a = fromBase64(r, codec: Base64Codec.bcrypt); + expect(a, equals(b), reason: 'length $i'); + } + }); + group('decoding with invalid chars', () { + test('Hashlib!', () { + try { + fromBase64("Hashlib!"); + throw Exception('No error thrown'); + } on FormatException catch (err) { + expect(err.message, equals("Invalid character 33")); + } + }); + test('a.10', () { + try { + fromBase64("a.10"); + throw Exception('No error thrown'); + } on FormatException catch (err) { + expect(err.message, equals("Invalid character 46")); + } + }); + test('s*methings', () { + try { + fromBase64("s*methings"); + throw Exception('No error thrown'); + } on FormatException catch (err) { + expect(err.message, equals("Invalid character 42")); + } + }); + }); + test("decoding with PHC string format B64 (16 bytes)", () { + var inp = "gZiV/M1gPc22ElAH/Jh1Hw"; + var out = fromBase64(inp, padding: false); + var res = toBase64(out, padding: false); + expect(res, inp); + // String "CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno" + }); + test("decoding with PHC string format B64 (32 bytes)", () { + var inp = "CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"; + var out = fromBase64(inp, padding: false); + var res = toBase64(out, padding: false); + expect(res, inp); + }); + group('decoding with invalid length', () { + test('H', () { + expect(() => fromBase64("H"), throwsFormatException); + }); + test('Ha', () { + expect(() => fromBase64("Ha"), throwsFormatException); + }); + test('HaB', () { + expect(() => fromBase64("HaB"), throwsFormatException); + }); + test('Hashl', () { + expect(() => fromBase64("Hashl"), throwsFormatException); + }); + test('Hashli', () { + expect(() => fromBase64("Hashli"), throwsFormatException); + }); + test('Hashlib', () { + expect(() => fromBase64("Hashlib"), throwsFormatException); + }); + }); + }); +} diff --git a/hashlib_codecs/test/base64url_test.dart b/hashlib_codecs/test/base64url_test.dart new file mode 100644 index 0000000..1aee7a1 --- /dev/null +++ b/hashlib_codecs/test/base64url_test.dart @@ -0,0 +1,60 @@ +import 'dart:convert'; + +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test base64url', () { + test('encoding', () { + var b = [0, 0, 0]; + var a = toBase64(b, url: true); + expect(a, equals("AAAA")); + }); + test('encoding no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var m = base64UrlEncode(b).replaceAll('=', ''); + var a = toBase64(b, padding: false, url: true); + expect(a, equals(m), reason: 'length $i'); + } + }); + test('decoding no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = base64UrlEncode(b).replaceAll('=', ''); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('encoding with padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var m = base64UrlEncode(b); + var a = toBase64(b, url: true); + expect(a, equals(m), reason: 'length $i'); + } + }); + test('decoding with padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = base64UrlEncode(b); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('encoding <-> decoding no padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase64(b, padding: false, url: true); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + test('encoding <-> decoding with padding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toBase64(b, url: true); + expect(fromBase64(r), equals(b), reason: 'length $i'); + } + }); + }); +} diff --git a/hashlib_codecs/test/base8_test.dart b/hashlib_codecs/test/base8_test.dart new file mode 100644 index 0000000..35ceb88 --- /dev/null +++ b/hashlib_codecs/test/base8_test.dart @@ -0,0 +1,122 @@ +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test base8', () { + group('[] <=> empty string', () { + final input = []; + final output = ""; + test('encoding', () { + expect(toOctal(input), output); + }); + test('decoding', () { + expect(fromOctal(output), input); + }); + }); + group('[1] <=> 001', () { + final input = [1]; + final output = "001"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + group('[0, 1] <=> 000001', () { + final input = [0, 1]; + final output = "000001"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + group('[1, 0] <=> 000400', () { + final input = [1, 0]; + final output = "000400"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + group('[7] <=> 007', () { + final input = [7]; + final output = "007"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + group('[10] <=> 012', () { + final input = [10]; + final output = "012"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + group('[0, 10] <=> 000012', () { + final input = [0, 10]; + final output = "000012"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + group('[1, 2, 3, 4, 5, 6, 7, 8] => 0004020060200501403410', () { + var input = [1, 2, 3, 4, 5, 6, 7, 8]; + final output = "0004020060200501403410"; + test('encoding', () { + expect(toOctal(input), equals(output)); + }); + test('decoding', () { + expect(fromOctal(output), equals(input)); + }); + }); + + test('encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomBytes(i); + var r = toOctal(b); + expect(fromOctal(r), equals(b), reason: 'length $i'); + } + }); + + group('decoding edge cases', () { + test('partial message', () { + expect(fromOctal("12"), equals([10])); + }); + test('long partial message', () { + final input = '4020060200501403410'; + final output = [1, 2, 3, 4, 5, 6, 7, 8]; + expect(fromOctal(input), equals(output)); + }); + test('200000', () { + var input = '200000'; + var output = [1, 0, 0]; + expect(fromOctal(input), equals(output)); + }); + test('182', () { + expect(() => fromOctal("182"), throwsFormatException); + }); + test('-10', () { + expect(() => fromOctal("-10"), throwsFormatException); + }); + test('01a1', () { + expect(() => fromOctal("01a1"), throwsFormatException); + }); + }); + }); +} diff --git a/hashlib_codecs/test/bigint_test.dart b/hashlib_codecs/test/bigint_test.dart new file mode 100644 index 0000000..1ae04a9 --- /dev/null +++ b/hashlib_codecs/test/bigint_test.dart @@ -0,0 +1,134 @@ +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('Test BigInt', () { + test('parameter overrides', () { + var i = [0, 0, 1]; + var o = BigInt.one << 16; + var a = toBigInt(i); + expect(a, equals(o)); + a = toBigInt( + i, + codec: BigIntCodec.lsbFirst, + ); + expect(a, equals(o)); + a = toBigInt( + i, + codec: BigIntCodec.lsbFirst, + msbFirst: true, + ); + expect(a, equals(o)); + }); + test('encoding empty list to raise error for LSB first', () { + expect(() => toBigInt([]), throwsFormatException); + }); + test('decoding negative to raise error for LSB first', () { + expect(() => fromBigInt(-BigInt.two), throwsFormatException); + }); + test('encoding empty list to raise error for LSB first', () { + expect(() { + toBigInt( + [], + codec: BigIntCodec.msbFirst, + ); + }, throwsFormatException); + }); + test('decoding negative to raise error for MSB first', () { + expect(() { + fromBigInt( + -BigInt.two, + codec: BigIntCodec.msbFirst, + ); + }, throwsFormatException); + }); + test('encoding [0] => 0', () { + var inp = [0]; + var out = BigInt.zero; + expect(toBigInt(inp), equals(out)); + }); + test('encoding [0] => 0 big endian', () { + var inp = [0]; + var out = BigInt.zero; + expect(toBigInt(inp, msbFirst: true), equals(out)); + }); + test('encoding [0, 0, 0] => 0', () { + var inp = [0, 0, 0]; + var out = BigInt.zero; + expect(toBigInt(inp), equals(out)); + }); + test('encoding [0, 0, 0] => 0 big endian', () { + var inp = [0, 0, 0]; + var out = BigInt.zero; + expect(toBigInt(inp, msbFirst: true), equals(out)); + }); + test('decoding 0 => [0]', () { + var inp = [0]; + var out = BigInt.zero; + expect(fromBigInt(out), equals(inp)); + }); + test('decoding 0 => [0] big endian', () { + var inp = [0]; + var out = BigInt.zero; + expect(fromBigInt(out, msbFirst: true), equals(inp)); + }); + test('little-endian encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var inp = [...randomBytes(i), 1]; + var out = toBigInt(inp); + var out2 = fromBigInt(out); + expect(out2, equals(inp), reason: 'length $i'); + } + }); + test('encoding 32-bit big endian in MSB first order', () { + var inp = [1, 2, 3, 4]; + var out = BigInt.from(0x01020304); + expect(toBigInt(inp, msbFirst: true), equals(out)); + }); + test('encoding 32-bit big endian in LSB first order', () { + var inp = [4, 3, 2, 1]; + var out = BigInt.from(0x01020304); + expect(toBigInt(inp, msbFirst: false), equals(out)); + }); + test('decoding 32-bit big endian in MSB first order', () { + var inp = [1, 2, 3, 4]; + var out = BigInt.from(0x01020304); + expect(fromBigInt(out, msbFirst: true), equals(inp)); + }); + test('decoding 32-bit big endian in LSB first order', () { + var inp = [4, 3, 2, 1]; + var out = BigInt.from(0x01020304); + expect(fromBigInt(out, msbFirst: false), equals(inp)); + }); + test('encoding 64-bit big endian in MSB first order', () { + var inp = [1, 2, 3, 4, 5, 6, 7, 8]; + var out = BigInt.from((0x01020304 << 32) | 0x05060708); + expect(toBigInt(inp, msbFirst: true), equals(out)); + }, tags: ['vm-only']); + test('encoding 64-bit big endian in LSB first order', () { + var inp = [8, 7, 6, 5, 4, 3, 2, 1]; + var out = BigInt.from((0x01020304 << 32) | 0x05060708); + expect(toBigInt(inp, msbFirst: false), equals(out)); + }, tags: ['vm-only']); + test('decoding 64-bit big endian in MSB first order', () { + var inp = [1, 2, 3, 4, 5, 6, 7, 8]; + var out = BigInt.from((0x01020304 << 32) | 0x05060708); + expect(fromBigInt(out, msbFirst: true), equals(inp)); + }, tags: ['vm-only']); + test('decoding 64-bit big endian in LSB first order', () { + var inp = [8, 7, 6, 5, 4, 3, 2, 1]; + var out = BigInt.from((0x01020304 << 32) | 0x05060708); + expect(fromBigInt(out, msbFirst: false), equals(inp)); + }, tags: ['vm-only']); + test('big-endian encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var inp = [1, ...randomBytes(i)]; + var out = toBigInt(inp, msbFirst: true); + var out2 = fromBigInt(out, msbFirst: true); + expect(out2, equals(inp), reason: 'length $i'); + } + }); + }); +} diff --git a/hashlib_codecs/test/core/alphabet_test.dart b/hashlib_codecs/test/core/alphabet_test.dart new file mode 100644 index 0000000..a0fdb20 --- /dev/null +++ b/hashlib_codecs/test/core/alphabet_test.dart @@ -0,0 +1,172 @@ +import 'package:test/test.dart'; +import 'package:hashlib_codecs/src/core/alphabet.dart'; + +final b64codes = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + .codeUnits; + +void main() { + group('AlphabetEncoder / AlphabetDecoder', () { + test('8-bit identity alphabet without padding', () { + // bits = 8 so encoder should behave like identity before alphabet map + final encodeAlphabet = List.generate(256, (i) => i); // identity + final enc = AlphabetEncoder(bits: 8, alphabet: encodeAlphabet); + final data = List.generate(256, (i) => i); // 0..255 + final out = enc.convert(data); + expect(out, data); + // Decode back + final decodeAlphabet = + List.generate(256, (i) => i); // inverse (identity) + final dec = AlphabetDecoder(bits: 8, alphabet: decodeAlphabet); + final back = dec.convert(out); + expect(back, data); + }); + + test('5-bit encoding with padding to full byte boundary', () { + final bits = 5; + final encodeAlphabet = List.generate(32, (i) => i); // identity + const pad = 255; + final enc = + AlphabetEncoder(bits: bits, alphabet: encodeAlphabet, padding: pad); + final input = [0xAB]; // single byte + final encoded = enc.convert(input); + // Expect length padded so that length * bits is multiple of 8. + expect((encoded.length * bits) % 8, 0); + // Without padding we would have ceil(8/5)=2 symbols; padding extends to 8 symbols (like base32 style) + expect(encoded.length, 8); + // First two symbols are from data, remaining are padding + for (int i = 2; i < encoded.length; i++) { + expect(encoded[i], pad); + } + + // Build decoder inverse alphabet (identity) with padding + final decodeAlphabet = List.generate(256, (i) => i < 32 ? i : -1); + final dec = + AlphabetDecoder(bits: bits, alphabet: decodeAlphabet, padding: pad); + final decoded = dec.convert(encoded); + expect(decoded, input); + }); + + test('Decoder stops at padding', () { + final bits = 5; + const pad = 200; + final encodeAlphabet = List.generate(32, (i) => i); + final enc = + AlphabetEncoder(bits: bits, alphabet: encodeAlphabet, padding: pad); + final input = [1, 2, 3]; + final encoded = enc.convert(input); + // Manually append extra data after padding that should be ignored + final withJunk = [ + ...encoded, + pad, // an explicit early padding (should stop here) + 10, 11, 12 + ]; + final decodeAlphabet = List.generate(256, (i) => i < 32 ? i : -1); + final dec = + AlphabetDecoder(bits: bits, alphabet: decodeAlphabet, padding: pad); + final decoded = dec.convert(withJunk); + expect(decoded, input); + }); + + test('Decoder throws on invalid character (out of range)', () { + final dec = AlphabetDecoder( + bits: 5, + alphabet: List.generate(32, (i) => i), + ); + expect(() => dec.convert([40]), throwsFormatException); + }); + + test('Decoder throws on invalid character (negative mapping)', () { + // alphabet[y] < 0 triggers FormatException + final badAlphabet = List.generate(32, (i) => i == 10 ? -1 : i); + final dec = AlphabetDecoder(bits: 5, alphabet: badAlphabet); + expect(() => dec.convert([10]), throwsFormatException); + }); + + test('Base64 encode/decode (no padding)', () { + final enc = AlphabetEncoder( + bits: 6, + alphabet: b64codes, + padding: '='.codeUnitAt(0), + ); + final input = 'Man'.codeUnits; // 3 bytes -> 4 chars, no padding + final encoded = enc.convert(input); + expect(String.fromCharCodes(encoded), 'TWFu'); + + final decodeAlphabet = List.filled(256, -1); + for (var i = 0; i < b64codes.length; i++) { + decodeAlphabet[b64codes[i]] = i; + } + final dec = AlphabetDecoder( + bits: 6, + alphabet: decodeAlphabet, + padding: '='.codeUnitAt(0), + ); + final decoded = dec.convert(encoded); + expect(decoded, input); + }); + + test('Base64 encode/decode (single padding)', () { + final pad = '='.codeUnitAt(0); + final enc = AlphabetEncoder(bits: 6, alphabet: b64codes, padding: pad); + final input = 'Ma'.codeUnits; // 2 bytes -> 3 data chars + 1 pad + final encoded = enc.convert(input); + expect(String.fromCharCodes(encoded), 'TWE='); + + final decodeAlphabet = List.filled(256, -1); + for (var i = 0; i < b64codes.length; i++) { + decodeAlphabet[b64codes[i]] = i; + } + final dec = + AlphabetDecoder(bits: 6, alphabet: decodeAlphabet, padding: pad); + final decoded = dec.convert(encoded); + expect(decoded, input); + }); + + test('Base64 encode/decode (double padding)', () { + final pad = '='.codeUnitAt(0); + final enc = AlphabetEncoder(bits: 6, alphabet: b64codes, padding: pad); + final input = 'M'.codeUnits; // 1 byte -> 2 data chars + 2 pads + final encoded = enc.convert(input); + expect(String.fromCharCodes(encoded), 'TQ=='); + + final decodeAlphabet = List.filled(256, -1); + for (var i = 0; i < b64codes.length; i++) { + decodeAlphabet[b64codes[i]] = i; + } + final dec = + AlphabetDecoder(bits: 6, alphabet: decodeAlphabet, padding: pad); + final decoded = dec.convert(encoded); + expect(decoded, input); + }); + + test('Base64 decoder ignores data after padding', () { + final pad = '='.codeUnitAt(0); + final enc = AlphabetEncoder(bits: 6, alphabet: b64codes, padding: pad); + final input = 'Ma'.codeUnits; + final encoded = enc.convert(input); // TWE= + final withJunk = [...encoded, 'A'.codeUnitAt(0), 'B'.codeUnitAt(0)]; + final decodeAlphabet = List.filled(256, -1); + for (var i = 0; i < b64codes.length; i++) { + decodeAlphabet[b64codes[i]] = i; + } + final dec = + AlphabetDecoder(bits: 6, alphabet: decodeAlphabet, padding: pad); + final decoded = dec.convert(withJunk); + expect(decoded, input); + }); + + test('Base64 decoder rejects invalid character', () { + final decodeAlphabet = List.filled(256, -1); + for (var i = 0; i < b64codes.length; i++) { + decodeAlphabet[b64codes[i]] = i; + } + final dec = AlphabetDecoder( + bits: 6, + alphabet: decodeAlphabet, + padding: '='.codeUnitAt(0), + ); + expect(() => dec.convert('?'.codeUnits), throwsFormatException); + }); + }); +} diff --git a/hashlib_codecs/test/core/byte_test.dart b/hashlib_codecs/test/core/byte_test.dart new file mode 100644 index 0000000..33a6606 --- /dev/null +++ b/hashlib_codecs/test/core/byte_test.dart @@ -0,0 +1,74 @@ +import 'package:test/test.dart'; +import 'dart:typed_data'; + +// Import the library under test +import 'package:hashlib_codecs/src/core/byte.dart'; + +// Dummy concrete implementations to enable testing the abstract classes +class PassthroughByteEncoder extends ByteEncoder { + const PassthroughByteEncoder({required super.bits}); + @override + Uint8List convert(List input) => Uint8List.fromList(input); +} + +class PassthroughByteDecoder extends ByteDecoder { + const PassthroughByteDecoder({required super.bits}); + @override + Uint8List convert(List encoded) => Uint8List.fromList(encoded); +} + +void main() { + group('ByteEncoder basics', () { + for (final b in [4, 5, 6, 7, 8, 12, 16]) { + test('properties with bits=$b', () { + final enc = PassthroughByteEncoder(bits: b); + expect(enc.bits, b); + expect(enc.source, 8); + expect(enc.target, b); + }); + } + + test('convert returns a Uint8List copy', () { + final enc = PassthroughByteEncoder(bits: 8); + final input = [1, 2, 255, 0]; + final out = enc.convert(input); + expect(out, equals(input)); + expect(out, isA()); + // Ensure it is a different instance (defensive copy semantics) + input[0] = 9; + expect(out[0], isNot(9)); + }); + }); + + group('ByteDecoder basics', () { + for (final b in [3, 5, 6, 8, 10]) { + test('properties with bits=$b', () { + final dec = PassthroughByteDecoder(bits: b); + expect(dec.bits, b); + expect(dec.source, b); + expect(dec.target, 8); + }); + } + + test('convert returns a Uint8List copy', () { + final dec = PassthroughByteDecoder(bits: 6); + final input = [10, 20, 30]; + final out = dec.convert(input); + expect(out, equals(input)); + expect(out, isA()); + input[1] = 99; + expect(out[1], isNot(99)); + }); + }); + + group('Symmetry (encoder->decoder passthrough)', () { + test('round trip with identical passthrough implementations', () { + final enc = PassthroughByteEncoder(bits: 8); + final dec = PassthroughByteDecoder(bits: 8); + final original = List.generate(32, (i) => (i * 7) & 0xFF); + final mid = enc.convert(original); + final again = dec.convert(mid); + expect(again, equals(original)); + }); + }); +} diff --git a/hashlib_codecs/test/core/codec_test.dart b/hashlib_codecs/test/core/codec_test.dart new file mode 100644 index 0000000..2bf860d --- /dev/null +++ b/hashlib_codecs/test/core/codec_test.dart @@ -0,0 +1,101 @@ +import 'dart:typed_data'; + +import 'package:hashlib_codecs/src/core/codec.dart'; +import 'package:hashlib_codecs/src/core/decoder.dart'; +import 'package:hashlib_codecs/src/core/encoder.dart'; +import 'package:test/test.dart'; + +class PlusOneCodec extends IterableCodec { + const PlusOneCodec(); + + @override + Iterable encode(Iterable input) => input.map((e) => (e + 1) & 0xFF); + + @override + Iterable decode(Iterable input) => input.map((e) => (e - 1) & 0xFF); + + // Not needed for these tests. + @override + BitEncoder get encoder => throw UnimplementedError(); + + @override + BitDecoder get decoder => throw UnimplementedError(); +} + +class IdentityConverter extends HashlibConverter { + @override + final int source; + + @override + final int target; + const IdentityConverter(this.source, this.target); + + @override + Iterable convert(Iterable input) => input; +} + +void main() { + group('IterableCodec convenience methods', () { + const codec = PlusOneCodec(); + + test('encodeString increments code units', () { + final out = codec.encodeString('ABC').toList(); + expect(out, [66, 67, 68]); + }); + + test('decodeString decrements code units', () { + final out = codec.decodeString('BCD').toList(); + expect(out, [66 - 1, 67 - 1, 68 - 1]); + expect(String.fromCharCodes(out), 'ABC'); + }); + + test('round trip with unicode', () { + final s = String.fromCharCodes([104, 233, 0xD8, 0x3D, 0xDE, 0x42]); + final enc = codec.encodeString(s).toList(); + final dec = codec.decode(enc).toList(); + expect(String.fromCharCodes(dec), s); + }); + + test('encodeBuffer works', () { + final bytes = Uint8List.fromList([0, 1, 254, 255]); + final out = codec.encodeBuffer(bytes.buffer).toList(); + expect(out, [1, 2, 255, 0]); // wrapped by & 0xFF + }); + + test('decodeBuffer works', () { + final bytes = Uint8List.fromList([1, 2, 0]); + final out = codec.decodeBuffer(bytes.buffer).toList(); + expect(out, [0, 1, 255]); + }); + + test('empty inputs', () { + expect(codec.encodeString('').toList(), isEmpty); + expect(codec.decode(const []).toList(), isEmpty); + }); + }); + + group('HashlibConverter base class', () { + test('identity converter preserves data', () { + const conv = IdentityConverter(8, 8); + final input = [0, 1, 127, 255]; + final out = conv.convert(input).toList(); + expect(out, input); + }); + + test('source/target properties exposed', () { + const conv = IdentityConverter(5, 7); + expect(conv.source, 5); + expect(conv.target, 7); + }); + + test('convert iterable laziness (multiple iterations consistent)', () { + const conv = IdentityConverter(8, 8); + final input = [10, 20, 30]; + final converted = conv.convert(input); + expect(converted.toList(), [10, 20, 30]); + + input[1] = 99; + expect(converted.toList(), [10, 99, 30]); + }); + }); +} diff --git a/hashlib_codecs/test/core/decoder_test.dart b/hashlib_codecs/test/core/decoder_test.dart new file mode 100644 index 0000000..41017d3 --- /dev/null +++ b/hashlib_codecs/test/core/decoder_test.dart @@ -0,0 +1,77 @@ +import 'package:test/test.dart'; +import 'package:hashlib_codecs/src/core/decoder.dart'; + +// Minimal concrete decoders for testing: +class Bits3to8Decoder extends BitDecoder { + const Bits3to8Decoder(); + @override + int get source => 3; + @override + int get target => 8; +} + +class BadSourceDecoder extends BitDecoder { + const BadSourceDecoder(); + @override + int get source => 1; // invalid (< 2) + @override + int get target => 8; +} + +class BadTargetDecoder extends BitDecoder { + const BadTargetDecoder(); + @override + int get source => 3; + @override + int get target => 65; // invalid (> 64) +} + +void main() { + group('BitDecoder (3→8)', () { + test('packs 8 x 3-bit symbols into 3 bytes', () { + // 8 valid symbols → 24 bits → 3 bytes + final dec = const Bits3to8Decoder(); + final out = dec.convert([0, 1, 2, 3, 4, 5, 6, 7]); + expect(out, equals([5, 57, 119])); // computed packing result + }); + + test('ignores data after first invalid symbol (no partial word)', () { + // 8 valid symbols complete 3 bytes; trailing invalid symbol is ignored. + final dec = const Bits3to8Decoder(); + final out = + dec.convert([0, 1, 2, 3, 4, 5, 6, 7, 9, 0, 0]); // 9 > 7 → terminates + expect(out, equals([5, 57, 119])); + }); + + test('throws FormatException on non-zero partial word (short input)', () { + // Only 1 symbol → partial word remains → must throw. + final dec = const Bits3to8Decoder(); + expect(() => dec.convert([1]), throwsA(isA())); + }); + + test('throws FormatException when invalid appears mid-group', () { + // 5 symbols (15 bits) then invalid → leaves partial word → throw. + final dec = const Bits3to8Decoder(); + expect(() => dec.convert([0, 1, 2, 3, 4, 9, 6, 7]), + throwsA(isA())); + }); + + test('negative symbol terminates (after full group is OK)', () { + final dec = const Bits3to8Decoder(); + final out = dec.convert([0, 1, 2, 3, 4, 5, 6, 7, -1, 0, 0]); + expect(out, equals([5, 57, 119])); + }); + }); + + group('BitDecoder argument checks', () { + test('rejects invalid source bit length', () { + final dec = const BadSourceDecoder(); + expect(() => dec.convert(const []), throwsA(isA())); + }); + + test('rejects invalid target bit length', () { + final dec = const BadTargetDecoder(); + expect(() => dec.convert(const []), throwsA(isA())); + }); + }); +} diff --git a/hashlib_codecs/test/core/encoder_test.dart b/hashlib_codecs/test/core/encoder_test.dart new file mode 100644 index 0000000..369616d --- /dev/null +++ b/hashlib_codecs/test/core/encoder_test.dart @@ -0,0 +1,82 @@ +import 'package:hashlib_codecs/src/core/encoder.dart'; +import 'package:test/test.dart'; + +class Bits3to8Encoder extends BitEncoder { + const Bits3to8Encoder(); + @override + int get source => 3; + @override + int get target => 8; +} + +class BadSourceEncoder extends BitEncoder { + const BadSourceEncoder(); + @override + int get source => 1; // invalid (<2) + @override + int get target => 8; +} + +class BadTargetEncoder extends BitEncoder { + const BadTargetEncoder(); + @override + int get source => 3; + @override + int get target => 65; // invalid (>64) +} + +void main() { + group('BitEncoder (3 → 8)', () { + test('packs 8×3-bit symbols into 3 bytes (exact fit)', () { + // 8 symbols × 3 bits = 24 bits → 3 bytes + final enc = const Bits3to8Encoder(); + final out = enc.convert([0, 1, 2, 3, 4, 5, 6, 7]); + expect(out, equals([5, 57, 119])); // known-good packing + }); + + test('pads partial word with zeros (single symbol)', () { + // 3 bits → pad 5 zeros on the right → 00100000 = 32 + final enc = const Bits3to8Encoder(); + expect(enc.convert([1]), equals([32])); + }); + + test('pads partial word with zeros (two symbols)', () { + // symbols: 7 (111), 1 (001) + // accumulate: (7<<3)|1 = 57; pad with 2 zeros: 57<<2 = 228 + final enc = const Bits3to8Encoder(); + expect(enc.convert([7, 1]), equals([228])); + }); + + test('multiple full and partial groups', () { + final enc = const Bits3to8Encoder(); + // 11 symbols → 33 bits → 5 bytes (last byte padded) + final out = enc.convert([0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7]); + // Compute expected manually: + // first 8 → [5,57,119] ; remaining 3 symbols: 7,7,7 → 9 bits: + // p=(7<<6)|(7<<3)|7 = (448)|(56)|7 = 511 ; n=9 → emit one byte (511>>>1=255), n=1 + // pad remaining 1 bit with 7 zeros: (p & (1)) << 7 = 1<<7 = 128 + expect(out, equals([5, 57, 119, 255, 128])); + }); + + test('BitEncoder accepts negative symbol by masking (surprising)', () { + final enc = const Bits3to8Encoder(); + final outNeg = enc.convert([-1]); // -1 & 0x7 == 7 + final outSeven = enc.convert([7]); + expect(outNeg, equals(outSeven), + reason: + 'Negative input got masked to 3-bit value; likely unintended'); + }); + }); + + group('BitEncoder argument checks', () { + test('rejects invalid source bit length', () { + final enc = const BadSourceEncoder(); + expect(() => enc.convert(const []), throwsA(isA())); + }); + + test('rejects invalid target bit length', () { + final enc = const BadTargetEncoder(); + expect(() => enc.convert(const []), throwsA(isA())); + }); + }); +} diff --git a/hashlib_codecs/test/crypt/crypt_builder_test.dart b/hashlib_codecs/test/crypt/crypt_builder_test.dart new file mode 100644 index 0000000..94eb22c --- /dev/null +++ b/hashlib_codecs/test/crypt/crypt_builder_test.dart @@ -0,0 +1,90 @@ +import 'package:hashlib_codecs/src/base64.dart'; +import 'package:hashlib_codecs/src/codecs/crypt/crypt_builder.dart'; +import 'package:test/test.dart'; + +void main() { + group('CryptDataBuilder', () { + test('should build with minimal id', () { + final builder = CryptDataBuilder('testid'); + final data = builder.build(); + expect(data.id, 'testid'); + expect(data.version, isNull); + expect(data.salt, isNull); + expect(data.hash, isNull); + expect(data.params, isNull); + }); + + test('should set version', () { + final builder = CryptDataBuilder('algo').version('1'); + final data = builder.build(); + expect(data.version, '1'); + }); + + test('should set salt', () { + final builder = CryptDataBuilder('algo').salt('mysalt'); + final data = builder.build(); + expect(data.salt, 'mysalt'); + }); + + test('should set hash', () { + final builder = CryptDataBuilder('algo').hash('myhash'); + final data = builder.build(); + expect(data.hash, 'myhash'); + }); + + test('should set saltBytes and hashBytes', () { + final saltBytes = [1, 2, 3, 4]; + final hashBytes = [5, 6, 7, 8]; + final builder = CryptDataBuilder('algo') + ..saltBytes(saltBytes) + ..hashBytes(hashBytes); + final data = builder.build(); + expect(data.salt, toBase64(saltBytes, padding: false)); + expect(data.hash, toBase64(hashBytes, padding: false)); + }); + + test('should set params', () { + final builder = CryptDataBuilder('algo') + ..param('rounds', 1000) + ..param('mode', 'fast'); + final data = builder.build(); + expect(data.params, isNotNull); + expect(data.params!['rounds'], '1000'); + expect(data.params!['mode'], 'fast'); + }); + + test('should throw ArgumentError for invalid id', () { + expect( + () => CryptDataBuilder('INVALID_ID!').build(), throwsArgumentError); + }); + + test('should throw ArgumentError for invalid version', () { + expect(() => CryptDataBuilder('algo').version('v1').build(), + throwsArgumentError); + }); + + test('should throw ArgumentError for invalid param name', () { + final builder = CryptDataBuilder('algo').param('invalid*name', 'value'); + expect(() => builder.build(), throwsArgumentError); + }); + + test('should throw ArgumentError for invalid param value', () { + final builder = CryptDataBuilder('algo').param('valid', 'bad value!'); + expect(() => builder.build(), throwsArgumentError); + }); + + test('should allow chaining', () { + final builder = CryptDataBuilder('algo') + .version('2') + .salt('salt') + .hash('hash') + .param('p', 'v'); + final data = builder.build(); + expect(data.id, 'algo'); + expect(data.version, '2'); + expect(data.salt, 'salt'); + expect(data.hash, 'hash'); + expect(data.params!['p'], 'v'); + }); + }); +} diff --git a/hashlib_codecs/test/crypt/crypt_test.dart b/hashlib_codecs/test/crypt/crypt_test.dart new file mode 100644 index 0000000..ff80f08 --- /dev/null +++ b/hashlib_codecs/test/crypt/crypt_test.dart @@ -0,0 +1,108 @@ +import 'package:test/test.dart'; +import 'package:hashlib_codecs/src/codecs/crypt/crypt_data.dart'; + +void main() { + group('CryptData', () { + test('constructor and fields', () { + final data = CryptData( + 'argon2id', + version: '19', + salt: 'c2FsdA', // "salt" in base64 + hash: 'aGFzaA', // "hash" in base64 + params: {'m': '65536', 't': '3', 'p': '4'}, + ); + expect(data.id, 'argon2id'); + expect(data.version, '19'); + expect(data.salt, 'c2FsdA'); + expect(data.hash, 'aGFzaA'); + expect(data.params, {'m': '65536', 't': '3', 'p': '4'}); + }); + + test('saltBytes and hashBytes', () { + final data = CryptData('id', salt: 'c2FsdA', hash: 'aGFzaA'); + expect(data.saltBytes(), isA>()); + expect(data.hashBytes(), isA>()); + expect(String.fromCharCodes(data.saltBytes()!), 'salt'); + expect(String.fromCharCodes(data.hashBytes()!), 'hash'); + }); + + test('versionInt', () { + final data = CryptData('id', version: '42'); + expect(data.versionInt(), 42); + + final invalid = CryptData('id', version: 'abc'); + expect(invalid.versionInt(), null); + + final none = CryptData('id'); + expect(none.versionInt(), null); + }); + + test('hasParam, getParam, getIntParam', () { + final data = CryptData('id', params: {'x': '123', 'y': 'abc'}); + expect(data.hasParam('x'), true); + expect(data.hasParam('z'), false); + expect(data.getParam('x'), '123'); + expect(data.getParam('y'), 'abc'); + expect(data.getParam('z'), null); + expect(data.getIntParam('x'), 123); + expect(data.getIntParam('y'), null); + expect(data.getIntParam('z'), null); + }); + + test('validate passes for valid data', () { + final data = CryptData( + 'argon2id', + version: '19', + salt: 'c2FsdA', + hash: 'aGFzaA', + params: {'m': '65536', 't': '3', 'p': '4'}, + ); + expect(() => data.validate(), returnsNormally); + }); + + test('validate fails for invalid id', () { + final data = CryptData('Argon2id!'); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for invalid version', () { + final data = CryptData('id', version: 'v19'); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for invalid param key', () { + final data = CryptData('id', params: {'bad_key!': '123'}); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for reserved param key "v"', () { + final data = CryptData('id', params: {'v': '123'}); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for empty param value', () { + final data = CryptData('id', params: {'x': ''}); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for invalid param value', () { + final data = CryptData('id', params: {'x': 'bad*value'}); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for invalid salt', () { + final data = CryptData('id', salt: 'bad*salt'); + expect(() => data.validate(), throwsArgumentError); + }); + + test('validate fails for invalid hash', () { + final data = CryptData('id', hash: 'bad*hash'); + expect(() => data.validate(), throwsArgumentError); + }); + + test('builder returns CryptDataBuilder', () { + final builder = CryptData.builder('argon2id'); + expect(builder.runtimeType.toString(), contains('CryptDataBuilder')); + }); + }); +} diff --git a/hashlib_codecs/test/crypt_test.dart b/hashlib_codecs/test/crypt_test.dart new file mode 100644 index 0000000..0c3d96e --- /dev/null +++ b/hashlib_codecs/test/crypt_test.dart @@ -0,0 +1,179 @@ +import 'package:hashlib_codecs/hashlib_codecs.dart'; +import 'package:test/test.dart'; + +void expectError(Function fun, String message) { + expect(fun, throwsA(isA().having((e) => '$e', 'message', message))); +} + +void main() { + group('Modular Crypt Format', () { + group('on valid string', () { + test('including all parts', () { + var v = + r"$argon2id$v=19$m=65536,t=2,p=1$gZiV/M1gPc22ElAH/Jh1Hw$CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without version', () { + var v = + r"$argon2id$m=65536,t=2,p=1$gZiV/M1gPc22ElAH/Jh1Hw$CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without params', () { + var v = + r"$argon2id$v=19$gZiV/M1gPc22ElAH/Jh1Hw$CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without hash', () { + String v = r"$argon2id$v=19$m=65536,t=2,p=1$gZiV/M1gPc22ElAH/Jh1Hw"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without salt and hash', () { + String v = r"$argon2id$v=19$m=65536,t=2,p=1"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without version and params', () { + var v = + r"$argon2id$gZiV/M1gPc22ElAH/Jh1Hw$CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without params, salt and hash', () { + var v = r"$argon2id$v=19"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without version, params and hash', () { + var v = r"$argon2id$gZiV/M1gPc22ElAH/Jh1Hw"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + test('without version, params, salt and hash', () { + var v = r"$argon2id"; + expect(toCrypt(fromCrypt(v)), equals(v)); + }); + }); + + group('Decoder failure cases', () { + test('throws on empty string', () { + expectError( + () => fromCrypt(''), + 'FormatException: Empty string', + ); + }); + test('throws on invalid start character', () { + expectError( + () => fromCrypt('s'), + r'FormatException: Does not start with "$"', + ); + }); + + test('empty string with a single dollar sign', () { + expectError( + () => fromCrypt(r'$'), + 'Invalid argument (id): must be [a-z0-9-] and under 32 characters: ""', + ); + }); + test('id is more than 32 characters', () { + var name = List.filled(50, 'a').join(); + expectError( + () => fromCrypt('\$$name'), + 'Invalid argument (id): must be [a-z0-9-] and under 32 characters: "$name"', + ); + }); + test('id contains invalid characters', () { + expectError( + () => fromCrypt(r"$v=19"), + 'Invalid argument (id): must be [a-z0-9-] and under 32 characters: "v=19"', + ); + }); + + test('empty version', () { + expectError( + () => fromCrypt(r"$argon2id$v=sd"), + 'Invalid argument (version): must be decimal digits: "sd"', + ); + }); + test('using reserved key in parameter', () { + expectError( + () => fromCrypt(r"$argon2id$v=3$v=42"), + 'Invalid argument (params.key): reserved; use version field instead: "v"', + ); + }); + test('using reserved key in parameter', () { + expectError( + () => fromCrypt(r"$argon2id$v=3$p=3,v=42"), + 'Invalid argument (params.key): reserved; use version field instead: "v"', + ); + }); + test('empty parameter name', () { + expectError( + () => fromCrypt(r"$argon2id$=1"), + 'Invalid argument (params.key): must be [a-z0-9-] and under 32 chars: ""', + ); + }); + test('empty parameter value', () { + expectError( + () => fromCrypt(r"$argon2id$sd=,3=2"), + 'Invalid argument (params[sd]): value is empty: ""', + ); + }); + test('parameter value with invalid character', () { + expectError( + () => fromCrypt(r"$argon2id$sd=o@o,3=2"), + 'Invalid argument (params[sd]): value has invalid characters: "o@o"', + ); + }); + test('parameter without equal sign', () { + expectError( + () => fromCrypt(r"$argon2id$k,f=3$salt$hash"), + 'FormatException: Invalid parameter: "k"', + ); + }); + test('duplicate parameter keys', () { + expectError( + () => fromCrypt(r"$argon2id$k=1,k=2$salt$hash"), + 'FormatException: Duplicate parameter key: "k"', + ); + }); + test('empty parameters fields', () { + expectError( + () => fromCrypt(r"$argon2id$,$salt"), + 'FormatException: Invalid parameter: ""', + ); + }); + test('invalid character in salt value', () { + expectError( + () => fromCrypt(r"$3$v=3$p=2$p&p"), + 'Invalid argument (salt): expected base64 string without padding: "p&p"', + ); + }); + test('equal sign with salt value', () { + expectError( + () => fromCrypt(r"$3$v=3$p=2$salt="), + 'Invalid argument (salt): expected base64 string without padding: "salt="', + ); + }); + test('invalid character in hash value', () { + expectError( + () => fromCrypt(r"$2$salt$er*er"), + 'Invalid argument (hash): expected base64 string without padding: "er*er"', + ); + }); + test('equal sign with hash value', () { + expectError( + () => fromCrypt(r"$2$salt$hash="), + 'Invalid argument (hash): expected base64 string without padding: "hash="', + ); + }); + test('extra characters at the end', () { + expectError( + () => fromCrypt(r"$argon2id$salt$hash$extra"), + 'FormatException: Extra characters at the end', + ); + }); + test('extra dollar sign at the end', () { + expectError( + () => fromCrypt(r"$argon2id$salt$hash$"), + 'FormatException: Extra characters at the end', + ); + }); + }); + }); +} diff --git a/hashlib_codecs/test/utf8_test.dart b/hashlib_codecs/test/utf8_test.dart new file mode 100644 index 0000000..b9b78fa --- /dev/null +++ b/hashlib_codecs/test/utf8_test.dart @@ -0,0 +1,249 @@ +import 'dart:convert'; + +import 'package:hashlib_codecs/src/codecs/utf8.dart'; +import 'package:hashlib_codecs/src/utf8.dart'; +import 'package:test/test.dart'; + +import './utils.dart'; + +void main() { + group('utf8 test', () { + test('ππππππππ', () { + var test = r"ππππππππ"; + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('encoding <-> decoding', () { + for (int i = 0; i < 100; ++i) { + var b = randomNumbers(i, stop: 0x0010FFFF); + var test = String.fromCharCodes(b); + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual), reason: 'Encoding: #$i'); + var decoded = fromUtf8(mine); + expect(decoded, equals(test), reason: 'Decoding: #$i'); + } + }); + + test('ASCII characters', () { + var test = "Hello, World!"; + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('2-byte UTF-8 characters', () { + var test = "éüçñ"; + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('3-byte UTF-8 characters', () { + var test = "हिन्दी中文"; + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('4-byte UTF-8 characters (emoji)', () { + var test = "😀💡🦄"; + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('Maximum valid code point (0x10FFFF) encodes/decodes correctly', () { + var test = String.fromCharCodes([0x10FFFF]); + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('Boundary values for each UTF-8 range', () { + var codePoints = [0x7F, 0x80, 0x7FF, 0x800, 0xFFFF, 0x10000, 0x10FFFF]; + for (var cp in codePoints) { + var test = String.fromCharCodes([cp]); + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual), reason: 'Encoding: $cp'); + var decoded = fromUtf8(mine); + expect(decoded, equals(test), reason: 'Decoding: $cp'); + } + }); + + test('Empty string', () { + var test = ""; + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + test('Surrogate pairs are encoded/decoded correctly', () { + // Dart uses UTF-16, so surrogate pairs for emoji + var test = String.fromCharCodes([0xD83D, 0xDE00]); // 😀 + var actual = Utf8Encoder().convert(test); + var mine = toUtf8(test); + expect(mine, equals(actual)); + var decoded = fromUtf8(mine); + expect(decoded, equals(test)); + }); + + group("Encoder", () { + final encoder = UTF8Codec.standard.encoder; + + test('encoder source', () { + expect(encoder.source, 32); + }); + + test('encoder target', () { + expect(encoder.target, 8); + }); + + test('Negative code unit throws FormatException', () { + expect(() => encoder.convert([-1]), throwsFormatException); + }); + + test('encoder with unpaired low surrogate', () { + expect(() => encoder.convert([0xDC00]), throwsFormatException); + }); + + test('encoder with unpaired high surrogate', () { + expect(() => encoder.convert([0xD801]), throwsFormatException); + }); + + test('encoder with invalid surrogate pair with low value', () { + expect(() => encoder.convert([0xD805, 0xDB00]), throwsFormatException); + }); + + test('encoder with invalid surrogate pair with high value', () { + expect(() => encoder.convert([0xD805, 0xEFFF]), throwsFormatException); + }); + + test('encoder with value exceeding range', () { + expect(() => encoder.convert([0x110000]), throwsFormatException); + }); + + test('Empty input for decoder returns empty list', () { + expect(encoder.convert([]), isEmpty); + }); + }); + + group('Decoder', () { + final decoder = UTF8Codec.standard.decoder; + + test('decoder source', () { + expect(decoder.source, 8); + }); + + test('decoder target', () { + expect(decoder.target, 32); + }); + + test('Insufficient input for 2-byte sequence', () { + expect(() => decoder.convert([0xC2]), throwsFormatException); + }); + + test('Invalid continuation byte at 1 for 2-byte sequence', () { + expect(() => decoder.convert([0xC2, 0xC2]), throwsFormatException); + }); + + test('Insufficient input for 3-byte sequence', () { + expect(() => decoder.convert([0xE1, 0x80]), throwsFormatException); + }); + + test('Invalid continuation byte at 1 for 3-byte sequence', () { + expect( + () => decoder.convert([0xE1, 0x41, 0x80]), throwsFormatException); + }); + + test('Invalid continuation byte at 2 for 3-byte sequence', () { + expect( + () => decoder.convert([0xE1, 0x80, 0x41]), throwsFormatException); + }); + + test('Overlong 3-byte sequence', () { + expect( + () => decoder.convert([0xE0, 0x80, 0xAF]), throwsFormatException); + }); + + test('Invalid surrogate for 3-byte', () { + expect( + () => decoder.convert([0xED, 0xA1, 0x80]), throwsFormatException); + }); + + test('Insufficient input for 4-byte sequence', () { + expect( + () => decoder.convert([0xF0, 0x90, 0x80]), throwsFormatException); + }); + + test('Invalid 4-byte lead', () { + expect(() => decoder.convert([0xF5, 0x80, 0x80, 0x80]), + throwsFormatException); + }); + + test('Overlong 4-byte sequence', () { + expect(() => decoder.convert([0xF0, 0x8F, 0x80, 0x80]), + throwsFormatException); + }); + + test('Invalid continuation byte at 1 for 4-byte sequence', () { + expect(() => decoder.convert([0xF0, 0x41, 0x80, 0x80]), + throwsFormatException); + }); + + test('Invalid continuation byte at 2 for 4-byte sequence', () { + expect(() => decoder.convert([0xF0, 0x90, 0x41, 0x80]), + throwsFormatException); + }); + + test('Invalid continuation byte at 3 for 4-byte sequence', () { + expect(() => decoder.convert([0xF0, 0x90, 0x80, 0x41]), + throwsFormatException); + }); + + test('Above U+10FFFF', () { + expect(() => decoder.convert([0xF4, 0x90, 0x80, 0x80]), + throwsFormatException); + }); + + test('Invalid UTF-8 sequence throws FormatException', () { + // Invalid continuation byte (should start with 10xxxxxx) + var invalid = [0xC2, 0x41]; + expect(() => decoder.convert(invalid), throwsFormatException); + }); + + test('Overlong encoding is rejected', () { + // Overlong encoding for ASCII 'A' (should be 0x41, not 0xC1 0x81) + var overlong = [0xC1, 0x81]; + expect(() => decoder.convert(overlong), throwsFormatException); + }); + + test('Code points above Unicode range are rejected', () { + // 0x11FFFF is above valid Unicode range + var invalid = [0xF4, 0x90, 0x80, 0x80]; + expect(() => decoder.convert(invalid), throwsFormatException); + }); + + test('5 or more bytes', () { + expect(() => decoder.convert([0xF8]), throwsFormatException); + }); + }); + }); +} diff --git a/hashlib_codecs/test/utils.dart b/hashlib_codecs/test/utils.dart new file mode 100644 index 0000000..614cc43 --- /dev/null +++ b/hashlib_codecs/test/utils.dart @@ -0,0 +1,47 @@ +import 'dart:math'; +import 'dart:typed_data'; + +Random _generator() { + try { + return Random.secure(); + } catch (err) { + return Random(DateTime.now().millisecondsSinceEpoch); + } +} + +/// Generate a list of random numbers of size [length] +Uint8List randomNumbers( + int length, { + int start = 0, + int stop = 0xFFFFFFFF, +}) { + var random = _generator(); + var data = Uint8List(length); + for (int i = 0; i < data.length; i++) { + data[i] = random.nextInt(stop - start + 1) + start; + } + return data; +} + +/// Generate a list of random 8-bit numbers of size [length] +Uint8List randomBytes(int length) { + return randomNumbers(length, stop: 0xFF); +} + +/// Fill the [buffer] with random numbers +void fillRandom( + ByteBuffer buffer, [ + int offsetInBytes = 0, + int? lengthInBytes, +]) { + if (lengthInBytes == null) { + lengthInBytes = buffer.lengthInBytes; + } else { + lengthInBytes = min(lengthInBytes + offsetInBytes, buffer.lengthInBytes); + } + var random = _generator(); + var data = buffer.asUint8List(); + for (int i = offsetInBytes; i < lengthInBytes; i++) { + data[i] = random.nextInt(256); + } +} diff --git a/introduction_screen/LICENSE b/introduction_screen/LICENSE new file mode 100644 index 0000000..d195f29 --- /dev/null +++ b/introduction_screen/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Jean-Charles Moussé + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/introduction_screen/lib/introduction_screen.dart b/introduction_screen/lib/introduction_screen.dart new file mode 100644 index 0000000..8ad72e1 --- /dev/null +++ b/introduction_screen/lib/introduction_screen.dart @@ -0,0 +1,8 @@ +library introduction_screen; + +export '/src/introduction_screen.dart' + show IntroductionScreen, IntroductionScreenState; +export '/src/model/page_view_model.dart' show PageViewModel; +export '/src/model/page_decoration.dart' show PageDecoration; +export '/src/model/position.dart' show Position; +export 'package:dots_indicator/dots_indicator.dart' show DotsDecorator; diff --git a/introduction_screen/lib/src/helper.dart b/introduction_screen/lib/src/helper.dart new file mode 100644 index 0000000..0e6dc6a --- /dev/null +++ b/introduction_screen/lib/src/helper.dart @@ -0,0 +1,19 @@ +extension CustomList on List { + List asReversed(bool isReverse) { + return isReverse ? reversed.toList() : this; + } +} + +bool isBackgroundImageAssetPathValid(String assetPath) { + const validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']; + + bool hasValidExtension = validExtensions.any((extension) { + return assetPath.toLowerCase().endsWith('.$extension'); + }); + + if (!hasValidExtension) { + return false; + } + + return true; +} diff --git a/introduction_screen/lib/src/introduction_screen.dart b/introduction_screen/lib/src/introduction_screen.dart new file mode 100644 index 0000000..fc6f8e0 --- /dev/null +++ b/introduction_screen/lib/src/introduction_screen.dart @@ -0,0 +1,737 @@ +library introduction_screen; + +import 'dart:async'; +import 'dart:math'; + +import 'package:collection/collection.dart'; +import 'package:dots_indicator/dots_indicator.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_keyboard_visibility_temp_fork/flutter_keyboard_visibility_temp_fork.dart'; + +import '/src/helper.dart'; +import '/src/model/page_view_model.dart'; +import '/src/model/position.dart'; +import '/src/ui/intro_button.dart'; +import '/src/ui/intro_page.dart'; + +bool kDefaultCanProgressFunction(int page) { + return true; +} + +typedef CanProgress = bool Function(int page); + +class IntroductionScreen extends StatefulWidget { + /// All pages of the onboarding + final List? pages; + + /// All pages of the onboarding, as a complete widget instead of a PageViewModel + final List? rawPages; + + /// Callback when Done button is pressed + final VoidCallback? onDone; + + /// Callback when Skip button is pressed + final VoidCallback? onSkip; + + /// Callback when page change + final ValueChanged? onChange; + + /// Done button child for the pre-made TextButton + final Widget? done; + + /// Override pre-made done button. + /// You can what you want (button, text, image, ...) + final Widget Function(BuildContext context, Function()? onPressed)? + overrideDone; + + /// Skip button child for the pre-made TextButton + final Widget? skip; + + /// Override pre-made skip button. + /// You can what you want (button, text, image, ...) + final Widget Function(BuildContext context, Function() onPressed)? + overrideSkip; + + /// Next button child for the pre-made TextButton + final Widget? next; + + /// Override pre-made next button. + /// You can what you want (button, text, image, ...) + final Widget Function(BuildContext context, Function()? onPressed)? + overrideNext; + + /// Back button child for the pre-made TextButton + final Widget? back; + + /// Override pre-made back button. + /// You can what you want (button, text, image, ...) + final Widget Function(BuildContext context, Function()? onPressed)? + overrideBack; + + /// Is the Skip button should be display + /// + /// @Default `false` + final bool showSkipButton; + + /// Is the Next button should be display + /// + /// @Default `true` + final bool showNextButton; + + /// If the 'Done' button should be rendered at all the end + /// + /// @Default `true` + final bool showDoneButton; + + /// Show the bottom part of the page, that's include skip, next, done buttons + /// as well as dotsDecorator. + /// + /// @Default `true` + final bool showBottomPart; + + /// If the bottom part of the page should be displayed when the keyboard is opened + /// + /// @Default `false` + final bool hideBottomOnKeyboard; + + /// If the Back button should be display + /// + /// @Default `false` + final bool showBackButton; + + /// If the Back button should be display for the first page + /// + /// @Default `false` + final bool showFirstBackButton; + + /// If a custom Widget should be used instead of the default progress indicator + /// + /// @Default `null` + final Widget? customProgress; + + /// If the progress indicator should be display + /// + /// @Default `true` + final bool isProgress; + + /// Enable or not onTap feature on progress indicator + /// + /// @Default `true` + final bool isProgressTap; + + /// If the user is allow to change page + /// + /// @Default `false` + final bool freeze; + + /// Global background color (only visible when a page has a transparent background color) + final Color? globalBackgroundColor; + + /// Dots decorator to custom dots color, size and spacing + final DotsDecorator dotsDecorator; + + /// Decorator to customize the appearance of the progress dots container. + /// This is useful when the background image is full screen. + final Decoration? dotsContainerDecorator; + + /// Animation duration in milliseconds + /// + /// @Default `350` + final int animationDuration; + + /// Auto scroll duration in milliseconds + /// + /// @Default `null` + /// + /// @Note `null` means no auto scroll + /// + /// Once the value of `autoScrollDuration` is set, auto scroll will be activated and it will scroll to the next page automatically after the specified duration. + final int? autoScrollDuration; + + /// Defines if the autoScroll should be infinite, returning to the first page after it reaches the last one. + /// + /// @Default `false` + /// + /// it can only be `true` if `autoScrollDuration` is not `null` + final bool infiniteAutoScroll; + + /// Index of the initial page + /// + /// @Default `0` + final int initialPage; + + /// Flex ratio of the skip or back button + /// + /// @Default `1` + final int skipOrBackFlex; + + /// Flex ratio of the progress indicator + /// + /// @Default `1` + final int dotsFlex; + + /// Flex ratio of the next/done button + /// + /// @Default `1` + final int nextFlex; + + /// Type of animation between pages + /// + /// @Default `Curves.easeIn` + final Curve curve; + + /// Base style for all buttons + final ButtonStyle? baseBtnStyle; + + /// Done button style + final ButtonStyle? doneStyle; + + /// Skip button style + final ButtonStyle? skipStyle; + + /// Next button style + final ButtonStyle? nextStyle; + + /// Back button style + final ButtonStyle? backStyle; + + /// Done button semantic label + final String? doneSemantic; + + /// Skip button semantic label + final String? skipSemantic; + + /// Next button semantic label + final String? nextSemantic; + + /// Back button semantic label + final String? backSemantic; + + /// Progress indicator semantic label + final String Function(int, int)? progressSemantic; + + /// Enable or disable content resizing for bottom inset (e.g. keyboard) + /// + /// @Default `true` + final bool resizeToAvoidBottomInset; + + /// Controls position + /// + /// @Default `Position(left: 0, right: 0, bottom: 0)` + final Position controlsPosition; + + /// Margin for controls + /// + /// @Default `EdgeInsets.zero` + final EdgeInsets controlsMargin; + + /// Margin for controls + /// + /// @Default `EdgeInsets.zero` + final EdgeInsets bodyPadding; + + /// Padding for controls + /// + /// @Default `EdgeInsets.all(16.0)` + final EdgeInsets controlsPadding; + + /// A header widget to be shown on every screen + final Widget? globalHeader; + + /// A footer widget to be shown on every screen + final Widget? globalFooter; + + /// ScrollController of vertical SingleChildScrollView for every single page + final List? scrollControllers; + + /// Scroll/Axis direction of pages, can he horizontal or vertical + /// + /// @Default `Axis.horizontal` + final Axis pagesAxis; + + /// PageView scroll physics (only when freeze is set to false) + /// + /// @Default `BouncingScrollPhysics()` + final ScrollPhysics scrollPhysics; + + /// If is right to left behaviour + /// + /// @Default `false` + final bool rtl; + + /// Corresponds to PageView's parameter of the same name. + /// More details can be found + /// [here](https://api.flutter.dev/flutter/widgets/PageView/PageView.html). + /// + /// @Default `false` + final bool allowImplicitScrolling; + + /// PageView's bool safe area list. + /// the list defines if the safe area will be active on left, right, top and bottom, respectively. + /// + /// @Default `[false,false,false,false]` + final List safeAreaList; + + /// A handler to check if the user is allowed to progress to the next page. + /// If returned value is true, the page will progress to the next page, otherwise the page will not progress. + /// In order to make it work properly with TextFormField, you should place setState in the onChanged callback of the TextFormField. + /// + /// @Default `true` + /// ```dart + /// canProgress: (int page) { + /// if (page == 0 && _textFieldController1.text.isEmpty) { + /// return false; + /// } else if (page == 1 && _textFieldController2.text.isEmpty) { + /// return false; + /// } else { + /// return true; + /// } + /// } + /// ``` + final CanProgress canProgress; + + IntroductionScreen( + {Key? key, + this.pages, + this.rawPages, + this.onDone, + this.onSkip, + this.onChange, + this.done, + this.overrideDone, + this.skip, + this.overrideSkip, + this.next, + this.overrideNext, + this.back, + this.overrideBack, + this.showSkipButton = false, + this.showNextButton = true, + this.showDoneButton = true, + this.showBottomPart = true, + this.showBackButton = false, + this.showFirstBackButton = false, + this.customProgress, + this.isProgress = true, + this.hideBottomOnKeyboard = false, + this.isProgressTap = true, + this.freeze = false, + this.globalBackgroundColor, + this.dotsDecorator = const DotsDecorator(), + this.dotsContainerDecorator, + this.animationDuration = 350, + this.autoScrollDuration, + this.infiniteAutoScroll = false, + this.initialPage = 0, + this.skipOrBackFlex = 1, + this.dotsFlex = 1, + this.nextFlex = 1, + this.curve = Curves.easeIn, + this.baseBtnStyle, + this.skipStyle, + this.nextStyle, + this.doneStyle, + this.backStyle, + this.skipSemantic, + this.nextSemantic, + this.doneSemantic, + this.backSemantic, + this.progressSemantic, + this.resizeToAvoidBottomInset = true, + this.controlsPosition = const Position(left: 0, right: 0, bottom: 0), + this.controlsMargin = EdgeInsets.zero, + this.controlsPadding = const EdgeInsets.all(16.0), + this.bodyPadding = EdgeInsets.zero, + this.globalHeader, + this.globalFooter, + this.scrollControllers, + this.pagesAxis = Axis.horizontal, + this.scrollPhysics = const BouncingScrollPhysics(), + this.rtl = false, + this.allowImplicitScrolling = false, + this.canProgress = kDefaultCanProgressFunction, + this.safeAreaList = const [false, false, false, false]}) + : assert( + pages != null || rawPages != null, + "You must set either 'pages' or 'rawPages' parameter", + ), + assert( + (pages?.length ?? rawPages?.length ?? 0) > 0, + "You must provide at least one page using 'pages' or 'rawPages' parameter !", + ), + assert( + !showDoneButton || done != null || overrideDone != null, + "You must set 'done' or 'overrideDone' parameter, or set 'showDoneButton' to false", + ), + assert( + done == null || onDone != null, + "If you set 'done' parameter, you must also set 'onDone' parameter", + ), + assert( + !showSkipButton || skip != null || overrideSkip != null, + "You must set 'skip' or 'overrideSkip' parameter, or set 'showSkipButton' to false", + ), + assert( + !showNextButton || next != null || overrideNext != null, + "You must set 'next' or 'overrideNext' parameter, or set 'showNextButton' to false", + ), + assert( + !showBackButton || back != null || overrideBack != null, + "You must set 'back' or 'overrideBack' parameter, or set 'showBackButton' to false", + ), + assert( + skipOrBackFlex >= 0 && dotsFlex >= 0 && nextFlex >= 0, + 'Flex parameters must be >= 0', + ), + assert( + initialPage >= 0, + 'Initial page parameter must by a positive number, >= 0.', + ), + assert( + hideBottomOnKeyboard == isProgress || !hideBottomOnKeyboard, + 'hideBottomOnKeyboard can only be true if isProgress = true', + ), + assert( + customProgress != null && isProgress || customProgress == null, + 'customProgress can only be used if isProgress = true', + ), + assert( + (infiniteAutoScroll && autoScrollDuration != null) || + !infiniteAutoScroll, + 'infiniteAutoScroll can only be true if autoScrollDuration != null', + ), + super(key: key); + + @override + IntroductionScreenState createState() => IntroductionScreenState(); +} + +class IntroductionScreenState extends State { + late PageController _pageController; + double _currentPage = 0.0; + bool _isSkipPressed = false; + bool _isScrolling = false; + late bool _showBottom; + StreamSubscription? keyboardSubscription; + + PageController get controller => _pageController; + + @override + void initState() { + super.initState(); + final int initialPage = min(widget.initialPage, getPagesLength() - 1); + _pageController = PageController(initialPage: initialPage); + _showBottom = widget.showBottomPart; + _currentPage = initialPage.toDouble(); + _autoScroll(widget.autoScrollDuration); + if (widget.hideBottomOnKeyboard) { + final keyboardVisibilityController = KeyboardVisibilityController(); + keyboardSubscription = keyboardVisibilityController.onChange.listen( + (bool visible) { + setState(() { + _showBottom = !visible; + }); + }, + ); + } + } + + @override + void dispose() { + _pageController.dispose(); + if (keyboardSubscription != null) { + keyboardSubscription!.cancel(); + } + widget.scrollControllers?.forEach((controller) { + controller?.dispose(); + }); + super.dispose(); + } + + int getPagesLength() { + return (widget.pages ?? widget.rawPages!).length; + } + + int getCurrentPage() => _currentPage.round(); + + Future _autoScroll(int? _durationInt) async { + if (_durationInt != null) { + final Duration _autoscrollDuration = Duration(milliseconds: _durationInt); + final _animationDuration = Duration( + milliseconds: widget.animationDuration, + ); + final int pagesLength = getPagesLength() - 1; + if (widget.infiniteAutoScroll) { + while (mounted) { + await _movePage( + _autoscrollDuration, + _animationDuration, + getCurrentPage() < pagesLength, + ); + } + } else { + while (mounted && getCurrentPage() < pagesLength) { + await _movePage( + _autoscrollDuration, + _animationDuration, + true, + ); + } + } + } + } + + Future _movePage( + Duration autoscrollDuration, + Duration animationDuration, + bool forward, + ) async { + await Future.delayed(autoscrollDuration); + if (mounted && !_isSkipPressed && !_isScrolling) { + if (forward) { + await _pageController.nextPage( + duration: animationDuration, + curve: widget.curve, + ); + } else { + await _pageController.animateToPage( + 0, + duration: animationDuration, + curve: widget.curve, + ); + } + } + } + + void next() { + animateScroll(getCurrentPage() + 1); + FocusScope.of(context).unfocus(); + } + + void previous() { + animateScroll(getCurrentPage() - 1); + FocusScope.of(context).unfocus(); + } + + Future _onSkip() async { + if (widget.onSkip != null) { + widget.onSkip!(); + } else { + await skipToEnd(); + } + } + + Future skipToEnd() async { + setState(() => _isSkipPressed = true); + await animateScroll(getPagesLength() - 1); + if (mounted) { + setState(() => _isSkipPressed = false); + } + } + + Future animateScroll(int page) async { + bool isValidToProgress = widget.canProgress(getCurrentPage()); + if (isValidToProgress) { + _isScrolling = true; + await _pageController.animateToPage( + max(min(page, getPagesLength() - 1), 0), + duration: Duration(milliseconds: widget.animationDuration), + curve: widget.curve, + ); + if (mounted) { + _isScrolling = false; + } + } + } + + bool _onScroll(ScrollNotification notification) { + final metrics = notification.metrics; + if (metrics is PageMetrics && metrics.page != null) { + if (mounted) { + setState(() => _currentPage = metrics.page!); + } + } + return false; + } + + @override + Widget build(BuildContext context) { + final isLastPage = (getCurrentPage() == getPagesLength() - 1); + + Widget? leftBtn; + // show skip button when skip is enabled and back is disabled, + // or show it on the first page when back is enabled. + if (widget.showSkipButton && + ((getCurrentPage() == 0 && widget.showBackButton) || + !widget.showBackButton)) { + leftBtn = Visibility( + visible: !isLastPage && !_isSkipPressed, + maintainState: true, + // Needs to be true to maintain animation + maintainAnimation: true, + // Needs to be true to maintain size + maintainSize: true, + child: widget.overrideSkip != null + ? widget.overrideSkip!(context, _onSkip) + : IntroButton( + child: widget.skip!, + style: widget.baseBtnStyle?.merge(widget.skipStyle) ?? + widget.skipStyle, + semanticLabel: widget.skipSemantic, + onPressed: _onSkip, + ), + ); + } else if ((widget.showFirstBackButton && getCurrentPage() == 0) || + (widget.showBackButton && + getCurrentPage() > 0 && + widget.canProgress(getCurrentPage()))) { + leftBtn = widget.overrideBack != null + ? widget.overrideBack!(context, !_isScrolling ? previous : null) + : IntroButton( + child: widget.back!, + style: widget.baseBtnStyle?.merge(widget.backStyle) ?? + widget.backStyle, + semanticLabel: widget.backSemantic, + onPressed: !_isScrolling ? previous : null, + ); + } + + Widget? rightBtn; + if (isLastPage && widget.showDoneButton) { + rightBtn = widget.overrideDone != null + ? widget.overrideDone!(context, !_isScrolling ? widget.onDone : null) + : IntroButton( + child: widget.done!, + style: widget.baseBtnStyle?.merge(widget.doneStyle) ?? + widget.doneStyle, + semanticLabel: widget.doneSemantic, + onPressed: !_isScrolling ? widget.onDone : null, + ); + } else if (!isLastPage && + widget.showNextButton && + widget.canProgress(getCurrentPage())) { + rightBtn = widget.overrideNext != null + ? widget.overrideNext!(context, !_isScrolling ? next : null) + : IntroButton( + child: widget.next!, + style: widget.baseBtnStyle?.merge(widget.nextStyle) ?? + widget.nextStyle, + semanticLabel: widget.nextSemantic, + onPressed: !_isScrolling ? next : null, + ); + } + + final pages = widget.pages + ?.mapIndexed((index, page) => IntroPage( + page: page, + scrollController: + widget.scrollControllers?.elementAtOrNull(index), + )) + .toList() ?? + widget.rawPages!; + + return SafeArea( + left: widget.safeAreaList[0], + right: widget.safeAreaList[1], + top: widget.safeAreaList[2], + bottom: widget.safeAreaList[3], + child: Scaffold( + backgroundColor: widget.globalBackgroundColor, + resizeToAvoidBottomInset: widget.resizeToAvoidBottomInset, + body: Stack( + children: [ + Positioned.fill( + top: widget.bodyPadding.top, + left: widget.bodyPadding.left, + right: widget.bodyPadding.right, + bottom: widget.bodyPadding.bottom, + child: NotificationListener( + onNotification: _onScroll, + child: PageView( + reverse: widget.rtl, + scrollDirection: widget.pagesAxis, + controller: _pageController, + onPageChanged: widget.onChange, + allowImplicitScrolling: widget.allowImplicitScrolling, + physics: widget.freeze + ? const NeverScrollableScrollPhysics() + : !widget.canProgress(getCurrentPage()) + ? const NeverScrollableScrollPhysics() + : widget.scrollPhysics, + children: pages + .map((page) => NotificationListener( + onNotification: (_) => true, + child: page, + )) + .toList(), + ), + ), + ), + if (widget.globalHeader != null) + Positioned( + top: 0, + left: 0, + right: 0, + child: widget.globalHeader!, + ), + if (_showBottom) + Positioned( + left: widget.controlsPosition.left, + top: widget.controlsPosition.top, + right: widget.controlsPosition.right, + bottom: widget.controlsPosition.bottom, + child: Column( + children: [ + Container( + padding: widget.controlsPadding, + margin: widget.controlsMargin, + decoration: widget.dotsContainerDecorator, + child: Row( + children: [ + Expanded( + flex: widget.skipOrBackFlex, + child: leftBtn ?? const SizedBox(), + ), + Expanded( + flex: widget.dotsFlex, + child: Center( + child: widget.isProgress + ? widget.customProgress ?? + Semantics( + label: widget.progressSemantic?.call( + getCurrentPage() + 1, + getPagesLength()) ?? + "Page ${getCurrentPage() + 1} of ${getPagesLength()}", + excludeSemantics: true, + child: DotsIndicator( + reversed: widget.rtl, + dotsCount: getPagesLength(), + position: _currentPage.toDouble(), + decorator: widget.dotsDecorator, + onTap: widget.isProgressTap && + !widget.freeze + ? (pos) => + animateScroll(pos.toInt()) + : null, + ), + ) + : const SizedBox(), + ), + ), + Expanded( + flex: widget.nextFlex, + child: rightBtn ?? const SizedBox(), + ), + ].asReversed(widget.rtl), + ), + ), + if (widget.globalFooter != null) widget.globalFooter! + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/introduction_screen/lib/src/model/page_decoration.dart b/introduction_screen/lib/src/model/page_decoration.dart new file mode 100644 index 0000000..3070a0b --- /dev/null +++ b/introduction_screen/lib/src/model/page_decoration.dart @@ -0,0 +1,154 @@ +import 'package:flutter/material.dart'; + +class PageDecoration { + /// Background page color + final Color? pageColor; + + /// TextStyle for title + /// + /// @Default style `fontSize: 20.0, fontWeight: FontWeight.bold` + final TextStyle titleTextStyle; + + /// TextStyle for title + /// + /// @Default style `fontSize: 18.0, fontWeight: FontWeight.normal` + final TextStyle bodyTextStyle; + + /// BoxDecoration for page + final BoxDecoration? boxDecoration; + + /// Flex ratio of the image + final int imageFlex; + + /// Flex ratio of the body + final int bodyFlex; + + /// Flex ratio of the footer + final int footerFlex; + + /// FlexFit of the footer + final FlexFit footerFit; + + /// Padding of image + /// + /// @Default `EdgeInsets.only(bottom: 24.0)` + final EdgeInsets imagePadding; + + /// Margin of content (title + description + footer) + /// + /// @Default `EdgeInsets.all(16.0)` + final EdgeInsets contentMargin; + + /// Margin for page + /// + /// @Default `EdgeInsets.only(bottom: 60.0)` + final EdgeInsets? pageMargin; + + /// Padding of title + /// + /// @Default `EdgeInsets.only(top: 16.0, bottom: 24.0)` + final EdgeInsets titlePadding; + + /// Padding of body + final EdgeInsets? bodyPadding; + + /// Padding of footer + /// + /// @Default `EdgeInsets.symmetric(vertical: 24.0)` + final EdgeInsets footerPadding; + + /// Body alignment + /// + /// @Default `Alignment.topCenter` + final Alignment bodyAlignment; + + /// Image alignment + /// + /// @Default `Alignment.bottomCenter` + final Alignment imageAlignment; + + /// Layout the page using the full screen with the image behind the text. + /// + /// @Default: `false` + final bool fullScreen; + + /// Safe area of the content. Change to avoid the overlap between the dots and the content + /// + /// @Default 60 + final double safeArea; + + const PageDecoration({ + this.pageColor, + this.titleTextStyle = const TextStyle( + fontSize: 20.0, + fontWeight: FontWeight.bold, + ), + this.bodyTextStyle = const TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.normal, + ), + this.boxDecoration, + this.imageFlex = 1, + this.bodyFlex = 1, + this.footerFlex = 1, + this.footerFit = FlexFit.loose, + this.imagePadding = const EdgeInsets.only(bottom: 24.0), + this.contentMargin = const EdgeInsets.all(16.0), + this.pageMargin = const EdgeInsets.only(bottom: 60.0), + this.titlePadding = const EdgeInsets.only(top: 16.0, bottom: 24.0), + this.bodyPadding, + this.footerPadding = const EdgeInsets.symmetric(vertical: 24.0), + this.bodyAlignment = Alignment.topCenter, + this.imageAlignment = Alignment.bottomCenter, + this.fullScreen = false, + this.safeArea = 60, + }) : assert(pageColor == null || boxDecoration == null, + 'Cannot provide both a Color and a BoxDecoration\n'); + + PageDecoration copyWith({ + Color? pageColor, + TextStyle? titleTextStyle, + TextStyle? bodyTextStyle, + BoxDecoration? boxDecoration, + int? imageFlex, + int? bodyFlex, + int? footerFlex, + FlexFit? footerFit, + EdgeInsets? imagePadding, + EdgeInsets? contentMargin, + EdgeInsets? pageMargin, + EdgeInsets? titlePadding, + EdgeInsets? descriptionPadding, + EdgeInsets? footerPadding, + Alignment? bodyAlignment, + Alignment? imageAlignment, + bool? fullScreen, + double? safeArea, + }) { + assert( + pageColor == null || boxDecoration == null, + 'Cannot provide both a Color and a BoxDecoration\n', + ); + + return PageDecoration( + pageColor: pageColor ?? this.pageColor, + titleTextStyle: titleTextStyle ?? this.titleTextStyle, + bodyTextStyle: bodyTextStyle ?? this.bodyTextStyle, + boxDecoration: boxDecoration ?? this.boxDecoration, + imageFlex: imageFlex ?? this.imageFlex, + bodyFlex: bodyFlex ?? this.bodyFlex, + footerFlex: footerFlex ?? this.footerFlex, + footerFit: footerFit ?? this.footerFit, + imagePadding: imagePadding ?? this.imagePadding, + contentMargin: contentMargin ?? this.contentMargin, + pageMargin: pageMargin ?? this.pageMargin, + titlePadding: titlePadding ?? this.titlePadding, + bodyPadding: descriptionPadding ?? this.bodyPadding, + footerPadding: footerPadding ?? this.footerPadding, + bodyAlignment: bodyAlignment ?? this.bodyAlignment, + imageAlignment: imageAlignment ?? this.imageAlignment, + fullScreen: fullScreen ?? this.fullScreen, + safeArea: safeArea ?? this.safeArea, + ); + } +} diff --git a/introduction_screen/lib/src/model/page_view_model.dart b/introduction_screen/lib/src/model/page_view_model.dart new file mode 100644 index 0000000..afb4a72 --- /dev/null +++ b/introduction_screen/lib/src/model/page_view_model.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:introduction_screen/src/helper.dart'; + +import '/src/model/page_decoration.dart'; + +class PageViewModel { + /// Title of page + final String? title; + + /// Title of page + final Widget? titleWidget; + + /// Text of page (description) + final String? body; + + /// Widget content of page (description) + final Widget? bodyWidget; + + /// Image of page + /// Tips: Wrap your image with an alignment widget like Align or Center + final Widget? image; + + /// Background image of a page. + /// Spans all over the screen. + /// + /// Tips: can be used alone or as a background image together with the "image" parameter. + final String? backgroundImage; + + /// Footer widget, you can add a button for example + final Widget? footer; + + /// Page decoration + /// Contain all page customizations, like page color, text styles + final PageDecoration decoration; + + /// If widget Order is reverse - body before image + final bool reverse; + + /// Wrap content in scrollView + final bool useScrollView; + + /// Keyboard dismiss behavious for scrollView + final ScrollViewKeyboardDismissBehavior scrollViewKeyboardDismissBehavior; + + /// Use Row instead of Column when in landscape to place image next to the content. + final bool useRowInLandscape; + + PageViewModel({ + this.title, + this.titleWidget, + this.body, + this.bodyWidget, + this.image, + this.backgroundImage, + this.footer, + this.reverse = false, + this.decoration = const PageDecoration(), + this.useScrollView = true, + this.scrollViewKeyboardDismissBehavior = + ScrollViewKeyboardDismissBehavior.manual, + this.useRowInLandscape = false, + }) : assert( + title != null || titleWidget != null, + "You must provide either title (String) or titleWidget (Widget).", + ), + assert( + (title == null) != (titleWidget == null), + "You can not provide both title and titleWidget.", + ), + assert( + body != null || bodyWidget != null, + "You must provide either body (String) or bodyWidget (Widget).", + ), + assert( + (body == null) != (bodyWidget == null), + "You can not provide both body and bodyWidget.", + ), + assert( + backgroundImage == null || + isBackgroundImageAssetPathValid(backgroundImage), + "You must provide a valid image asset path"); +} diff --git a/introduction_screen/lib/src/model/position.dart b/introduction_screen/lib/src/model/position.dart new file mode 100644 index 0000000..3ad14f7 --- /dev/null +++ b/introduction_screen/lib/src/model/position.dart @@ -0,0 +1,10 @@ +class Position { + final double? left; + final double? right; + final double? top; + final double? bottom; + + const Position({this.left, this.right, this.top, this.bottom}); + + const Position.fromLTRB(this.left, this.top, this.right, this.bottom); +} diff --git a/introduction_screen/lib/src/ui/footer_content.dart b/introduction_screen/lib/src/ui/footer_content.dart new file mode 100644 index 0000000..f530a89 --- /dev/null +++ b/introduction_screen/lib/src/ui/footer_content.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import '/introduction_screen.dart'; + +class FooterContent extends StatelessWidget { + final PageViewModel page; + final bool isFullScreen; + + const FooterContent({Key? key, required this.page, this.isFullScreen = false}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: page.decoration.contentMargin, + decoration: isFullScreen + ? page.decoration.boxDecoration ?? + BoxDecoration( + color: page.decoration.pageColor, + borderRadius: BorderRadius.circular(8.0), + ) + : null, + child: Padding( + padding: page.decoration.footerPadding, + child: page.footer, + ), + ); + } +} diff --git a/introduction_screen/lib/src/ui/intro_button.dart b/introduction_screen/lib/src/ui/intro_button.dart new file mode 100644 index 0000000..759b82b --- /dev/null +++ b/introduction_screen/lib/src/ui/intro_button.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; + +class IntroButton extends StatelessWidget { + final Widget child; + final VoidCallback? onPressed; + final ButtonStyle? style; + final String? semanticLabel; + + const IntroButton({ + Key? key, + required this.child, + this.onPressed, + this.style, + this.semanticLabel, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final defaultStyle = TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ); + + return MergeSemantics( + child: Semantics( + label: semanticLabel, + button: true, + child: TextButton( + onPressed: onPressed, + child: child, + style: style?.merge(defaultStyle) ?? defaultStyle, + ), + ), + ); + } +} diff --git a/introduction_screen/lib/src/ui/intro_content.dart b/introduction_screen/lib/src/ui/intro_content.dart new file mode 100644 index 0000000..6a9e6b4 --- /dev/null +++ b/introduction_screen/lib/src/ui/intro_content.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +import '/introduction_screen.dart'; + +class IntroContent extends StatelessWidget { + final PageViewModel page; + final bool isFullScreen; + + const IntroContent({Key? key, required this.page, this.isFullScreen = false}) + : super(key: key); + + Widget _buildWidget(Widget? widget, String? text, TextStyle style) { + return widget ?? Text(text!, style: style, textAlign: TextAlign.center); + } + + @override + Widget build(BuildContext context) { + return Container( + margin: page.decoration.contentMargin, + decoration: isFullScreen + ? page.decoration.boxDecoration ?? + BoxDecoration( + color: page.decoration.pageColor, + borderRadius: BorderRadius.circular(8.0), + ) + : null, + child: Column( + children: [ + Padding( + padding: page.decoration.titlePadding, + child: _buildWidget( + page.titleWidget, + page.title, + page.decoration.titleTextStyle, + ), + ), + Container( + padding: page.decoration.bodyPadding, + child: _buildWidget( + page.bodyWidget, + page.body, + page.decoration.bodyTextStyle, + ), + ), + ], + ), + ); + } +} diff --git a/introduction_screen/lib/src/ui/intro_page.dart b/introduction_screen/lib/src/ui/intro_page.dart new file mode 100644 index 0000000..6b226e1 --- /dev/null +++ b/introduction_screen/lib/src/ui/intro_page.dart @@ -0,0 +1,144 @@ +import 'package:flutter/material.dart'; + +import '/src/helper.dart'; +import '/src/model/page_view_model.dart'; +import '/src/ui/intro_content.dart'; + +class IntroPage extends StatefulWidget { + final PageViewModel page; + final ScrollController? scrollController; + + const IntroPage({ + Key? key, + required this.page, + this.scrollController, + }) : super(key: key); + + @override + _IntroPageState createState() => _IntroPageState(); +} + +class _IntroPageState extends State + with AutomaticKeepAliveClientMixin { + @override + bool get wantKeepAlive => true; + + Widget _buildStack() { + final PageViewModel page = widget.page; + final content = IntroContent(page: page, isFullScreen: true); + + return Stack( + children: [ + if (page.backgroundImage != null) + Image.asset( + page.backgroundImage!, + fit: BoxFit.cover, + height: double.infinity, + width: double.infinity, + alignment: Alignment.center, + ), + if (page.image != null) page.image!, + Positioned.fill( + child: Column( + children: [ + ...[ + Spacer(flex: page.decoration.imageFlex), + Expanded( + flex: page.decoration.bodyFlex, + child: Align( + alignment: page.decoration.bodyAlignment, + child: page.useScrollView + ? SingleChildScrollView( + controller: widget.scrollController, + physics: const BouncingScrollPhysics(), + keyboardDismissBehavior: + page.scrollViewKeyboardDismissBehavior, + child: content, + ) + : content, + ), + ), + ].asReversed(page.reverse), + if (page.footer != null) + Flexible( + child: page.footer!, + flex: page.decoration.footerFlex, + fit: page.decoration.footerFit, + ), + SafeArea( + top: false, + child: SizedBox( + height: page.decoration.safeArea, + ), + ), + ], + ), + ), + ], + ); + } + + Widget _buildFlex(context) { + final orientation = MediaQuery.of(context).orientation; + final PageViewModel page = widget.page; + + return Container( + color: page.decoration.pageColor, + decoration: page.decoration.boxDecoration, + margin: page.decoration.pageMargin, + child: Flex( + direction: + page.useRowInLandscape && orientation == Orientation.landscape + ? Axis.horizontal + : Axis.vertical, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ...[ + if (page.image != null) + Expanded( + flex: page.decoration.imageFlex, + child: Align( + alignment: page.decoration.imageAlignment, + child: Padding( + padding: page.decoration.imagePadding, + child: page.image, + ), + ), + ), + Expanded( + flex: page.decoration.bodyFlex, + child: Align( + alignment: page.decoration.bodyAlignment, + child: page.useScrollView + ? SingleChildScrollView( + controller: widget.scrollController, + physics: const BouncingScrollPhysics(), + child: IntroContent(page: page), + ) + : IntroContent(page: page), + ), + ), + ].asReversed(page.reverse), + if (page.footer != null) + Flexible( + child: page.footer!, + flex: page.decoration.footerFlex, + fit: page.decoration.footerFit, + ), + SizedBox(height: page.decoration.safeArea) + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + super.build(context); + + if (widget.page.decoration.fullScreen || + widget.page.backgroundImage != null) { + return _buildStack(); + } + return _buildFlex(context); + } +} diff --git a/introduction_screen/lib/testable_widget.dart b/introduction_screen/lib/testable_widget.dart new file mode 100644 index 0000000..599d6d3 --- /dev/null +++ b/introduction_screen/lib/testable_widget.dart @@ -0,0 +1,7 @@ +import 'package:flutter/material.dart'; + +Widget testableWidget({required Widget child}) { + return MaterialApp( + home: Scaffold(body: child), + ); +} diff --git a/introduction_screen/pubspec.yaml b/introduction_screen/pubspec.yaml new file mode 100644 index 0000000..33e1187 --- /dev/null +++ b/introduction_screen/pubspec.yaml @@ -0,0 +1,20 @@ +name: introduction_screen +description: Introduction/Onboarding package for flutter app with some customizations possibilities +version: 4.0.0 +repository: https://github.com/pyozer/introduction_screen +issue_tracker: https://github.com/pyozer/introduction_screen/issues + +environment: + sdk: ">=2.17.0 <4.0.0" + +dependencies: + flutter: + sdk: flutter + + collection: ^1.18.0 + dots_indicator: ^4.0.1 + flutter_keyboard_visibility_temp_fork: ^0.1.5 + +dev_dependencies: + flutter_test: + sdk: flutter diff --git a/introduction_screen/test/src/helper_test.dart b/introduction_screen/test/src/helper_test.dart new file mode 100644 index 0000000..158fda1 --- /dev/null +++ b/introduction_screen/test/src/helper_test.dart @@ -0,0 +1,17 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:introduction_screen/src/helper.dart'; + +void main() { + // Global variables + final originalList = [1, 2, 3, 4, 5]; + + group('CustomList', () { + test('asReversed() reverses list when isReverse is true', () { + expect(originalList.asReversed(true), [5, 4, 3, 2, 1]); + }); + + test('asReversed() returns original list when isReverse is false', () { + expect(originalList.asReversed(false), [1, 2, 3, 4, 5]); + }); + }); +} diff --git a/introduction_screen/test/src/introduction_screen_test.dart b/introduction_screen/test/src/introduction_screen_test.dart new file mode 100644 index 0000000..e614f9e --- /dev/null +++ b/introduction_screen/test/src/introduction_screen_test.dart @@ -0,0 +1,234 @@ +import 'package:dots_indicator/dots_indicator.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:introduction_screen/introduction_screen.dart'; + +void main() { + // Helper function to create the IntroductionScreen widget + Widget createIntroductionScreen({ + required List pages, + VoidCallback? onDone, + VoidCallback? onSkip, + bool showSkipButton = false, + bool showDoneButton = false, + bool showNextButton = true, + bool showBackButton = false, + int initialPage = 0, + int? autoScrollDuration, + }) { + return MaterialApp( + home: IntroductionScreen( + pages: pages, + done: showDoneButton ? Text("Done") : null, + onDone: onDone, + skip: showSkipButton ? Text("Skip") : null, + onSkip: onSkip, + next: showNextButton ? Text("Next") : null, + showSkipButton: showSkipButton, + showDoneButton: showDoneButton, + showBackButton: showBackButton, + back: showBackButton ? Text("Back") : null, + showNextButton: showNextButton, + autoScrollDuration: autoScrollDuration, + initialPage: initialPage, + ), + ); + } + + group('IntroductionScreen Widget Tests', () { + testWidgets('Initial page is rendered and buttons are displayed', + (tester) async { + // Act + final pages = [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + ]; + + await tester.pumpWidget( + createIntroductionScreen(pages: pages, showSkipButton: true)); + + // Assert + expect(find.text('Page 1'), findsOneWidget); + expect(find.text('Skip'), findsOneWidget); + expect(find.text('Next'), findsOneWidget); + }); + + testWidgets('Next button advances the page', (tester) async { + // Arrange + final pages = [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + ]; + await tester.pumpWidget(createIntroductionScreen(pages: pages)); + + // Act + await tester.tap(find.text('Next')); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('Page 2'), findsOneWidget); + }); + + testWidgets('Back button goes back to the previous page', (tester) async { + // Arrange + await tester.pumpWidget(createIntroductionScreen( + pages: [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + ], + showBackButton: true, + initialPage: 1, + )); + + expect(find.text('Page 1'), findsNothing); + expect(find.text('Page 2'), findsOneWidget); + + // Act + await tester.tap(find.text('Back')); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('Page 1'), findsOneWidget); + expect(find.text('Page 2'), findsNothing); + }); + + testWidgets('Skip button triggers onSkip callback', (tester) async { + // Arrange + var skipTapped = false; + + final pages = [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + PageViewModel(title: 'Page 3', body: 'Introduction 3'), + ]; + + await tester.pumpWidget( + createIntroductionScreen( + pages: pages, + onSkip: () => skipTapped = true, + showSkipButton: true, + ), + ); + + // Act + await tester.tap(find.text('Skip')); + await tester.pumpAndSettle(); + + // Assert + expect(skipTapped, isTrue); + }); + + testWidgets('Skip to end navigates to the last page', + (WidgetTester tester) async { + // Arrange + final pages = [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + PageViewModel(title: 'Page 3', body: 'Introduction 3'), + ]; + await tester.pumpWidget( + createIntroductionScreen( + pages: pages, + showSkipButton: true, + ), + ); + + // Initially, the first page should be visible + expect(find.text('Page 1'), findsOneWidget); + + // Tap the skip button to skip to the end + await tester.tap(find.text('Skip')); + await tester.pumpAndSettle(); + + // Verify that we are now on the last page + expect(find.text('Page 3'), findsOneWidget); + }); + + testWidgets('Done button triggers onDone callback', (tester) async { + // Arrange + var doneTapped = false; + final pages = [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + ]; + + await tester.pumpWidget( + createIntroductionScreen( + pages: pages, + onDone: () => doneTapped = true, + showDoneButton: true, + ), + ); + + // Act + // Navigate to the last page + await tester.tap(find.text('Next')); + await tester.pumpAndSettle(); + await tester.tap(find.text('Done')); + await tester.pumpAndSettle(); + + // Assert + expect(doneTapped, isTrue); + }); + + testWidgets('Progress indicator updates with page change', (tester) async { + // Arrange + final pages = [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + ]; + + await tester.pumpWidget(createIntroductionScreen(pages: pages)); + + // Assert initial page + expect(find.byType(DotsIndicator), findsOneWidget); + DotsIndicator indicator = tester.widget(find.byType(DotsIndicator)); + expect(indicator.position, 0.0); + + // Act - Move to the next page + await tester.tap(find.text('Next')); + await tester.pumpAndSettle(); + + // Assert updated indicator + indicator = tester.widget(find.byType(DotsIndicator)); + expect(indicator.position, 1.0); + }); + }); + + testWidgets('Auto-scroll advances one page at a time', + (WidgetTester tester) async { + // Arrange + const autoScrollDuration = 2000; + await tester.pumpWidget(createIntroductionScreen( + pages: [ + PageViewModel(title: 'Page 1', body: 'Introduction 1'), + PageViewModel(title: 'Page 2', body: 'Introduction 2'), + PageViewModel(title: 'Page 3', body: 'Introduction 3'), + ], + autoScrollDuration: autoScrollDuration, + )); + + // Should still be at page 1 after 100 ms + await tester.pump(Duration(milliseconds: 100)); + await tester.pumpAndSettle(); + expect(find.text('Page 1'), findsOneWidget); + expect(find.text('Page 2'), findsNothing); + expect(find.text('Page 3'), findsNothing); + + // Wait for first auto-scroll, should be on page 2 now + await tester.pump(Duration(milliseconds: autoScrollDuration + 100)); + await tester.pumpAndSettle(); + + expect(find.text('Page 1'), findsNothing); + expect(find.text('Page 2'), findsOneWidget); + expect(find.text('Page 3'), findsNothing); + + // Wait for second auto-scroll, should be on page 3 now + await tester.pump(Duration(milliseconds: autoScrollDuration)); + await tester.pumpAndSettle(); + + expect(find.text('Page 1'), findsNothing); + expect(find.text('Page 2'), findsNothing); + expect(find.text('Page 3'), findsOneWidget); + }); +} diff --git a/introduction_screen/test/src/model/page_decoration_test.dart b/introduction_screen/test/src/model/page_decoration_test.dart new file mode 100644 index 0000000..1b93ba0 --- /dev/null +++ b/introduction_screen/test/src/model/page_decoration_test.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:introduction_screen/src/model/page_decoration.dart'; + +void main() { + group('PageDecoration', () { + test('default constructor initializes with correct default values', () { + final decoration = PageDecoration(); + + expect(decoration.pageColor, isNull); + expect(decoration.titleTextStyle.fontSize, 20.0); + expect(decoration.titleTextStyle.fontWeight, FontWeight.bold); + expect(decoration.bodyTextStyle.fontSize, 18.0); + expect(decoration.bodyTextStyle.fontWeight, FontWeight.normal); + expect(decoration.imageFlex, 1); + expect(decoration.bodyFlex, 1); + expect(decoration.footerFlex, 1); + expect(decoration.footerFit, FlexFit.loose); + expect(decoration.imagePadding, EdgeInsets.only(bottom: 24.0)); + expect(decoration.contentMargin, EdgeInsets.all(16.0)); + expect(decoration.pageMargin, EdgeInsets.only(bottom: 60.0)); + expect(decoration.titlePadding, EdgeInsets.only(top: 16.0, bottom: 24.0)); + expect(decoration.footerPadding, EdgeInsets.symmetric(vertical: 24.0)); + expect(decoration.bodyAlignment, Alignment.topCenter); + expect(decoration.imageAlignment, Alignment.bottomCenter); + expect(decoration.fullScreen, isFalse); + expect(decoration.safeArea, 60); + }); + + test('cannot provide both pageColor and boxDecoration', () { + expect( + () => PageDecoration( + pageColor: Colors.white, boxDecoration: BoxDecoration()), + throwsA(isA()), + ); + }); + + test('copyWith returns a new instance with updated values', () { + final decoration = PageDecoration( + pageColor: Colors.white, + titleTextStyle: TextStyle(fontSize: 22.0), + ); + + final newDecoration = decoration.copyWith( + bodyTextStyle: TextStyle(fontSize: 20.0), + footerFlex: 2, + ); + + expect(newDecoration.pageColor, Colors.white); + expect(newDecoration.titleTextStyle.fontSize, 22.0); + expect(newDecoration.bodyTextStyle.fontSize, 20.0); + expect(newDecoration.footerFlex, 2); + expect(newDecoration.imageFlex, + decoration.imageFlex); // Should remain the same + }); + + test('copyWith does not modify original instance', () { + final decoration = PageDecoration(pageColor: Colors.white); + decoration.copyWith(titleTextStyle: TextStyle(fontSize: 22.0)); + + expect(decoration.titleTextStyle.fontSize, + 20.0); // Original should remain unchanged + }); + }); +} diff --git a/introduction_screen/test/src/model/position_test.dart b/introduction_screen/test/src/model/position_test.dart new file mode 100644 index 0000000..bc24b24 --- /dev/null +++ b/introduction_screen/test/src/model/position_test.dart @@ -0,0 +1,43 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:introduction_screen/src/model/position.dart'; + +void main() { + group('Position', () { + test('default constructor initializes with null values', () { + final position = Position(); + + expect(position.left, isNull); + expect(position.right, isNull); + expect(position.top, isNull); + expect(position.bottom, isNull); + }); + + test('constructor initializes with specified values', () { + final position = + Position(left: 10.0, top: 20.0, right: 30.0, bottom: 40.0); + + expect(position.left, 10.0); + expect(position.top, 20.0); + expect(position.right, 30.0); + expect(position.bottom, 40.0); + }); + + test('fromLTRB constructor initializes with specified values', () { + final position = Position.fromLTRB(10.0, 20.0, 30.0, 40.0); + + expect(position.left, 10.0); + expect(position.top, 20.0); + expect(position.right, 30.0); + expect(position.bottom, 40.0); + }); + + test('fromLTRB constructor with null values', () { + final position = Position.fromLTRB(null, null, null, null); + + expect(position.left, isNull); + expect(position.top, isNull); + expect(position.right, isNull); + expect(position.bottom, isNull); + }); + }); +} diff --git a/introduction_screen/test/widget/intro_ui_test.dart b/introduction_screen/test/widget/intro_ui_test.dart new file mode 100644 index 0000000..efef456 --- /dev/null +++ b/introduction_screen/test/widget/intro_ui_test.dart @@ -0,0 +1,161 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:introduction_screen/introduction_screen.dart'; +import 'package:introduction_screen/src/ui/intro_page.dart'; +import 'package:introduction_screen/testable_widget.dart'; + +import 'package:introduction_screen/src/ui/intro_button.dart'; +import 'package:introduction_screen/src/ui/intro_content.dart'; + +void main() { + group("Intro UI widget tests", () { + final titleFinder = find.text('Test Title'); + final bodyFinder = find.text('Test Body'); + final footerFinder = find.text('Test Footer'); + + // Helper function to create the IntroPage widget + Widget createIntroPage( + {bool isFullScreen = false, + PageDecoration? pageDecoration, + bool useScrollView = true, + Widget? image}) { + return IntroPage( + page: PageViewModel( + title: 'Test Title', + body: 'Test Body', + image: image, + footer: const Text('Test Footer'), + decoration: pageDecoration ?? const PageDecoration(), + useScrollView: useScrollView, + ), + ); + } + + testWidgets('IntroButton has text', (tester) async { + await tester.pumpWidget(testableWidget( + child: IntroButton(child: const Text('Test Text')), + )); + + final textFinder = find.text('Test Text'); + expect(textFinder, findsOneWidget); + }); + + testWidgets('IntroContent is rendered', (tester) async { + await tester.pumpWidget(testableWidget( + child: IntroContent( + page: PageViewModel( + title: 'Test Title', + body: 'Test Body', + footer: const Text('Test Footer'), + ), + ), + )); + + expect(titleFinder, findsOneWidget); + expect(bodyFinder, findsOneWidget); + expect(footerFinder, findsNothing); + }); + + testWidgets('Intro Content renders full screen with decoration', + (WidgetTester tester) async { + await tester.pumpWidget(testableWidget( + child: IntroContent( + page: PageViewModel( + title: 'Test Title', + body: 'Test Body', + footer: const Text('Test Footer'), + ), + isFullScreen: true), + )); + + // Find the IntroContent widget + final introContentFinder = find.byType(IntroContent); + expect(introContentFinder, findsOneWidget); + + // Check if the container has a decoration when isFullScreen is true + final introContent = tester.widget(introContentFinder); + expect(introContent.isFullScreen, isTrue); + }); + + testWidgets('renders IntroPage with full screen stack', + (WidgetTester tester) async { + await tester.pumpWidget( + testableWidget( + child: createIntroPage( + pageDecoration: PageDecoration(fullScreen: true), + ), + ), + ); + + // Check that the IntroContent is rendered in a Stack + expect(find.byType(Stack), findsWidgets); + expect(find.byType(IntroContent), findsOneWidget); + expect(find.byType(SingleChildScrollView), + findsOneWidget); // No scroll view if useScrollView is false + }); + + testWidgets('renders IntroPage with Flex layout', + (WidgetTester tester) async { + await tester.pumpWidget( + testableWidget(child: createIntroPage(useScrollView: false))); + + // Check that the IntroContent is rendered in a Flex layout + expect(find.byType(Flex), findsOneWidget); + expect(find.byType(IntroContent), findsOneWidget); + expect(find.byType(SingleChildScrollView), + findsNothing); // No scroll view if useScrollView is false + }); + + testWidgets('renders IntroPage with image when provided', + (WidgetTester tester) async { + // Create a mock image widget + final mockImage = Container( + color: Colors.blue, + width: 100, + height: 100, + ); + + await tester.pumpWidget(testableWidget( + child: createIntroPage( + useScrollView: false, + image: mockImage, // Set the page image to the mock image + ), + )); + + // Check that the image is rendered + expect(find.byWidget(mockImage), findsOneWidget); + }); + + testWidgets('IntroButton custom styles override default styles', + (tester) async { + // Create a custom style with a different border radius + final customStyle = TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(20.0), // Different from default 8.0 + ), + backgroundColor: Colors.blue, // Additional property to verify + ); + + await tester.pumpWidget(testableWidget( + child: IntroButton( + child: const Text('Test Text'), + style: customStyle, + ), + )); + + // Find the TextButton + final button = tester.widget(find.byType(TextButton)); + + // Get the shape from the button's style + final shape = button.style?.shape?.resolve({}); + expect(shape, isA()); + final borderRadius = (shape as RoundedRectangleBorder).borderRadius; + expect(borderRadius, BorderRadius.circular(20.0)); + + // Verify the background color was also applied + final backgroundColor = button.style?.backgroundColor?.resolve({}); + expect(backgroundColor, Colors.blue); + }); + }); +} diff --git a/libsignal_protocol_dart/LICENSE b/libsignal_protocol_dart/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/libsignal_protocol_dart/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/libsignal_protocol_dart/lib/libsignal_protocol_dart.dart b/libsignal_protocol_dart/lib/libsignal_protocol_dart.dart new file mode 100644 index 0000000..c720691 --- /dev/null +++ b/libsignal_protocol_dart/lib/libsignal_protocol_dart.dart @@ -0,0 +1,52 @@ +export 'src/decryption_callback.dart'; +export 'src/duplicate_message_exception.dart'; +export 'src/ecc/curve.dart'; +export 'src/ecc/djb_ec_private_key.dart'; +export 'src/ecc/djb_ec_public_key.dart'; +export 'src/ecc/ec_key_pair.dart'; +export 'src/ecc/ec_private_key.dart'; +export 'src/ecc/ec_public_key.dart'; +export 'src/fingerprint/displayable_fingerprint.dart'; +export 'src/fingerprint/fingerprint.dart'; +export 'src/fingerprint/numeric_fingerprint_generator.dart'; +export 'src/fingerprint/scannable_fingerprint.dart'; +export 'src/groups/group_cipher.dart'; +export 'src/groups/group_session_builder.dart'; +export 'src/groups/sender_key_name.dart'; +export 'src/groups/state/in_memory_sender_key_store.dart'; +export 'src/groups/state/sender_key_record.dart'; +export 'src/groups/state/sender_key_store.dart'; +export 'src/identity_key.dart'; +export 'src/identity_key_pair.dart'; +export 'src/invalid_key_exception.dart'; +export 'src/invalid_key_id_exception.dart'; +export 'src/legacy_message_exception.dart'; +export 'src/no_session_exception.dart'; +export 'src/protocol/ciphertext_message.dart'; +export 'src/protocol/pre_key_signal_message.dart'; +export 'src/protocol/sender_key_distribution_message_wrapper.dart'; +export 'src/protocol/sender_key_message.dart'; +export 'src/protocol/signal_message.dart'; +export 'src/provisioning_cipher.dart'; +export 'src/session_builder.dart'; +export 'src/session_cipher.dart'; +export 'src/signal_protocol_address.dart'; +export 'src/state/identity_key_store.dart'; +export 'src/state/impl/in_memory_identity_key_store.dart'; +export 'src/state/impl/in_memory_pre_key_store.dart'; +export 'src/state/impl/in_memory_session_store.dart'; +export 'src/state/impl/in_memory_signal_protocol_store.dart'; +export 'src/state/impl/in_memory_signed_pre_key_store.dart'; +export 'src/state/pre_key_bundle.dart'; +export 'src/state/pre_key_record.dart'; +export 'src/state/pre_key_store.dart'; +export 'src/state/session_record.dart'; +export 'src/state/session_state.dart'; +export 'src/state/session_store.dart'; +export 'src/state/signal_protocol_store.dart'; +export 'src/state/signed_pre_key_record.dart'; +export 'src/state/signed_pre_key_store.dart'; +export 'src/untrusted_identity_exception.dart'; +export 'src/util/byte_util.dart'; +export 'src/util/key_helper.dart'; +export 'src/util/medium.dart'; diff --git a/libsignal_protocol_dart/lib/src/cbc.dart b/libsignal_protocol_dart/lib/src/cbc.dart new file mode 100644 index 0000000..c77e4b2 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/cbc.dart @@ -0,0 +1,40 @@ +import 'dart:typed_data'; + +import 'package:pointycastle/export.dart'; + +Uint8List aesCbcEncrypt(Uint8List key, Uint8List iv, Uint8List plaintext) { + final paddedPlaintext = pad(plaintext, 16); + final cbc = CBCBlockCipher(AESEngine()) + ..init(true, ParametersWithIV(KeyParameter(key), iv)); // true=encrypt + + final cipherText = Uint8List(paddedPlaintext.length); // allocate space + var offset = 0; + while (offset < paddedPlaintext.length) { + offset += cbc.processBlock(paddedPlaintext, offset, cipherText, offset); + } + assert(offset == paddedPlaintext.length); + return cipherText; +} + +Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) { + final cbc = CBCBlockCipher(AESEngine()) + ..init(false, ParametersWithIV(KeyParameter(key), iv)); // false=decrypt + + final paddedPlainText = Uint8List(cipherText.length); // allocate space + var offset = 0; + while (offset < cipherText.length) { + offset += cbc.processBlock(cipherText, offset, paddedPlainText, offset); + } + assert(offset == cipherText.length); + return unpad(paddedPlainText); +} + +Uint8List pad(Uint8List bytes, int blockSize) { + final padLength = blockSize - (bytes.length % blockSize); + final padded = Uint8List(bytes.length + padLength)..setAll(0, bytes); + PKCS7Padding().addPadding(padded, bytes.length); + return padded; +} + +Uint8List unpad(Uint8List padded) => + padded.sublist(0, padded.length - PKCS7Padding().padCount(padded)); diff --git a/libsignal_protocol_dart/lib/src/decryption_callback.dart b/libsignal_protocol_dart/lib/src/decryption_callback.dart new file mode 100644 index 0000000..d56013f --- /dev/null +++ b/libsignal_protocol_dart/lib/src/decryption_callback.dart @@ -0,0 +1,3 @@ +import 'dart:typed_data'; + +typedef DecryptionCallback = void Function(Uint8List plaintext); diff --git a/libsignal_protocol_dart/lib/src/devices/device_consistency_code_generator.dart b/libsignal_protocol_dart/lib/src/devices/device_consistency_code_generator.dart new file mode 100644 index 0000000..29a6699 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/devices/device_consistency_code_generator.dart @@ -0,0 +1,41 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; +import '../util/byte_util.dart'; + +import 'device_consistency_commitment.dart'; +import 'device_consistency_signature.dart'; + +class DeviceConsistencyCodeGenerator { + static const int codeVersion = 0; + + static String generateFor(DeviceConsistencyCommitment commitment, + List signatures) { + final sortedSignatures = [...signatures] + ..sort(compareSignature); + + final output = AccumulatorSink(); + final input = sha512.startChunkedConversion(output) + ..add(ByteUtil.shortToByteArray(codeVersion)) + ..add(commitment.serialized); + + for (final signature in sortedSignatures) { + input.add(signature.vrfOutput); + } + input.close(); + final hash = output.events.single.bytes; + final digits = getEncodedChunk(Uint8List.fromList(hash), 0) + + getEncodedChunk(Uint8List.fromList(hash), 5); + return digits.substring(0, 6); + } + + static String getEncodedChunk(Uint8List hash, int offset) { + final chunk = ByteUtil.byteArray5ToLong(hash, offset).remainder(100000); + return chunk.toString().padLeft(5, '0'); + } +} + +int compareSignature( + DeviceConsistencySignature a, DeviceConsistencySignature b) => + ByteUtil.compare(a.vrfOutput, b.vrfOutput); diff --git a/libsignal_protocol_dart/lib/src/devices/device_consistency_commitment.dart b/libsignal_protocol_dart/lib/src/devices/device_consistency_commitment.dart new file mode 100644 index 0000000..1e0dc92 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/devices/device_consistency_commitment.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; + +import '../identity_key.dart'; +import '../util/byte_util.dart'; + +class DeviceConsistencyCommitment { + DeviceConsistencyCommitment(int generation, List identityKeys) { + final sortedIdentityKeys = [...identityKeys]..sort((a, b) => + ByteUtil.compare(a.publicKey.serialize(), b.publicKey.serialize())); + + final output = AccumulatorSink(); + final input = sha512.startChunkedConversion(output) + ..add(utf8.encode(version)) + ..add(ByteUtil.intToByteArray(generation)); + + for (final commitment in sortedIdentityKeys) { + input.add(commitment.publicKey.serialize()); + } + input.close(); + + _generation = generation; + _serialized = Uint8List.fromList(output.events.single.bytes); + } + + static const String version = 'DeviceConsistencyCommitment_V0'; + + late int _generation; + late Uint8List _serialized; + + Uint8List get serialized => _serialized; + + int get generation => _generation; +} diff --git a/libsignal_protocol_dart/lib/src/devices/device_consistency_signature.dart b/libsignal_protocol_dart/lib/src/devices/device_consistency_signature.dart new file mode 100644 index 0000000..965e4f2 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/devices/device_consistency_signature.dart @@ -0,0 +1,12 @@ +import 'dart:typed_data'; + +class DeviceConsistencySignature { + DeviceConsistencySignature(this._signature, this._vrfOutput); + + final Uint8List _signature; + final Uint8List _vrfOutput; + + Uint8List get vrfOutput => _vrfOutput; + + Uint8List get signature => _signature; +} diff --git a/libsignal_protocol_dart/lib/src/duplicate_message_exception.dart b/libsignal_protocol_dart/lib/src/duplicate_message_exception.dart new file mode 100644 index 0000000..662e7a6 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/duplicate_message_exception.dart @@ -0,0 +1,7 @@ +class DuplicateMessageException implements Exception { + DuplicateMessageException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'DuplicateMessageException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/ecc/curve.dart b/libsignal_protocol_dart/lib/src/ecc/curve.dart new file mode 100644 index 0000000..4deda5e --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/curve.dart @@ -0,0 +1,187 @@ +import 'dart:typed_data'; + +import 'package:x25519/x25519.dart' as x25519; + +import '../invalid_key_exception.dart'; +import '../util/key_helper.dart'; +import 'djb_ec_private_key.dart'; +import 'djb_ec_public_key.dart'; +import 'ec_key_pair.dart'; +import 'ec_private_key.dart'; +import 'ec_public_key.dart'; +import 'ed25519.dart'; + +typedef KeyPairGenerator = GeneratedKeyPair Function(); +typedef AgreementCalculator = Uint8List Function(Uint8List, Uint8List); + +class GeneratedKeyPair { + GeneratedKeyPair(this.private, this.public); + + final Uint8List private; + final Uint8List public; +} + +class Curve { + static const int djbType = 0x05; + + static KeyPairGenerator? keyPairGenerator; + static AgreementCalculator? agreementCalculator; + + static ECKeyPair generateKeyPair() { + final x25519.KeyPair keyPair; + final generator = keyPairGenerator; + if (generator != null) { + final kp = generator(); + keyPair = x25519.KeyPair(privateKey: kp.private, publicKey: kp.public); + } else { + keyPair = x25519.generateKeyPair(); + } + + return ECKeyPair(DjbECPublicKey(Uint8List.fromList(keyPair.publicKey)), + DjbECPrivateKey(Uint8List.fromList(keyPair.privateKey))); + } + + static ECKeyPair generateKeyPairFromPrivate(List private) { + if (private.length != 32) { + throw InvalidKeyException( + 'Invalid private key length: ${private.length}'); + } + final public = List.filled(32, 0); + + private[0] &= 248; + private[31] &= 127; + private[31] |= 64; + + x25519.ScalarBaseMult(public, private); + + return ECKeyPair(DjbECPublicKey(Uint8List.fromList(public)), + DjbECPrivateKey(Uint8List.fromList(private))); + } + + static ECPublicKey decodePointList(List bytes, int offset) => + decodePoint(Uint8List.fromList(bytes), offset); + + static ECPublicKey decodePoint(Uint8List bytes, int offset) { + if (bytes.length - offset < 1) { + throw InvalidKeyException('No key type identifier'); + } + + final type = bytes[offset] & 0xFF; + + switch (type) { + case Curve.djbType: + if (bytes.length - offset < 33) { + throw InvalidKeyException('Bad key length: ${bytes.length}'); + } + + final keyBytes = Uint8List(32); + arraycopy(bytes, offset + 1, keyBytes, 0, keyBytes.length); + return DjbECPublicKey(keyBytes); + default: + throw InvalidKeyException('Bad key type: $type'); + } + } + + static void arraycopy( + List src, int srcPos, List dest, int destPos, int length) { + dest.setRange(destPos, length + destPos, src, srcPos); + } + + static ECPrivateKey decodePrivatePoint(Uint8List bytes) => + DjbECPrivateKey(bytes); + + static Uint8List calculateAgreement( + ECPublicKey? publicKey, ECPrivateKey? privateKey) { + if (publicKey == null) { + throw Exception('publicKey value is null'); + } + + if (privateKey == null) { + throw Exception('privateKey value is null'); + } + if (publicKey.getType() != privateKey.getType()) { + throw Exception('Public and private keys must be of the same type!'); + } + + if (publicKey.getType() == djbType) { + final calculator = agreementCalculator; + if (calculator != null) { + return calculator( + (privateKey as DjbECPrivateKey).privateKey, + (publicKey as DjbECPublicKey).publicKey, + ); + } + + final secretKey = x25519.X25519( + List.from((privateKey as DjbECPrivateKey).privateKey), + List.from((publicKey as DjbECPublicKey).publicKey), + ); + return secretKey; + } else { + throw Exception('Unknown type: ${publicKey.getType()}'); + } + } + + static bool verifySignature( + ECPublicKey? signingKey, Uint8List? message, Uint8List? signature) { + if (signingKey == null || message == null || signature == null) { + throw InvalidKeyException('Values must not be null'); + } + + if (signingKey.getType() == djbType) { + if (signature.length != 64) { + return false; + } + + final publicKey = (signingKey as DjbECPublicKey).publicKey; + return verifySig(publicKey, message, signature); + } else { + throw InvalidKeyException( + 'Unknown Signing Key type${signingKey.getType()}'); + } + } + + static Uint8List calculateSignature( + ECPrivateKey? signingKey, Uint8List? message) { + if (signingKey == null || message == null) { + throw Exception('Values must not be null'); + } + + if (signingKey.getType() == djbType) { + final privateKey = signingKey.serialize(); + final random = generateRandomBytes(); + + return sign(privateKey, message, random); + } else { + throw Exception('Unknown Signing Key type${signingKey.getType()}'); + } + } + + static Uint8List calculateVrfSignature( + ECPrivateKey? signingKey, Uint8List? message) { + if (signingKey == null || message == null) { + throw Exception('Values must not be null'); + } + + if (signingKey.getType() == djbType) { + // TODO + } else { + throw Exception('Unknown Signing Key type${signingKey.getType()}'); + } + return Uint8List(0); + } + + static Uint8List verifyVrfSignature( + ECPublicKey? signingKey, Uint8List? message, Uint8List? signature) { + if (signingKey == null || message == null || signature == null) { + throw Exception('Values must not be null'); + } + + if (signingKey.getType() == djbType) { + // TODO + } else { + throw Exception('Unknown Signing Key type${signingKey.getType()}'); + } + return Uint8List(0); + } +} diff --git a/libsignal_protocol_dart/lib/src/ecc/djb_ec_private_key.dart b/libsignal_protocol_dart/lib/src/ecc/djb_ec_private_key.dart new file mode 100644 index 0000000..c5ae4f9 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/djb_ec_private_key.dart @@ -0,0 +1,18 @@ +import 'dart:typed_data'; + +import 'curve.dart'; +import 'ec_private_key.dart'; + +class DjbECPrivateKey extends ECPrivateKey { + DjbECPrivateKey(this._privateKey); + + final Uint8List _privateKey; + + @override + int getType() => Curve.djbType; + + @override + Uint8List serialize() => privateKey; + + Uint8List get privateKey => _privateKey; +} diff --git a/libsignal_protocol_dart/lib/src/ecc/djb_ec_public_key.dart b/libsignal_protocol_dart/lib/src/ecc/djb_ec_public_key.dart new file mode 100644 index 0000000..e86e3bd --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/djb_ec_public_key.dart @@ -0,0 +1,44 @@ +import 'dart:typed_data'; + +import 'package:meta/meta.dart'; + +import '../eq.dart'; + +import 'curve.dart'; +import 'ec_public_key.dart'; + +@immutable +class DjbECPublicKey extends ECPublicKey { + DjbECPublicKey(this._publicKey); + + final Uint8List _publicKey; + + @override + int getType() => Curve.djbType; + + @override + Uint8List serialize() => Uint8List.fromList([Curve.djbType] + _publicKey); + + Uint8List get publicKey => _publicKey; + + @override + int compareTo(ECPublicKey another) => decodeBigInt(publicKey) + .compareTo(decodeBigInt((another as DjbECPublicKey).publicKey)); + + @override + bool operator ==(Object other) { + if (other is! DjbECPublicKey) return false; + return eq(_publicKey, other._publicKey); + } + + @override + int get hashCode => _publicKey.hashCode; + + BigInt decodeBigInt(List bytes) { + var result = BigInt.from(0); + for (var i = 0; i < bytes.length; i++) { + result += BigInt.from(bytes[bytes.length - i - 1]) << (8 * i); + } + return result; + } +} diff --git a/libsignal_protocol_dart/lib/src/ecc/ec_key_pair.dart b/libsignal_protocol_dart/lib/src/ecc/ec_key_pair.dart new file mode 100644 index 0000000..56b1a71 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/ec_key_pair.dart @@ -0,0 +1,13 @@ +import 'ec_private_key.dart'; +import 'ec_public_key.dart'; + +class ECKeyPair { + ECKeyPair(this._publicKey, this._privateKey); + + final ECPublicKey _publicKey; + final ECPrivateKey _privateKey; + + ECPublicKey get publicKey => _publicKey; + + ECPrivateKey get privateKey => _privateKey; +} diff --git a/libsignal_protocol_dart/lib/src/ecc/ec_private_key.dart b/libsignal_protocol_dart/lib/src/ecc/ec_private_key.dart new file mode 100644 index 0000000..4fe18c5 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/ec_private_key.dart @@ -0,0 +1,6 @@ +import 'dart:typed_data'; + +abstract class ECPrivateKey { + Uint8List serialize(); + int getType(); +} diff --git a/libsignal_protocol_dart/lib/src/ecc/ec_public_key.dart b/libsignal_protocol_dart/lib/src/ecc/ec_public_key.dart new file mode 100644 index 0000000..21e5886 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/ec_public_key.dart @@ -0,0 +1,8 @@ +import 'dart:typed_data'; + +abstract class ECPublicKey implements Comparable { + static const int keySize = 33; + + Uint8List serialize(); + int getType(); +} diff --git a/libsignal_protocol_dart/lib/src/ecc/ed25519.dart b/libsignal_protocol_dart/lib/src/ecc/ed25519.dart new file mode 100644 index 0000000..3bb28e8 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ecc/ed25519.dart @@ -0,0 +1,117 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart' as cr; +import 'package:ed25519_edwards/ed25519_edwards.dart'; +// ignore: implementation_imports +import 'package:ed25519_edwards/src/edwards25519.dart'; + +import 'curve.dart'; + +Uint8List sign(Uint8List privateKey, Uint8List message, Uint8List random) { + final A = ExtendedGroupElement(); + final publicKey = Uint8List(32); + GeScalarMultBase(A, privateKey); + A.ToBytes(publicKey); + + // Calculate r + final diversifier = Uint8List.fromList([ + 0xFE, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF + ]); + + var output = AccumulatorSink(); + cr.sha512.startChunkedConversion(output) + ..add(diversifier) + ..add(privateKey) + ..add(message) + ..add(random) + ..close(); + final r = output.events.single.bytes; + + final rReduced = Uint8List(32); + ScReduce(rReduced, Uint8List.fromList(r)); + final R = ExtendedGroupElement(); + GeScalarMultBase(R, rReduced); + + final encodedR = Uint8List(32); + R.ToBytes(encodedR); + + output = AccumulatorSink(); + cr.sha512.startChunkedConversion(output) + ..add(encodedR) + ..add(publicKey) + ..add(message) + ..close(); + final hramDigest = output.events.single.bytes; + + final hramDigestReduced = Uint8List(32); + ScReduce(hramDigestReduced, Uint8List.fromList(hramDigest)); + + final s = Uint8List(32); + ScMulAdd(s, hramDigestReduced, privateKey, rReduced); + + final signature = Uint8List(64); + Curve.arraycopy(encodedR, 0, signature, 0, 32); + Curve.arraycopy(s, 0, signature, 32, 32); + signature[63] |= publicKey[31] & 0x80; + + return signature; +} + +// verify checks whether the message has a valid signature. +bool verifySig(Uint8List publicKey, Uint8List message, Uint8List signature) { + publicKey[31] &= 0x7F; + + final edY = FieldElement(); + final one = FieldElement(); + final montX = FieldElement(); + final montXMinusOne = FieldElement(); + final montXPlusOne = FieldElement(); + FeFromBytes(montX, publicKey); + FeOne(one); + FeSub(montXMinusOne, montX, one); + FeAdd(montXPlusOne, montX, one); + FeInvert(montXPlusOne, montXPlusOne); + FeMul(edY, montXMinusOne, montXPlusOne); + + // ignore: non_constant_identifier_names + final A_ed = Uint8List(32); + FeToBytes(A_ed, edY); + + A_ed[31] |= signature[63] & 0x80; + signature[63] &= 0x7F; + +// bool verify(PublicKey publicKey, Uint8List message, Uint8List sig) { + return verify(PublicKey(A_ed.toList()), message, signature); +} diff --git a/libsignal_protocol_dart/lib/src/entry.dart b/libsignal_protocol_dart/lib/src/entry.dart new file mode 100644 index 0000000..5085002 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/entry.dart @@ -0,0 +1,6 @@ +import 'dart:collection'; + +base class Entry extends LinkedListEntry> { + Entry(this.value); + T value; +} diff --git a/libsignal_protocol_dart/lib/src/eq.dart b/libsignal_protocol_dart/lib/src/eq.dart new file mode 100644 index 0000000..4c2dde6 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/eq.dart @@ -0,0 +1,4 @@ +import 'package:collection/collection.dart'; + +bool eq(List? list1, List? list2) => + ListEquality().equals(list1, list2); diff --git a/libsignal_protocol_dart/lib/src/fingerprint/displayable_fingerprint.dart b/libsignal_protocol_dart/lib/src/fingerprint/displayable_fingerprint.dart new file mode 100644 index 0000000..d92f44c --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/displayable_fingerprint.dart @@ -0,0 +1,35 @@ +import 'dart:typed_data'; + +import '../util/byte_util.dart'; + +class DisplayableFingerprint { + DisplayableFingerprint( + Uint8List localFingerprint, Uint8List remoteFingerprint) { + localFingerprintNumbers = _getDisplayStringFor(localFingerprint); + remoteFingerprintNumbers = _getDisplayStringFor(remoteFingerprint); + } + + late String localFingerprintNumbers; + late String remoteFingerprintNumbers; + + String getDisplayText() { + if (localFingerprintNumbers.compareTo(remoteFingerprintNumbers) <= 0) { + return localFingerprintNumbers + remoteFingerprintNumbers; + } else { + return remoteFingerprintNumbers + localFingerprintNumbers; + } + } + + String _getDisplayStringFor(Uint8List fingerprint) => + _getEncodedChunk(fingerprint, 0) + + _getEncodedChunk(fingerprint, 5) + + _getEncodedChunk(fingerprint, 10) + + _getEncodedChunk(fingerprint, 15) + + _getEncodedChunk(fingerprint, 20) + + _getEncodedChunk(fingerprint, 25); + + String _getEncodedChunk(Uint8List hash, int offset) { + final chunk = ByteUtil.byteArray5ToLong(hash, offset).remainder(100000); + return chunk.toString().padLeft(5, '0'); + } +} diff --git a/libsignal_protocol_dart/lib/src/fingerprint/fingerprint.dart b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint.dart new file mode 100644 index 0000000..5b3f433 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint.dart @@ -0,0 +1,12 @@ +import 'displayable_fingerprint.dart'; +import 'scannable_fingerprint.dart'; + +class Fingerprint { + Fingerprint(this._displayableFingerprint, this._scannableFingerprint); + + final DisplayableFingerprint _displayableFingerprint; + final ScannableFingerprint _scannableFingerprint; + + DisplayableFingerprint get displayableFingerprint => _displayableFingerprint; + ScannableFingerprint get scannableFingerprint => _scannableFingerprint; +} diff --git a/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_generator.dart b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_generator.dart new file mode 100644 index 0000000..0f98086 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_generator.dart @@ -0,0 +1,20 @@ +import 'dart:typed_data'; + +import '../identity_key.dart'; +import 'fingerprint.dart'; + +abstract class FingerprintGenerator { + Fingerprint createFor( + int version, + Uint8List localStableIdentifier, + IdentityKey localIdentityKey, + Uint8List remoteStableIdentifier, + IdentityKey remoteIdentityKey); + + Fingerprint createListFor( + int version, + Uint8List localStableIdentifier, + List localIdentityKey, + Uint8List remoteStableIdentifier, + List remoteIdentityKey); +} diff --git a/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_parsing_exception.dart b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_parsing_exception.dart new file mode 100644 index 0000000..61f5807 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_parsing_exception.dart @@ -0,0 +1,8 @@ +class FingerprintParsingException implements Exception { + FingerprintParsingException(this._message); + + final Exception _message; + + @override + String toString() => 'FingerprintParsingException - $_message'; +} diff --git a/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_version_mismatch_exception.dart b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_version_mismatch_exception.dart new file mode 100644 index 0000000..a0aa351 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/fingerprint_version_mismatch_exception.dart @@ -0,0 +1,8 @@ +class FingerprintVersionMismatchException implements Exception { + FingerprintVersionMismatchException(this._theirVersion, this._ourVersion); + + // ignore: unused_field + final int _theirVersion; + // ignore: unused_field + final int _ourVersion; +} diff --git a/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart b/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart new file mode 100644 index 0000000..99becee --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart @@ -0,0 +1,79 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; + +import '../identity_key.dart'; +import '../util/byte_util.dart'; +import '../util/identity_key_comparator.dart'; +import 'displayable_fingerprint.dart'; +import 'fingerprint.dart'; +import 'fingerprint_generator.dart'; +import 'scannable_fingerprint.dart'; + +class NumericFingerprintGenerator implements FingerprintGenerator { + NumericFingerprintGenerator(this._iterations); + + static const int fingerprintVersion = 0; + + final int _iterations; + + @override + Fingerprint createFor( + int version, + Uint8List localStableIdentifier, + IdentityKey localIdentityKey, + Uint8List remoteStableIdentifier, + IdentityKey remoteIdentityKey) => + createListFor(version, localStableIdentifier, [localIdentityKey], + remoteStableIdentifier, [remoteIdentityKey]); + + @override + Fingerprint createListFor( + int version, + Uint8List localStableIdentifier, + List localIdentityKey, + Uint8List remoteStableIdentifier, + List remoteIdentityKey) { + final localFingerprint = + _getFingerprint(_iterations, localStableIdentifier, localIdentityKey); + final remoteFingerprint = + _getFingerprint(_iterations, remoteStableIdentifier, remoteIdentityKey); + final displayableFingerprint = + DisplayableFingerprint(localFingerprint, remoteFingerprint); + final scannableFingerprint = + ScannableFingerprint(version, localFingerprint, remoteFingerprint); + return Fingerprint(displayableFingerprint, scannableFingerprint); + } + + Uint8List _getFingerprint(int iterations, Uint8List stableIdentifier, + List unsortedIdentityKeys) { + final publicKey = _getLogicalKeyBytes(unsortedIdentityKeys); + var hash = ByteUtil.combine([ + ByteUtil.shortToByteArray(fingerprintVersion), + publicKey, + stableIdentifier + ]); + for (var i = 0; i < iterations; i++) { + final output = AccumulatorSink(); + sha512.startChunkedConversion(output) + ..add(hash) + ..add(publicKey) + ..close(); + hash = Uint8List.fromList(output.events.single.bytes); + } + + return hash; + } + + Uint8List _getLogicalKeyBytes(List identityKeys) { + final sortedIdentityKeys = [...identityKeys]..sort(identityKeyComparator); + + final keys = []; + sortedIdentityKeys.forEach((IdentityKey key) { + final publicKeyBytes = key.publicKey.serialize(); + keys.addAll(publicKeyBytes.toList()); + }); + return Uint8List.fromList(keys); + } +} diff --git a/libsignal_protocol_dart/lib/src/fingerprint/scannable_fingerprint.dart b/libsignal_protocol_dart/lib/src/fingerprint/scannable_fingerprint.dart new file mode 100644 index 0000000..b84c99d --- /dev/null +++ b/libsignal_protocol_dart/lib/src/fingerprint/scannable_fingerprint.dart @@ -0,0 +1,49 @@ +import 'dart:typed_data'; + +import 'package:crypto/crypto.dart'; +import 'package:protobuf/protobuf.dart'; + +import '../state/fingerprint_protocol.pb.dart'; +import '../util/byte_util.dart'; +import 'fingerprint_parsing_exception.dart'; +import 'fingerprint_version_mismatch_exception.dart'; + +class ScannableFingerprint { + ScannableFingerprint(int version, Uint8List localFingerprintData, + Uint8List remoteFingerprintData) { + final localFingerprint = LogicalFingerprint.create() + ..content = ByteUtil.trim(localFingerprintData, 32); + + final remoteFingerprint = LogicalFingerprint.create() + ..content = ByteUtil.trim(remoteFingerprintData, 32); + + _version = version; + _fingerprints = CombinedFingerprints.create() + ..version = version + ..localFingerprint = localFingerprint + ..remoteFingerprint = remoteFingerprint; + } + + late int _version; + late CombinedFingerprints _fingerprints; + + bool compareTo(Uint8List scannedFingerprintData) { + try { + final scanned = CombinedFingerprints.fromBuffer(scannedFingerprintData); + if (!scanned.hasRemoteFingerprint() || + !scanned.hasLocalFingerprint() || + !scanned.hasVersion() || + scanned.version != _version) { + throw FingerprintVersionMismatchException(scanned.version, _version); + } + return Digest(_fingerprints.localFingerprint.content) == + Digest(scanned.remoteFingerprint.content) && + Digest(_fingerprints.remoteFingerprint.content) == + Digest(scanned.localFingerprint.content); + } on InvalidProtocolBufferException catch (e) { + throw FingerprintParsingException(e); + } + } + + Uint8List get fingerprints => _fingerprints.writeToBuffer(); +} diff --git a/libsignal_protocol_dart/lib/src/groups/group_cipher.dart b/libsignal_protocol_dart/lib/src/groups/group_cipher.dart new file mode 100644 index 0000000..f2b7c38 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/group_cipher.dart @@ -0,0 +1,98 @@ +import 'dart:typed_data'; + +import '../cbc.dart'; +import '../decryption_callback.dart'; +import '../duplicate_message_exception.dart'; +import '../invalid_key_exception.dart'; +import '../invalid_key_id_exception.dart'; +import '../invalid_message_exception.dart'; +import '../no_session_exception.dart'; +import '../protocol/sender_key_message.dart'; +import 'ratchet/sender_message_key.dart'; +import 'sender_key_name.dart'; +import 'state/sender_key_state.dart'; +import 'state/sender_key_store.dart'; + +class GroupCipher { + GroupCipher(this._senderKeyStore, this._senderKeyId); + + final SenderKeyStore _senderKeyStore; + final SenderKeyName _senderKeyId; + + Future encrypt(Uint8List paddedPlaintext) async { + try { + final record = await _senderKeyStore.loadSenderKey(_senderKeyId); + final senderKeyState = record.getSenderKeyState(); + final senderKey = senderKeyState.senderChainKey.senderMessageKey; + final ciphertext = + aesCbcEncrypt(senderKey.cipherKey, senderKey.iv, paddedPlaintext); + final senderKeyMessage = SenderKeyMessage(senderKeyState.keyId, + senderKey.iteration, ciphertext, senderKeyState.signingKeyPrivate); + final nextSenderChainKey = senderKeyState.senderChainKey.next; + senderKeyState.senderChainKey = nextSenderChainKey; + await _senderKeyStore.storeSenderKey(_senderKeyId, record); + return senderKeyMessage.serialize(); + } on InvalidKeyIdException catch (e) { + throw NoSessionException(e.detailMessage); + } + } + + Future decrypt(Uint8List senderKeyMessageBytes) async => + decryptWithCallback(senderKeyMessageBytes, () {}()); + + Future decryptWithCallback( + Uint8List senderKeyMessageBytes, DecryptionCallback? callback) async { + try { + final record = await _senderKeyStore.loadSenderKey(_senderKeyId); + if (record.isEmpty) { + throw NoSessionException( + 'No group sender key for: ${_senderKeyId.serialize()}'); + } + + final senderKeyMessage = + SenderKeyMessage.fromSerialized(senderKeyMessageBytes); + final senderKeyState = + record.getSenderKeyStateById(senderKeyMessage.keyId); + senderKeyMessage.verifySignature(senderKeyState.signingKeyPublic); + final senderKey = + getSenderKey(senderKeyState, senderKeyMessage.iteration); + final plaintext = aesCbcDecrypt( + senderKey.cipherKey, senderKey.iv, senderKeyMessage.ciphertext); + + if (callback != null) { + callback(plaintext); + } + + await _senderKeyStore.storeSenderKey(_senderKeyId, record); + return plaintext; + } on InvalidKeyIdException catch (e) { + throw InvalidMessageException(e.detailMessage); + } on InvalidKeyException catch (e) { + throw InvalidMessageException(e.detailMessage); + } + } + + SenderMessageKey getSenderKey(SenderKeyState senderKeyState, int iteration) { + var senderChainKey = senderKeyState.senderChainKey; + if (senderChainKey.iteration > iteration) { + if (senderKeyState.hasSenderMessageKey(iteration)) { + return senderKeyState.removeSenderMessageKey(iteration)!; + } else { + throw DuplicateMessageException('Received message with old counter: ' + '${senderChainKey.iteration} , $iteration'); + } + } + + if (iteration - senderChainKey.iteration > 2000) { + throw InvalidMessageException('Over 2000 messages into the future!'); + } + + while (senderChainKey.iteration < iteration) { + senderKeyState.addSenderMessageKey(senderChainKey.senderMessageKey); + senderChainKey = senderChainKey.next; + } + + senderKeyState.senderChainKey = senderChainKey.next; + return senderChainKey.senderMessageKey; + } +} diff --git a/libsignal_protocol_dart/lib/src/groups/group_session_builder.dart b/libsignal_protocol_dart/lib/src/groups/group_session_builder.dart new file mode 100644 index 0000000..14832cc --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/group_session_builder.dart @@ -0,0 +1,48 @@ +import '../invalid_key_exception.dart'; +import '../invalid_key_id_exception.dart'; +import '../protocol/sender_key_distribution_message_wrapper.dart'; +import '../util/key_helper.dart'; +import 'sender_key_name.dart'; +import 'state/sender_key_store.dart'; + +class GroupSessionBuilder { + GroupSessionBuilder(this._senderKeyStore); + + final SenderKeyStore _senderKeyStore; + + Future process( + SenderKeyName senderKeyName, + SenderKeyDistributionMessageWrapper + senderKeyDistributionMessageWrapper) async { + final senderKeyRecord = await _senderKeyStore.loadSenderKey(senderKeyName); + senderKeyRecord.addSenderKeyState( + senderKeyDistributionMessageWrapper.id, + senderKeyDistributionMessageWrapper.iteration, + senderKeyDistributionMessageWrapper.chainKey, + senderKeyDistributionMessageWrapper.signatureKey); + await _senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord); + } + + Future create( + SenderKeyName senderKeyName) async { + try { + final senderKeyRecord = + await _senderKeyStore.loadSenderKey(senderKeyName); + if (senderKeyRecord.isEmpty) { + senderKeyRecord.setSenderKeyState(generateSenderKeyId(), 0, + generateSenderKey(), generateSenderSigningKey()); + await _senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord); + } + final state = senderKeyRecord.getSenderKeyState(); + return SenderKeyDistributionMessageWrapper( + state.keyId, + state.senderChainKey.iteration, + state.senderChainKey.seed, + state.signingKeyPublic); + } on InvalidKeyIdException catch (e) { + throw AssertionError(e); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } +} diff --git a/libsignal_protocol_dart/lib/src/groups/ratchet/sender_chain_key.dart b/libsignal_protocol_dart/lib/src/groups/ratchet/sender_chain_key.dart new file mode 100644 index 0000000..0d8b377 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/ratchet/sender_chain_key.dart @@ -0,0 +1,31 @@ +import 'dart:typed_data'; + +import 'package:crypto/crypto.dart'; + +import 'sender_message_key.dart'; + +class SenderChainKey { + SenderChainKey(this._iteration, this._chainKey); + + static final Uint8List _messageKeySeed = Uint8List.fromList([0x01]); + static final Uint8List _chainKeySeed = Uint8List.fromList([0x02]); + + final int _iteration; + final Uint8List _chainKey; + + int get iteration => _iteration; + + Uint8List get seed => _chainKey; + + SenderMessageKey get senderMessageKey => + SenderMessageKey(_iteration, getDerivative(_messageKeySeed, _chainKey)); + + SenderChainKey get next => + SenderChainKey(_iteration + 1, getDerivative(_chainKeySeed, _chainKey)); + + Uint8List getDerivative(Uint8List seed, Uint8List key) { + final hmacSha256 = Hmac(sha256, key); + final digest = hmacSha256.convert(seed); + return Uint8List.fromList(digest.bytes); + } +} diff --git a/libsignal_protocol_dart/lib/src/groups/ratchet/sender_message_key.dart b/libsignal_protocol_dart/lib/src/groups/ratchet/sender_message_key.dart new file mode 100644 index 0000000..52979f7 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/ratchet/sender_message_key.dart @@ -0,0 +1,24 @@ +import 'dart:typed_data'; + +import '../../kdf/hkdfv3.dart'; +import '../../util/byte_util.dart'; + +class SenderMessageKey { + SenderMessageKey(this._iteration, this._seed) { + final derivative = HKDFv3() + .deriveSecrets(seed, Uint8List.fromList('WhisperGroup'.codeUnits), 48); + final parts = ByteUtil.splitTwo(derivative, 16, 32); + _iv = parts[0]; + _cipherKey = parts[1]; + } + + final int _iteration; + final Uint8List _seed; + late Uint8List _iv; + late Uint8List _cipherKey; + + int get iteration => _iteration; + Uint8List get iv => _iv; + Uint8List get cipherKey => _cipherKey; + Uint8List get seed => _seed; +} diff --git a/libsignal_protocol_dart/lib/src/groups/sender_key_name.dart b/libsignal_protocol_dart/lib/src/groups/sender_key_name.dart new file mode 100644 index 0000000..2420385 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/sender_key_name.dart @@ -0,0 +1,28 @@ +import 'package:meta/meta.dart'; + +import '../signal_protocol_address.dart'; + +@immutable +class SenderKeyName { + const SenderKeyName(this._groupId, this._sender); + + final String _groupId; + final SignalProtocolAddress _sender; + + String get groupId => _groupId; + + SignalProtocolAddress get sender => _sender; + + String serialize() => + '$_groupId::${_sender.getName()}::${_sender.getDeviceId()}'; + + @override + bool operator ==(Object other) { + if (other is! SenderKeyName) return false; + + return _groupId == other.groupId && _sender == other.sender; + } + + @override + int get hashCode => _groupId.hashCode ^ _sender.hashCode; +} diff --git a/libsignal_protocol_dart/lib/src/groups/state/in_memory_sender_key_store.dart b/libsignal_protocol_dart/lib/src/groups/state/in_memory_sender_key_store.dart new file mode 100644 index 0000000..9884fbc --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/state/in_memory_sender_key_store.dart @@ -0,0 +1,29 @@ +import 'dart:collection'; + +import '../sender_key_name.dart'; +import 'sender_key_record.dart'; +import 'sender_key_store.dart'; + +class InMemorySenderKeyStore extends SenderKeyStore { + final _store = HashMap(); + + @override + Future loadSenderKey(SenderKeyName senderKeyName) async { + try { + final record = _store[senderKeyName]; + if (record == null) { + return SenderKeyRecord(); + } else { + return SenderKeyRecord.fromSerialized(record.serialize()); + } + } on Exception catch (e) { + throw AssertionError(e); + } + } + + @override + Future storeSenderKey( + SenderKeyName senderKeyName, SenderKeyRecord record) async { + _store[senderKeyName] = record; + } +} diff --git a/libsignal_protocol_dart/lib/src/groups/state/sender_key_record.dart b/libsignal_protocol_dart/lib/src/groups/state/sender_key_record.dart new file mode 100644 index 0000000..878bcc1 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/state/sender_key_record.dart @@ -0,0 +1,71 @@ +import 'dart:collection'; +import 'dart:typed_data'; + +import '../../ecc/ec_key_pair.dart'; +import '../../ecc/ec_public_key.dart'; +import '../../entry.dart'; +import '../../invalid_key_id_exception.dart'; +import '../../state/local_storage_protocol.pb.dart'; +import 'sender_key_state.dart'; + +class SenderKeyRecord { + SenderKeyRecord(); + + SenderKeyRecord.fromSerialized(Uint8List serialized) { + final senderKeyRecordStructure = + SenderKeyRecordStructure.fromBuffer(serialized); + for (final structure in senderKeyRecordStructure.senderKeyStates) { + _senderKeyStates + .add(Entry(SenderKeyState.fromSenderKeyStateStructure(structure))); + } + } + + static const int _maxStates = 5; + + final LinkedList> _senderKeyStates = + LinkedList>(); + + bool get isEmpty => _senderKeyStates.isEmpty; + + SenderKeyState getSenderKeyState() { + if (_senderKeyStates.isNotEmpty) { + return _senderKeyStates.first.value; + } else { + throw InvalidKeyIdException('No key state in record!'); + } + } + + SenderKeyState getSenderKeyStateById(int keyId) { + for (final state in _senderKeyStates) { + if (state.value.keyId == keyId) { + return state.value; + } + } + throw InvalidKeyIdException('No key for: $keyId'); + } + + void addSenderKeyState( + int id, int iteration, Uint8List chainKey, ECPublicKey signatureKey) { + _senderKeyStates.addFirst(Entry( + SenderKeyState.fromPublicKey(id, iteration, chainKey, signatureKey))); + if (_senderKeyStates.length > _maxStates) { + _senderKeyStates.remove(_senderKeyStates.last); + } + } + + void setSenderKeyState( + int id, int iteration, Uint8List chainKey, ECKeyPair signatureKey) { + _senderKeyStates + ..clear() + ..add(Entry( + SenderKeyState.fromKeyPair(id, iteration, chainKey, signatureKey))); + } + + Uint8List serialize() { + final recordStructure = SenderKeyRecordStructure.create(); + _senderKeyStates.forEach((entry) { + recordStructure.senderKeyStates.add(entry.value.structure); + }); + return recordStructure.writeToBuffer(); + } +} diff --git a/libsignal_protocol_dart/lib/src/groups/state/sender_key_state.dart b/libsignal_protocol_dart/lib/src/groups/state/sender_key_state.dart new file mode 100644 index 0000000..8b71842 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/state/sender_key_state.dart @@ -0,0 +1,107 @@ +import 'dart:typed_data'; + +import 'package:optional/optional.dart'; + +import '../../ecc/curve.dart'; +import '../../ecc/ec_key_pair.dart'; +import '../../ecc/ec_private_key.dart'; +import '../../ecc/ec_public_key.dart'; +import '../../state/local_storage_protocol.pb.dart'; +import '../ratchet/sender_chain_key.dart'; +import '../ratchet/sender_message_key.dart'; + +class SenderKeyState { + SenderKeyState.fromPublicKey(int id, int iteration, Uint8List chainKey, + ECPublicKey signatureKeyPublic) { + init(id, iteration, chainKey, signatureKeyPublic, const Optional.empty()); + } + + SenderKeyState.fromKeyPair( + int id, int iteration, Uint8List chainKey, ECKeyPair signatureKey) { + final signatureKeyPublic = signatureKey.publicKey; + final signatureKeyPrivate = Optional.of(signatureKey.privateKey); + init(id, iteration, chainKey, signatureKeyPublic, signatureKeyPrivate); + } + + SenderKeyState.fromSenderKeyStateStructure( + SenderKeyStateStructure senderKeyStateStructure) { + _senderKeyStateStructure = senderKeyStateStructure; + } + + static const int _maxMessageKeys = 2000; + + late SenderKeyStateStructure _senderKeyStateStructure; + + void init( + int id, int iteration, Uint8List chainKey, ECPublicKey signatureKeyPublic, + [Optional? signatureKeyPrivate]) { + final seed = Uint8List.fromList(chainKey); + final senderChainKeyStructure = + SenderKeyStateStructureSenderChainKey.create() + ..iteration = iteration + ..seed = seed; + final signingKeyStructure = SenderKeyStateStructureSenderSigningKey.create() + ..public = signatureKeyPublic.serialize(); + if (signatureKeyPrivate!.isPresent) { + signingKeyStructure.private = signatureKeyPrivate.value.serialize(); + } + _senderKeyStateStructure = SenderKeyStateStructure.create() + ..senderKeyId = id + ..senderChainKey = senderChainKeyStructure + ..senderSigningKey = signingKeyStructure; + } + + int get keyId => _senderKeyStateStructure.senderKeyId; + + SenderChainKey get senderChainKey => SenderChainKey( + _senderKeyStateStructure.senderChainKey.iteration, + Uint8List.fromList(_senderKeyStateStructure.senderChainKey.seed)); + + set senderChainKey(SenderChainKey senderChainKey) => { + _senderKeyStateStructure.senderChainKey = + SenderKeyStateStructureSenderChainKey.create() + ..iteration = senderChainKey.iteration + ..seed = List.from(senderChainKey.seed) + }; + + ECPublicKey get signingKeyPublic => Curve.decodePointList( + _senderKeyStateStructure.senderSigningKey.public, 0); + + ECPrivateKey get signingKeyPrivate => Curve.decodePrivatePoint( + Uint8List.fromList(_senderKeyStateStructure.senderSigningKey.private)); + + bool hasSenderMessageKey(int iteration) { + for (final senderMessageKey in _senderKeyStateStructure.senderMessageKeys) { + if (senderMessageKey.iteration == iteration) { + return true; + } + } + return false; + } + + void addSenderMessageKey(SenderMessageKey senderMessageKey) { + final senderMessageKeyStructure = + SenderKeyStateStructureSenderMessageKey.create() + ..iteration = senderMessageKey.iteration + ..seed = senderMessageKey.seed; + _senderKeyStateStructure.senderMessageKeys.add(senderMessageKeyStructure); + if (_senderKeyStateStructure.senderMessageKeys.length > _maxMessageKeys) { + _senderKeyStateStructure.senderMessageKeys.removeAt(0); + } + } + + SenderMessageKey? removeSenderMessageKey(int iteration) { + _senderKeyStateStructure.senderMessageKeys + .toList() + .addAll(_senderKeyStateStructure.senderMessageKeys); + final index = _senderKeyStateStructure.senderMessageKeys + .indexWhere((item) => item.iteration == iteration); + if (index == -1) return null; + final senderMessageKey = + _senderKeyStateStructure.senderMessageKeys.removeAt(index); + return SenderMessageKey( + senderMessageKey.iteration, Uint8List.fromList(senderMessageKey.seed)); + } + + SenderKeyStateStructure get structure => _senderKeyStateStructure; +} diff --git a/libsignal_protocol_dart/lib/src/groups/state/sender_key_store.dart b/libsignal_protocol_dart/lib/src/groups/state/sender_key_store.dart new file mode 100644 index 0000000..5e57359 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/groups/state/sender_key_store.dart @@ -0,0 +1,9 @@ +import '../sender_key_name.dart'; +import 'sender_key_record.dart'; + +abstract class SenderKeyStore { + Future storeSenderKey( + SenderKeyName senderKeyName, SenderKeyRecord record); + + Future loadSenderKey(SenderKeyName senderKeyName); +} diff --git a/libsignal_protocol_dart/lib/src/identity_key.dart b/libsignal_protocol_dart/lib/src/identity_key.dart new file mode 100644 index 0000000..f2516df --- /dev/null +++ b/libsignal_protocol_dart/lib/src/identity_key.dart @@ -0,0 +1,33 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:meta/meta.dart'; + +import 'ecc/curve.dart'; +import 'ecc/ec_public_key.dart'; + +@immutable +class IdentityKey { + const IdentityKey(this._publicKey); + + factory IdentityKey.fromBytes(Uint8List bytes, int offset) => + IdentityKey(Curve.decodePoint(bytes, offset)); + + final ECPublicKey _publicKey; + + ECPublicKey get publicKey => _publicKey; + + Uint8List serialize() => _publicKey.serialize(); + + String getFingerprint() => hex.encode(_publicKey.serialize()); + + @override + bool operator ==(Object other) { + if (other is! IdentityKey) return false; + + return _publicKey == other._publicKey; + } + + @override + int get hashCode => _publicKey.hashCode; +} diff --git a/libsignal_protocol_dart/lib/src/identity_key_pair.dart b/libsignal_protocol_dart/lib/src/identity_key_pair.dart new file mode 100644 index 0000000..6c9d4e0 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/identity_key_pair.dart @@ -0,0 +1,32 @@ +import 'dart:typed_data'; + +import 'ecc/curve.dart'; +import 'ecc/ec_private_key.dart'; +import 'identity_key.dart'; +import 'state/local_storage_protocol.pb.dart'; + +class IdentityKeyPair { + IdentityKeyPair(this._publicKey, this._privateKey); + + IdentityKeyPair.fromSerialized(Uint8List serialized) { + final structure = IdentityKeyPairStructure.fromBuffer(serialized); + _publicKey = + IdentityKey.fromBytes(Uint8List.fromList(structure.publicKey), 0); + _privateKey = + Curve.decodePrivatePoint(Uint8List.fromList(structure.privateKey)); + } + + late IdentityKey _publicKey; + late ECPrivateKey _privateKey; + + IdentityKey getPublicKey() => _publicKey; + + ECPrivateKey getPrivateKey() => _privateKey; + + Uint8List serialize() { + final i = IdentityKeyPairStructure.create() + ..publicKey = List.from(_publicKey.serialize()) + ..privateKey = List.from(_privateKey.serialize()); + return i.toBuilder().writeToBuffer(); + } +} diff --git a/libsignal_protocol_dart/lib/src/invalid_key_exception.dart b/libsignal_protocol_dart/lib/src/invalid_key_exception.dart new file mode 100644 index 0000000..e3bef90 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/invalid_key_exception.dart @@ -0,0 +1,7 @@ +class InvalidKeyException implements Exception { + InvalidKeyException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'InvalidKeyException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/invalid_key_id_exception.dart b/libsignal_protocol_dart/lib/src/invalid_key_id_exception.dart new file mode 100644 index 0000000..265adcb --- /dev/null +++ b/libsignal_protocol_dart/lib/src/invalid_key_id_exception.dart @@ -0,0 +1,7 @@ +class InvalidKeyIdException implements Exception { + InvalidKeyIdException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'InvalidKeyIdException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/invalid_mac_exception.dart b/libsignal_protocol_dart/lib/src/invalid_mac_exception.dart new file mode 100644 index 0000000..d49b853 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/invalid_mac_exception.dart @@ -0,0 +1,7 @@ +class InvalidMacException implements Exception { + InvalidMacException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'InvalidMacException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/invalid_message_exception.dart b/libsignal_protocol_dart/lib/src/invalid_message_exception.dart new file mode 100644 index 0000000..388b79d --- /dev/null +++ b/libsignal_protocol_dart/lib/src/invalid_message_exception.dart @@ -0,0 +1,7 @@ +class InvalidMessageException implements Exception { + InvalidMessageException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'InvalidMessageException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/kdf/derived_message_secrets.dart b/libsignal_protocol_dart/lib/src/kdf/derived_message_secrets.dart new file mode 100644 index 0000000..d54f4be --- /dev/null +++ b/libsignal_protocol_dart/lib/src/kdf/derived_message_secrets.dart @@ -0,0 +1,29 @@ +import 'dart:typed_data'; + +import '../util/byte_util.dart'; + +class DerivedMessageSecrets { + DerivedMessageSecrets(Uint8List okm) { + final keys = + ByteUtil.split(okm, _cipherKeyLength, _macKeyLength, _ivLength); + + _cipherKey = keys[0]; + _macKey = keys[1]; + _iv = keys[2]; + } + + static const int size = 80; + static const int _cipherKeyLength = 32; + static const int _macKeyLength = 32; + static const int _ivLength = 16; + + late Uint8List _cipherKey; + late Uint8List _macKey; + late Uint8List _iv; + + Uint8List getCipherKey() => _cipherKey; + + Uint8List getMacKey() => _macKey; + + Uint8List getIv() => _iv; +} diff --git a/libsignal_protocol_dart/lib/src/kdf/derived_root_secrets.dart b/libsignal_protocol_dart/lib/src/kdf/derived_root_secrets.dart new file mode 100644 index 0000000..9426186 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/kdf/derived_root_secrets.dart @@ -0,0 +1,20 @@ +import 'dart:typed_data'; + +import '../util/byte_util.dart'; + +class DerivedRootSecrets { + DerivedRootSecrets(Uint8List okm) { + final keys = ByteUtil.splitTwo(okm, 32, 32); + _rootKey = keys[0]; + _chainKey = keys[1]; + } + + static const int size = 64; + + late Uint8List _rootKey; + late Uint8List _chainKey; + + Uint8List getRootKey() => _rootKey; + + Uint8List getChainKey() => _chainKey; +} diff --git a/libsignal_protocol_dart/lib/src/kdf/hkdf.dart b/libsignal_protocol_dart/lib/src/kdf/hkdf.dart new file mode 100644 index 0000000..5645147 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/kdf/hkdf.dart @@ -0,0 +1,81 @@ +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; + +import '../invalid_key_exception.dart'; +import 'hkdfv2.dart'; +import 'hkdfv3.dart'; + +abstract class HKDF { + static const int hashOutputSize = 32; + + static HKDF createFor(int messageVersion) { + switch (messageVersion) { + case 2: + return HKDFv2(); + case 3: + return HKDFv3(); + default: + throw AssertionError('Unknown version: $messageVersion'); + } + } + + Uint8List deriveSecrets( + Uint8List inputKeyMaterial, Uint8List info, int outputLength) { + final salt = Uint8List(hashOutputSize); + return deriveSecrets4(inputKeyMaterial, salt, info, outputLength); + } + + Uint8List deriveSecrets4(Uint8List inputKeyMaterial, Uint8List salt, + Uint8List info, int outputLength) { + final prk = extract(salt, inputKeyMaterial); + return expand(prk, info, outputLength); + } + + Uint8List extract(Uint8List salt, Uint8List inputKeyMaterial) { + final hmacSha256 = Hmac(sha256, salt); + final digest = hmacSha256.convert(inputKeyMaterial); + return Uint8List.fromList(digest.bytes); + } + + Uint8List expand(Uint8List prk, Uint8List? info, int outputSize) { + try { + final iterations = + (outputSize.toDouble() / hashOutputSize.toDouble()).ceil(); + var mix = Uint8List(0); + final results = Uint8List(outputSize); + var remainingBytes = outputSize; + + for (var i = getIterationStartOffset(); + i < iterations + getIterationStartOffset(); + i++) { + final mac = Hmac(sha256, prk); + final output = AccumulatorSink(); + final input = mac.startChunkedConversion(output)..add(mix); + if (info != null) { + input.add(info); + } + input + ..add([i]) + ..close(); + final stepResult = Uint8List.fromList(output.events.single.bytes); + final stepSize = min(remainingBytes, stepResult.length); + + for (var j = 0; j < stepSize; j++) { + final offset = (i - getIterationStartOffset()) * hashOutputSize + j; + results[offset] = stepResult[j]; + } + + mix = stepResult; + remainingBytes -= stepSize; + } + return results.buffer.asUint8List(); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } + + int getIterationStartOffset(); +} diff --git a/libsignal_protocol_dart/lib/src/kdf/hkdfv2.dart b/libsignal_protocol_dart/lib/src/kdf/hkdfv2.dart new file mode 100644 index 0000000..3c7bc7b --- /dev/null +++ b/libsignal_protocol_dart/lib/src/kdf/hkdfv2.dart @@ -0,0 +1,6 @@ +import 'hkdf.dart'; + +class HKDFv2 extends HKDF { + @override + int getIterationStartOffset() => 0; +} diff --git a/libsignal_protocol_dart/lib/src/kdf/hkdfv3.dart b/libsignal_protocol_dart/lib/src/kdf/hkdfv3.dart new file mode 100644 index 0000000..1defb1e --- /dev/null +++ b/libsignal_protocol_dart/lib/src/kdf/hkdfv3.dart @@ -0,0 +1,6 @@ +import 'hkdf.dart'; + +class HKDFv3 extends HKDF { + @override + int getIterationStartOffset() => 1; +} diff --git a/libsignal_protocol_dart/lib/src/legacy_message_exception.dart b/libsignal_protocol_dart/lib/src/legacy_message_exception.dart new file mode 100644 index 0000000..e389d13 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/legacy_message_exception.dart @@ -0,0 +1,7 @@ +class LegacyMessageException implements Exception { + LegacyMessageException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'LegacyMessageException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/no_session_exception.dart b/libsignal_protocol_dart/lib/src/no_session_exception.dart new file mode 100644 index 0000000..ed9b257 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/no_session_exception.dart @@ -0,0 +1,7 @@ +class NoSessionException implements Exception { + NoSessionException(this.detailMessage); + final String detailMessage; + + @override + String toString() => 'NoSessionException - $detailMessage'; +} diff --git a/libsignal_protocol_dart/lib/src/protocol/ciphertext_message.dart b/libsignal_protocol_dart/lib/src/protocol/ciphertext_message.dart new file mode 100644 index 0000000..17bb26e --- /dev/null +++ b/libsignal_protocol_dart/lib/src/protocol/ciphertext_message.dart @@ -0,0 +1,16 @@ +import 'dart:typed_data'; + +abstract class CiphertextMessage { + static const int currentVersion = 3; + + static const int whisperType = 2; + static const int prekeyType = 3; + static const int senderKeyType = 4; + static const int senderKeyDistributionType = 5; + + // This should be the worst case (worse than V2). So not always accurate, but good enough for padding. + static const int encryptedMessageOverhead = 53; + + Uint8List serialize(); + int getType(); +} diff --git a/libsignal_protocol_dart/lib/src/protocol/device_consistency_message.dart b/libsignal_protocol_dart/lib/src/protocol/device_consistency_message.dart new file mode 100644 index 0000000..a87fe7d --- /dev/null +++ b/libsignal_protocol_dart/lib/src/protocol/device_consistency_message.dart @@ -0,0 +1,71 @@ +import 'dart:typed_data'; + +import 'package:protobuf/protobuf.dart'; + +import '../devices/device_consistency_commitment.dart'; +import '../devices/device_consistency_signature.dart'; +import '../ecc/curve.dart'; +import '../identity_key.dart'; +import '../identity_key_pair.dart'; +import '../invalid_key_exception.dart'; +import '../invalid_message_exception.dart'; +import '../state/whisper_text_protocol.pb.dart'; + +class DeviceConsistencyMessage { + DeviceConsistencyMessage( + DeviceConsistencyCommitment commitment, IdentityKeyPair identityKeyPair) { + try { + final signatureBytes = Curve.calculateVrfSignature( + identityKeyPair.getPrivateKey(), commitment.serialized); + final vrfOutputBytes = Curve.verifyVrfSignature( + identityKeyPair.getPublicKey().publicKey, + commitment.serialized, + signatureBytes); + + _generation = commitment.generation; + _signature = DeviceConsistencySignature(signatureBytes, vrfOutputBytes); + final d = DeviceConsistencyCodeMessage.create() + ..generation = commitment.generation + ..signature = _signature.signature.toList(); + _serialized = d.writeToBuffer(); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } +// } on VrfSignatureVerificationFailedException catch (e) { +// throw AssertionError(e); +// } + } + + DeviceConsistencyMessage.fromSerialized( + DeviceConsistencyCommitment commitment, + Uint8List serialized, + IdentityKey identityKey) { + try { + final message = DeviceConsistencyCodeMessage.fromBuffer(serialized); + final vrfOutputBytes = Curve.verifyVrfSignature(identityKey.publicKey, + commitment.serialized, Uint8List.fromList(message.signature)); + + _generation = message.generation; + _signature = DeviceConsistencySignature( + Uint8List.fromList(message.signature), vrfOutputBytes); + _serialized = serialized; + } on InvalidProtocolBufferException catch (e) { + throw InvalidMessageException(e.message); + } on InvalidKeyException catch (e) { + throw InvalidMessageException(e.detailMessage); + } +// } on VrfSignatureVerificationFailedException catch (e) { +// throw AssertionError(e); +// } + } + + late DeviceConsistencySignature _signature; + late int _generation; + late Uint8List _serialized; + + Uint8List get serialized => _serialized; + + DeviceConsistencySignature get signature => _signature; + + int get generation => _generation; +} diff --git a/libsignal_protocol_dart/lib/src/protocol/pre_key_signal_message.dart b/libsignal_protocol_dart/lib/src/protocol/pre_key_signal_message.dart new file mode 100644 index 0000000..058bb83 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/protocol/pre_key_signal_message.dart @@ -0,0 +1,101 @@ +import 'dart:typed_data'; + +import 'package:optional/optional.dart'; + +import '../ecc/curve.dart'; +import '../ecc/ec_public_key.dart'; +import '../identity_key.dart'; +import '../invalid_key_exception.dart'; +import '../invalid_message_exception.dart'; +import '../legacy_message_exception.dart'; +import '../protocol/ciphertext_message.dart'; +import '../protocol/signal_message.dart'; +import '../state/whisper_text_protocol.pb.dart' as signal_protos; +import '../util/byte_util.dart'; + +class PreKeySignalMessage extends CiphertextMessage { + PreKeySignalMessage(Uint8List serialized) { + try { + _version = ByteUtil.highBitsToInt(serialized[0]); + + final preKeyWhisperMessage = + signal_protos.PreKeySignalMessage.fromBuffer(serialized.sublist(1)); + + if (!preKeyWhisperMessage.hasSignedPreKeyId() || + !preKeyWhisperMessage.hasBaseKey() || + !preKeyWhisperMessage.hasIdentityKey() || + !preKeyWhisperMessage.hasMessage()) { + throw InvalidMessageException('Incomplete message.'); + } + + this.serialized = serialized; + registrationId = preKeyWhisperMessage.registrationId; + preKeyId = preKeyWhisperMessage.hasPreKeyId() + ? Optional.of(preKeyWhisperMessage.preKeyId) + : const Optional.empty(); + signedPreKeyId = preKeyWhisperMessage.hasSignedPreKeyId() + ? preKeyWhisperMessage.signedPreKeyId + : -1; + baseKey = Curve.decodePoint( + Uint8List.fromList(preKeyWhisperMessage.baseKey), 0); + identityKey = IdentityKey(Curve.decodePoint( + Uint8List.fromList(preKeyWhisperMessage.identityKey), 0)); + message = SignalMessage.fromSerialized( + Uint8List.fromList(preKeyWhisperMessage.message)); + } on InvalidKeyException catch (e) { + throw InvalidMessageException(e.detailMessage); + } on LegacyMessageException catch (e) { + throw InvalidMessageException(e.detailMessage); + } + } + + PreKeySignalMessage.from(this._version, this.registrationId, this.preKeyId, + this.signedPreKeyId, this.baseKey, this.identityKey, this.message) { + final builder = signal_protos.PreKeySignalMessage.create() + ..signedPreKeyId = signedPreKeyId + ..baseKey = baseKey.serialize() + ..identityKey = identityKey.serialize() + ..message = message.serialize() + ..registrationId = registrationId; + + if (preKeyId.isPresent) { + builder.preKeyId = preKeyId.value; + } + + final versionBytes = [ + ByteUtil.intsToByteHighAndLow(_version, CiphertextMessage.currentVersion) + ]; + + final messageBytes = builder.toBuilder().writeToBuffer(); + serialized = Uint8List.fromList(versionBytes + messageBytes); + } + + late int _version; + late int registrationId; + late Optional preKeyId; + late int signedPreKeyId; + late ECPublicKey baseKey; + late IdentityKey identityKey; + late SignalMessage message; + late Uint8List serialized; + + int getMessageVersion() => _version; + + IdentityKey getIdentityKey() => identityKey; + + int getRegistrationId() => registrationId; + + Optional getPreKeyId() => preKeyId; + + int getSignedPreKeyId() => signedPreKeyId; + + ECPublicKey getBaseKey() => baseKey; + + SignalMessage getWhisperMessage() => message; + + @override + int getType() => CiphertextMessage.prekeyType; + + @override + Uint8List serialize() => serialized; +} diff --git a/libsignal_protocol_dart/lib/src/protocol/sender_key_distribution_message_wrapper.dart b/libsignal_protocol_dart/lib/src/protocol/sender_key_distribution_message_wrapper.dart new file mode 100644 index 0000000..14e4b1b --- /dev/null +++ b/libsignal_protocol_dart/lib/src/protocol/sender_key_distribution_message_wrapper.dart @@ -0,0 +1,87 @@ +import 'dart:typed_data'; + +import 'package:protobuf/protobuf.dart'; + +import '../ecc/curve.dart'; +import '../ecc/ec_public_key.dart'; +import '../invalid_key_exception.dart'; +import '../invalid_message_exception.dart'; +import '../legacy_message_exception.dart'; +import '../state/whisper_text_protocol.pb.dart'; +import '../util/byte_util.dart'; +import 'ciphertext_message.dart'; + +class SenderKeyDistributionMessageWrapper extends CiphertextMessage { + SenderKeyDistributionMessageWrapper( + int id, int iteration, Uint8List chainKey, ECPublicKey signatureKey) { + final version = Uint8List.fromList([ + ByteUtil.intsToByteHighAndLow( + CiphertextMessage.currentVersion, CiphertextMessage.currentVersion) + ]); + final protobuf = SenderKeyDistributionMessage.create() + ..id = id + ..iteration = iteration + ..chainKey = List.from(chainKey) + ..signingKey = List.from(signatureKey.serialize()); + _id = id; + _iteration = iteration; + _chainKey = chainKey; + _signatureKey = signatureKey; + _serialized = ByteUtil.combine([version, protobuf.writeToBuffer()]); + } + + SenderKeyDistributionMessageWrapper.fromSerialized(Uint8List serialized) { + try { + final messageParts = + ByteUtil.splitTwo(serialized, 1, serialized.length - 1); + final version = messageParts[0][0]; + final message = messageParts[1]; + + if (ByteUtil.highBitsToInt(version) < CiphertextMessage.currentVersion) { + throw LegacyMessageException( + 'Legacy message: ${ByteUtil.highBitsToInt(version)}'); + } + if (ByteUtil.highBitsToInt(version) > CiphertextMessage.currentVersion) { + throw InvalidMessageException( + 'Unknown version: ${ByteUtil.highBitsToInt(version)}'); + } + + final distributionMessages = + SenderKeyDistributionMessage.fromBuffer(message); + if (!distributionMessages.hasId() || + !distributionMessages.hasIteration() || + !distributionMessages.hasChainKey() || + !distributionMessages.hasSigningKey()) { + throw InvalidMessageException('Incomplete message.'); + } + + _serialized = serialized; + _id = distributionMessages.id; + _iteration = distributionMessages.iteration; + _chainKey = Uint8List.fromList(distributionMessages.chainKey); + _signatureKey = Curve.decodePoint( + Uint8List.fromList(distributionMessages.signingKey), 0); + } on InvalidProtocolBufferException catch (e) { + throw InvalidMessageException(e.message); + } on InvalidKeyException catch (e) { + throw InvalidMessageException(e.detailMessage); + } + } + + late int _id; + late int _iteration; + late Uint8List _chainKey; + late ECPublicKey _signatureKey; + late Uint8List _serialized; + + @override + int getType() => CiphertextMessage.senderKeyDistributionType; + + @override + Uint8List serialize() => _serialized; + + int get iteration => _iteration; + Uint8List get chainKey => _chainKey; + ECPublicKey get signatureKey => _signatureKey; + int get id => _id; +} diff --git a/libsignal_protocol_dart/lib/src/protocol/sender_key_message.dart b/libsignal_protocol_dart/lib/src/protocol/sender_key_message.dart new file mode 100644 index 0000000..39b99c6 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/protocol/sender_key_message.dart @@ -0,0 +1,108 @@ +import 'dart:typed_data'; + +import '../ecc/curve.dart'; +import '../ecc/ec_private_key.dart'; +import '../ecc/ec_public_key.dart'; +import '../invalid_key_exception.dart'; +import '../invalid_key_id_exception.dart'; +import '../invalid_message_exception.dart'; +import '../legacy_message_exception.dart'; +import '../state/whisper_text_protocol.pb.dart' as protocol; +import '../util/byte_util.dart'; +import 'ciphertext_message.dart'; + +class SenderKeyMessage extends CiphertextMessage { + SenderKeyMessage(int keyId, int iteration, Uint8List ciphertext, + ECPrivateKey signatureKey) { + final version = Uint8List.fromList([ + ByteUtil.intsToByteHighAndLow( + CiphertextMessage.currentVersion, CiphertextMessage.currentVersion) + ]); + final message = protocol.SenderKeyMessage.create() + ..id = keyId + ..iteration = iteration + ..ciphertext = ciphertext; + final messageList = message.writeToBuffer(); + final signature = + _getSignature(signatureKey, ByteUtil.combine([version, messageList])); + _serialized = ByteUtil.combine([version, messageList, signature]); + _messageVersion = CiphertextMessage.currentVersion; + _keyId = keyId; + _iteration = iteration; + _ciphertext = ciphertext; + } + + SenderKeyMessage.fromSerialized(Uint8List serialized) { + final messageParts = ByteUtil.split(serialized, 1, + serialized.length - 1 - signatureLength, signatureLength); + final version = messageParts[0][0]; + final message = messageParts[1]; + // ignore: unused_local_variable + final signature = messageParts[2]; + + if (ByteUtil.highBitsToInt(version) < 3) { + throw LegacyMessageException( + 'Legacy message: ${ByteUtil.highBitsToInt(version)}'); + } + + if (ByteUtil.highBitsToInt(version) > CiphertextMessage.currentVersion) { + throw InvalidMessageException( + 'Unknown version: ${ByteUtil.highBitsToInt(version)}'); + } + + final senderKeyMessage = protocol.SenderKeyMessage.fromBuffer(message); + + if (!senderKeyMessage.hasId() || + !senderKeyMessage.hasIteration() || + !senderKeyMessage.hasCiphertext()) { + throw InvalidMessageException('Incomplete message.'); + } + + _serialized = serialized; + _messageVersion = ByteUtil.highBitsToInt(version); + _keyId = senderKeyMessage.id; + _iteration = senderKeyMessage.iteration; + _ciphertext = Uint8List.fromList(senderKeyMessage.ciphertext); + } + + static const int signatureLength = 64; + + // ignore: unused_field + late int _messageVersion; + late int _keyId; + late int _iteration; + late Uint8List _ciphertext; + late Uint8List _serialized; + + Uint8List _getSignature(ECPrivateKey signatureKey, Uint8List serialized) { + try { + return Curve.calculateSignature(signatureKey, serialized); + } on InvalidKeyIdException catch (e) { + throw AssertionError(e); + } + } + + int get keyId => _keyId; + + int get iteration => _iteration; + + Uint8List get ciphertext => _ciphertext; + + void verifySignature(ECPublicKey signatureKey) { + try { + final parts = ByteUtil.splitTwo( + _serialized, _serialized.length - signatureLength, signatureLength); + if (!Curve.verifySignature(signatureKey, parts[0], parts[1])) { + throw InvalidMessageException('Invalid signature!'); + } + } on InvalidKeyException catch (e) { + throw InvalidMessageException(e.detailMessage); + } + } + + @override + int getType() => CiphertextMessage.senderKeyType; + + @override + Uint8List serialize() => _serialized; +} diff --git a/libsignal_protocol_dart/lib/src/protocol/signal_message.dart b/libsignal_protocol_dart/lib/src/protocol/signal_message.dart new file mode 100644 index 0000000..dd526ea --- /dev/null +++ b/libsignal_protocol_dart/lib/src/protocol/signal_message.dart @@ -0,0 +1,141 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; +import 'package:protobuf/protobuf.dart'; + +import '../ecc/curve.dart'; +import '../ecc/ec_public_key.dart'; +import '../identity_key.dart'; +import '../invalid_key_exception.dart'; +import '../invalid_message_exception.dart'; +import '../legacy_message_exception.dart'; +import '../protocol/ciphertext_message.dart'; +import '../state/whisper_text_protocol.pb.dart' as signal_protos; +import '../util/byte_util.dart'; + +class SignalMessage extends CiphertextMessage { + SignalMessage( + int messageVersion, + Uint8List macKey, + ECPublicKey senderRatchetKey, + int counter, + int previousCounter, + Uint8List ciphertext, + IdentityKey senderIdentityKey, + IdentityKey? receiverIdentityKey) { + final version = Uint8List.fromList([ + ByteUtil.intsToByteHighAndLow( + messageVersion, CiphertextMessage.currentVersion) + ]); + + final m = signal_protos.SignalMessage.create() + ..ratchetKey = senderRatchetKey.serialize() + ..counter = counter + ..previousCounter = previousCounter + ..ciphertext = ciphertext; + final message = m.writeToBuffer(); + + final mac = _getMac(senderIdentityKey, receiverIdentityKey!, macKey, + ByteUtil.combine([version, message])); + + _serialized = ByteUtil.combine([version, message, mac]); + _senderRatchetKey = senderRatchetKey; + _counter = counter; + _previousCounter = previousCounter; + _ciphertext = ciphertext; + _messageVersion = messageVersion; + } + + SignalMessage.fromSerialized(Uint8List serialized) { + try { + final messageParts = ByteUtil.split( + serialized, 1, serialized.length - 1 - macLength, macLength); + final version = messageParts[0].first; + final message = messageParts[1]; + // ignore: unused_local_variable + final mac = messageParts[2]; + + if (ByteUtil.highBitsToInt(version) < CiphertextMessage.currentVersion) { + throw LegacyMessageException( + 'Legacy message: $ByteUtil.highBitsToInt(version)'); + } + + if (ByteUtil.highBitsToInt(version) > CiphertextMessage.currentVersion) { + throw InvalidMessageException( + 'Unknown version: $ByteUtil.highBitsToInt(version)'); + } + + final whisperMessage = signal_protos.SignalMessage.fromBuffer(message); + + if (!whisperMessage.hasCiphertext() || + !whisperMessage.hasCounter() || + !whisperMessage.hasRatchetKey()) { + throw InvalidMessageException('Incomplete message.'); + } + + _serialized = serialized; + _senderRatchetKey = + Curve.decodePoint(Uint8List.fromList(whisperMessage.ratchetKey), 0); + _messageVersion = ByteUtil.highBitsToInt(version); + _counter = whisperMessage.counter; + _previousCounter = whisperMessage.previousCounter; + _ciphertext = Uint8List.fromList(whisperMessage.ciphertext); + } on InvalidProtocolBufferException catch (e) { + throw InvalidMessageException(e.toString()); + } on InvalidKeyException catch (e) { + throw InvalidMessageException(e.detailMessage); + } + } + + static const int macLength = 8; + + late int _messageVersion; + late ECPublicKey _senderRatchetKey; + late int _counter; + // ignore: unused_field + late int _previousCounter; + late Uint8List _ciphertext; + late Uint8List _serialized; + + ECPublicKey getSenderRatchetKey() => _senderRatchetKey; + + int getMessageVersion() => _messageVersion; + + int getCounter() => _counter; + + Uint8List getBody() => _ciphertext; + + void verifyMac(IdentityKey senderIdentityKey, IdentityKey receiverIdentityKey, + Uint8List macKey) { + final parts = ByteUtil.splitTwo( + _serialized, _serialized.length - macLength, macLength); + final ourMac = + _getMac(senderIdentityKey, receiverIdentityKey, macKey, parts[0]); + final theirMac = parts[1]; + + if (Digest(ourMac) != Digest(theirMac)) { + throw InvalidMessageException('Bad Mac!'); + } + } + + Uint8List _getMac(IdentityKey senderIdentityKey, + IdentityKey receiverIdentityKey, Uint8List macKey, Uint8List serialized) { + final mac = Hmac(sha256, macKey); // HMAC-SHA256 + + final output = AccumulatorSink(); + mac.startChunkedConversion(output) + ..add(senderIdentityKey.publicKey.serialize()) + ..add(receiverIdentityKey.publicKey.serialize()) + ..add(serialized) + ..close(); + final fullMac = Uint8List.fromList(output.events.single.bytes); + return ByteUtil.trim(fullMac, macLength); + } + + @override + int getType() => CiphertextMessage.whisperType; + + @override + Uint8List serialize() => _serialized; +} diff --git a/libsignal_protocol_dart/lib/src/provisioning_cipher.dart b/libsignal_protocol_dart/lib/src/provisioning_cipher.dart new file mode 100644 index 0000000..cee0141 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/provisioning_cipher.dart @@ -0,0 +1,109 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:crypto/crypto.dart'; + +import 'cbc.dart'; +import 'ecc/curve.dart'; +import 'ecc/ec_public_key.dart'; +import 'eq.dart'; +import 'invalid_mac_exception.dart'; +import 'kdf/derived_root_secrets.dart'; +import 'kdf/hkdfv3.dart'; +import 'legacy_message_exception.dart'; +import 'util/byte_util.dart'; + +const String provision = 'Mixin Provisioning Message'; + +class ProvisionEnvelope { + ProvisionEnvelope(this.publicKey, this.body); + + ProvisionEnvelope.fromJson(Map json) + : publicKey = base64Decode(json['public_key'] as String), + body = base64Decode(json['body'] as String); + + final Uint8List publicKey; + final Uint8List body; + + Map toJson() => { + 'public_key': base64Encode(publicKey), + 'body': base64Encode(body), + }; +} + +Uint8List decrypt(String privateKey, String content) { + final ourPrivateKey = base64Decode(privateKey); + final envelopeDecode = base64Decode(content); + + final map = jsonDecode(String.fromCharCodes(envelopeDecode)); + final provisionEnvelope = + ProvisionEnvelope.fromJson(map as Map); + final publicKeyable = Curve.decodePoint(provisionEnvelope.publicKey, 0); + final message = provisionEnvelope.body; + if (message[0] != 1) { + throw LegacyMessageException('Invalid version'); + } + final iv = Uint8List.fromList(message.getRange(1, 16 + 1).toList()); + final mac = message.getRange(message.length - 32, message.length).toList(); + final ivAndCiphertext = + Uint8List.fromList(message.getRange(0, message.length - 32).toList()); + final cipherText = Uint8List.fromList( + message.getRange(16 + 1, message.length - 32).toList()); + final sharedSecret = Curve.calculateAgreement( + publicKeyable, Curve.decodePrivatePoint(ourPrivateKey)); + + final derivedSecretBytes = HKDFv3().deriveSecrets(sharedSecret, + Uint8List.fromList(utf8.encode(provision)), DerivedRootSecrets.size); + + final aesKey = + Uint8List.fromList(derivedSecretBytes.getRange(0, 32).toList()); + final macKey = Uint8List.fromList( + derivedSecretBytes.getRange(32, derivedSecretBytes.length).toList()); + + if (!verifyMAC(macKey, ivAndCiphertext, mac)) { + throw InvalidMacException("MAC doesn't match!"); + } + final plaintext = aesCbcDecrypt(aesKey, iv, cipherText); + return plaintext; +} + +bool verifyMAC(Uint8List key, Uint8List input, List mac) { + final hmacSha256 = Hmac(sha256, key); + final digest = hmacSha256.convert(input); + return eq(digest.bytes, mac); +} + +class ProvisioningCipher { + ProvisioningCipher(this._theirPublicKey); + + final ECPublicKey _theirPublicKey; + + Uint8List encrypt(Uint8List message) { + final ourKeyPair = Curve.generateKeyPair(); + final sharedSecret = + Curve.calculateAgreement(_theirPublicKey, ourKeyPair.privateKey); + final derivedSecret = HKDFv3().deriveSecrets( + sharedSecret, Uint8List.fromList(utf8.encode(provision)), 64); + final parts = ByteUtil.splitTwo(derivedSecret, 32, 32); + + final version = Uint8List.fromList([1]); + final ciphertext = getCiphertext(parts[0], message); + final mac = _getMac(parts[1], ByteUtil.combine([version, ciphertext])); + final body = ByteUtil.combine([version, ciphertext, mac]); + final envelope = ProvisionEnvelope(ourKeyPair.publicKey.serialize(), body); + final result = jsonEncode(envelope); + return Uint8List.fromList(utf8.encode(result)); + } + + Uint8List getCiphertext(Uint8List key, Uint8List message) { + final iv = Uint8List(16); + final m = aesCbcEncrypt(key, iv, message); + return Uint8List.fromList(iv + m); + } + + Uint8List _getMac(Uint8List key, Uint8List message) { + final hmacSha256 = Hmac(sha256, key); + final digest = hmacSha256.convert(message); + return Uint8List.fromList(digest.bytes); + } +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/alice_signal_protocol_parameters.dart b/libsignal_protocol_dart/lib/src/ratchet/alice_signal_protocol_parameters.dart new file mode 100644 index 0000000..2ef531b --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/alice_signal_protocol_parameters.dart @@ -0,0 +1,25 @@ +import 'package:optional/optional.dart'; + +import '../ecc/ec_key_pair.dart'; +import '../ecc/ec_public_key.dart'; +import '../identity_key.dart'; +import '../identity_key_pair.dart'; + +class AliceSignalProtocolParameters { + AliceSignalProtocolParameters({ + required this.ourIdentityKey, + required this.ourBaseKey, + required this.theirIdentityKey, + required this.theirSignedPreKey, + required this.theirRatchetKey, + required this.theirOneTimePreKey, + }); + + final IdentityKeyPair ourIdentityKey; + final ECKeyPair ourBaseKey; + + final IdentityKey theirIdentityKey; + final ECPublicKey theirSignedPreKey; + final Optional theirOneTimePreKey; + final ECPublicKey theirRatchetKey; +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/bob_signal_protocol_parameters.dart b/libsignal_protocol_dart/lib/src/ratchet/bob_signal_protocol_parameters.dart new file mode 100644 index 0000000..2ccb165 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/bob_signal_protocol_parameters.dart @@ -0,0 +1,37 @@ +import 'package:optional/optional.dart'; + +import '../ecc/ec_key_pair.dart'; +import '../ecc/ec_public_key.dart'; +import '../identity_key.dart'; +import '../identity_key_pair.dart'; + +class BobSignalProtocolParameters { + BobSignalProtocolParameters({ + required this.ourIdentityKey, + required this.ourSignedPreKey, + required this.ourRatchetKey, + required this.ourOneTimePreKey, + required this.theirIdentityKey, + required this.theirBaseKey, + }); + + final IdentityKeyPair ourIdentityKey; + final ECKeyPair ourSignedPreKey; + final Optional ourOneTimePreKey; + final ECKeyPair ourRatchetKey; + + final IdentityKey theirIdentityKey; + final ECPublicKey theirBaseKey; + + IdentityKeyPair getOurIdentityKey() => ourIdentityKey; + + ECKeyPair getOurSignedPreKey() => ourSignedPreKey; + + Optional getOurOneTimePreKey() => ourOneTimePreKey; + + IdentityKey getTheirIdentityKey() => theirIdentityKey; + + ECPublicKey getTheirBaseKey() => theirBaseKey; + + ECKeyPair getOurRatchetKey() => ourRatchetKey; +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/chain_key.dart b/libsignal_protocol_dart/lib/src/ratchet/chain_key.dart new file mode 100644 index 0000000..9fc1186 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/chain_key.dart @@ -0,0 +1,46 @@ +import 'dart:convert'; +import 'dart:core'; +import 'dart:typed_data'; + +import 'package:crypto/crypto.dart'; +import '../kdf/derived_message_secrets.dart'; +import '../kdf/hkdf.dart'; +import '../ratchet/message_keys.dart'; + +class ChainKey { + ChainKey(this._kdf, this._key, this._index); + + static final Uint8List messageKeySeed = Uint8List.fromList([0x01]); + static final Uint8List chainKeySeed = Uint8List.fromList([0x02]); + + final HKDF _kdf; + final Uint8List _key; + final int _index; + + Uint8List get key => _key; + + int get index => _index; + + ChainKey getNextChainKey() { + final nextKey = _getBaseMaterial(chainKeySeed); + return ChainKey(_kdf, nextKey, _index + 1); + } + + MessageKeys getMessageKeys() { + final bytes = Uint8List.fromList(utf8.encode('WhisperMessageKeys')); + + final inputKeyMaterial = _getBaseMaterial(messageKeySeed); + final keyMaterialBytes = + _kdf.deriveSecrets(inputKeyMaterial, bytes, DerivedMessageSecrets.size); + final keyMaterial = DerivedMessageSecrets(keyMaterialBytes); + + return MessageKeys(keyMaterial.getCipherKey(), keyMaterial.getMacKey(), + keyMaterial.getIv(), _index); + } + + Uint8List _getBaseMaterial(Uint8List seed) { + final hmacSha256 = Hmac(sha256, _key); + final digest = hmacSha256.convert(seed); + return Uint8List.fromList(digest.bytes); + } +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/message_keys.dart b/libsignal_protocol_dart/lib/src/ratchet/message_keys.dart new file mode 100644 index 0000000..8c0d1e1 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/message_keys.dart @@ -0,0 +1,18 @@ +import 'dart:typed_data'; + +class MessageKeys { + MessageKeys(this.cipherKey, this.macKey, this.iv, this.counter); + + final Uint8List cipherKey; + final Uint8List macKey; + final Uint8List iv; + final int counter; + + Uint8List getCipherKey() => cipherKey; + + Uint8List getMacKey() => macKey; + + Uint8List getIv() => iv; + + int getCounter() => counter; +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/ratcheting_session.dart b/libsignal_protocol_dart/lib/src/ratchet/ratcheting_session.dart new file mode 100644 index 0000000..3b97872 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/ratcheting_session.dart @@ -0,0 +1,151 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:optional/optional.dart'; + +import '../ecc/curve.dart'; +import '../ecc/ec_key_pair.dart'; +import '../ecc/ec_public_key.dart'; +import '../kdf/hkdf.dart'; +import '../kdf/hkdfv3.dart'; +import '../protocol/ciphertext_message.dart'; +import '../ratchet/alice_signal_protocol_parameters.dart'; +import '../ratchet/bob_signal_protocol_parameters.dart'; +import '../ratchet/chain_key.dart'; +import '../ratchet/root_key.dart'; +import '../ratchet/symmetric_signal_protocol_parameters.dart'; +import '../state/session_state.dart'; +import '../util/byte_util.dart'; + +class RatchetingSession { + static void initializeSession( + SessionState sessionState, SymmetricSignalProtocolParameters parameters) { + if (isAlice(parameters.ourBaseKey.publicKey, parameters.theirBaseKey)) { + final aliceParameters = AliceSignalProtocolParameters( + ourBaseKey: parameters.ourBaseKey, + ourIdentityKey: parameters.ourIdentityKey, + theirRatchetKey: parameters.theirRatchetKey, + theirIdentityKey: parameters.theirIdentityKey, + theirSignedPreKey: parameters.theirBaseKey, + theirOneTimePreKey: const Optional.empty(), + ); + RatchetingSession.initializeSessionAlice(sessionState, aliceParameters); + } else { + final bobParameters = BobSignalProtocolParameters( + ourIdentityKey: parameters.ourIdentityKey, + ourRatchetKey: parameters.ourRatchetKey, + ourSignedPreKey: parameters.ourBaseKey, + ourOneTimePreKey: const Optional.empty(), + theirBaseKey: parameters.theirBaseKey, + theirIdentityKey: parameters.theirIdentityKey, + ); + + RatchetingSession.initializeSessionBob(sessionState, bobParameters); + } + } + + static void initializeSessionAlice( + SessionState sessionState, AliceSignalProtocolParameters parameters) { + try { + sessionState + ..sessionVersion = CiphertextMessage.currentVersion + ..remoteIdentityKey = parameters.theirIdentityKey + ..localIdentityKey = parameters.ourIdentityKey.getPublicKey(); + + final sendingRatchetKey = Curve.generateKeyPair(); + final secrets = [ + ...getDiscontinuityBytes(), + ...Curve.calculateAgreement(parameters.theirSignedPreKey, + parameters.ourIdentityKey.getPrivateKey()), + ...Curve.calculateAgreement(parameters.theirIdentityKey.publicKey, + parameters.ourBaseKey.privateKey), + ...Curve.calculateAgreement( + parameters.theirSignedPreKey, parameters.ourBaseKey.privateKey) + ]; + + if (parameters.theirOneTimePreKey.isPresent) { + secrets.addAll(Curve.calculateAgreement( + parameters.theirOneTimePreKey.value, + parameters.ourBaseKey.privateKey)); + } + + final derivedKeys = calculateDerivedKeys(Uint8List.fromList(secrets)); + final sendingChain = derivedKeys + .getRootKey() + .createChain(parameters.theirRatchetKey, sendingRatchetKey); + + sessionState + ..addReceiverChain( + parameters.theirRatchetKey, derivedKeys.getChainKey()) + ..setSenderChain(sendingRatchetKey, sendingChain.$2) + ..rootKey = sendingChain.$1; + } on Exception catch (e) { + throw AssertionError(e); + } + } + + static void initializeSessionBob( + SessionState sessionState, BobSignalProtocolParameters parameters) { + try { + sessionState + ..sessionVersion = CiphertextMessage.currentVersion + ..remoteIdentityKey = parameters.theirIdentityKey + ..localIdentityKey = parameters.ourIdentityKey.getPublicKey(); + + final secrets = [ + ...getDiscontinuityBytes(), + ...Curve.calculateAgreement(parameters.theirIdentityKey.publicKey, + parameters.ourSignedPreKey.privateKey), + ...Curve.calculateAgreement( + parameters.theirBaseKey, parameters.ourIdentityKey.getPrivateKey()), + ...Curve.calculateAgreement( + parameters.theirBaseKey, parameters.ourSignedPreKey.privateKey) + ]; + if (parameters.ourOneTimePreKey.isPresent) { + secrets.addAll(Curve.calculateAgreement(parameters.theirBaseKey, + parameters.ourOneTimePreKey.value.privateKey)); + } + + final derivedKeys = calculateDerivedKeys(Uint8List.fromList(secrets)); + + sessionState + ..setSenderChain(parameters.ourRatchetKey, derivedKeys.getChainKey()) + ..rootKey = derivedKeys.getRootKey(); + } on Exception catch (e) { + throw AssertionError(e); + } + } + + static Uint8List getDiscontinuityBytes() { + final discontinuity = Uint8List(32); + final len = discontinuity.length; + for (var i = 0; i < len; i++) { + discontinuity[i] = 0xFF; + } + return discontinuity; + } + + static DerivedKeys calculateDerivedKeys(Uint8List masterSecret) { + final HKDF kdf = HKDFv3(); + final bytes = Uint8List.fromList(utf8.encode('WhisperText')); + final derivedSecretBytes = kdf.deriveSecrets(masterSecret, bytes, 64); + final derivedSecrets = ByteUtil.splitTwo(derivedSecretBytes, 32, 32); + + return DerivedKeys( + RootKey(kdf, derivedSecrets[0]), ChainKey(kdf, derivedSecrets[1], 0)); + } + + static bool isAlice(ECPublicKey ourKey, ECPublicKey theirKey) => + ourKey.compareTo(theirKey) < 0; +} + +class DerivedKeys { + DerivedKeys(this._rootKey, this._chainKey); + + final RootKey _rootKey; + final ChainKey _chainKey; + + RootKey getRootKey() => _rootKey; + + ChainKey getChainKey() => _chainKey; +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/root_key.dart b/libsignal_protocol_dart/lib/src/ratchet/root_key.dart new file mode 100644 index 0000000..9fcd1cd --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/root_key.dart @@ -0,0 +1,33 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import '../ecc/curve.dart'; +import '../ecc/ec_key_pair.dart'; +import '../ecc/ec_public_key.dart'; +import '../kdf/derived_root_secrets.dart'; +import '../kdf/hkdf.dart'; +import '../ratchet/chain_key.dart'; + +class RootKey { + RootKey(this._kdf, this._key); + + final HKDF _kdf; + final Uint8List _key; + + Uint8List getKeyBytes() => _key; + + (RootKey, ChainKey) createChain( + ECPublicKey theirRatchetKey, ECKeyPair ourRatchetKey) { + final sharedSecret = + Curve.calculateAgreement(theirRatchetKey, ourRatchetKey.privateKey); + final bytes = Uint8List.fromList(utf8.encode('WhisperRatchet')); + final derivedSecretBytes = + _kdf.deriveSecrets4(sharedSecret, _key, bytes, DerivedRootSecrets.size); + final derivedSecrets = DerivedRootSecrets(derivedSecretBytes); + + final newRootKey = RootKey(_kdf, derivedSecrets.getRootKey()); + final newChainKey = ChainKey(_kdf, derivedSecrets.getChainKey(), 0); + + return (newRootKey, newChainKey); + } +} diff --git a/libsignal_protocol_dart/lib/src/ratchet/symmetric_signal_protocol_parameters.dart b/libsignal_protocol_dart/lib/src/ratchet/symmetric_signal_protocol_parameters.dart new file mode 100644 index 0000000..d90703b --- /dev/null +++ b/libsignal_protocol_dart/lib/src/ratchet/symmetric_signal_protocol_parameters.dart @@ -0,0 +1,23 @@ +import '../ecc/ec_key_pair.dart'; +import '../ecc/ec_public_key.dart'; +import '../identity_key.dart'; +import '../identity_key_pair.dart'; + +class SymmetricSignalProtocolParameters { + SymmetricSignalProtocolParameters({ + required this.ourBaseKey, + required this.ourRatchetKey, + required this.ourIdentityKey, + required this.theirBaseKey, + required this.theirRatchetKey, + required this.theirIdentityKey, + }); + + final ECKeyPair ourBaseKey; + final ECKeyPair ourRatchetKey; + final IdentityKeyPair ourIdentityKey; + + final ECPublicKey theirBaseKey; + final ECPublicKey theirRatchetKey; + final IdentityKey theirIdentityKey; +} diff --git a/libsignal_protocol_dart/lib/src/session_builder.dart b/libsignal_protocol_dart/lib/src/session_builder.dart new file mode 100644 index 0000000..b0ad558 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/session_builder.dart @@ -0,0 +1,156 @@ +import 'package:optional/optional.dart'; + +import 'ecc/curve.dart'; +import 'ecc/ec_key_pair.dart'; +import 'invalid_key_exception.dart'; +import 'protocol/pre_key_signal_message.dart'; +import 'ratchet/alice_signal_protocol_parameters.dart'; +import 'ratchet/bob_signal_protocol_parameters.dart'; +import 'ratchet/ratcheting_session.dart'; +import 'signal_protocol_address.dart'; +import 'state/identity_key_store.dart'; +import 'state/pre_key_bundle.dart'; +import 'state/pre_key_store.dart'; +import 'state/session_record.dart'; +import 'state/session_store.dart'; +import 'state/signal_protocol_store.dart'; +import 'state/signed_pre_key_store.dart'; +import 'untrusted_identity_exception.dart'; +import 'util/log.dart' as $log; + +class SessionBuilder { + SessionBuilder(this._sessionStore, this._preKeyStore, this._signedPreKeyStore, + this._identityKeyStore, this._remoteAddress); + + SessionBuilder.fromSignalStore( + SignalProtocolStore store, SignalProtocolAddress remoteAddress) + : this(store, store, store, store, remoteAddress); + + static const String tag = 'SessionBuilder'; + + SessionStore _sessionStore; + PreKeyStore _preKeyStore; + SignedPreKeyStore _signedPreKeyStore; + IdentityKeyStore _identityKeyStore; + SignalProtocolAddress _remoteAddress; + + Future> process( + SessionRecord sessionRecord, PreKeySignalMessage message) async { + final theirIdentityKey = message.getIdentityKey(); + + if (!await _identityKeyStore.isTrustedIdentity( + _remoteAddress, theirIdentityKey, Direction.receiving)) { + throw UntrustedIdentityException( + _remoteAddress.getName(), theirIdentityKey); + } + + final unsignedPreKeyId = processV3(sessionRecord, message); + + await _identityKeyStore.saveIdentity(_remoteAddress, theirIdentityKey); + + return unsignedPreKeyId; + } + + Future> processV3( + SessionRecord sessionRecord, PreKeySignalMessage message) async { + if (sessionRecord.hasSessionState( + message.getMessageVersion(), message.getBaseKey().serialize())) { + $log.log( + "We've already setup a session for this V3 message, letting bundled message fall through..."); + return const Optional.empty(); + } + + final ourSignedPreKey = _signedPreKeyStore + .loadSignedPreKey(message.getSignedPreKeyId()) + .then((value) => value.getKeyPair()); + + late final Optional ourOneTimePreKey; + if (message.getPreKeyId().isPresent) { + ourOneTimePreKey = Optional.of(await _preKeyStore + .loadPreKey(message.getPreKeyId().value) + .then((value) => value.getKeyPair())); + } else { + ourOneTimePreKey = const Optional.empty(); + } + + if (!sessionRecord.isFresh()) sessionRecord.archiveCurrentState(); + + final parameters = BobSignalProtocolParameters( + theirBaseKey: message.getBaseKey(), + theirIdentityKey: message.getIdentityKey(), + ourIdentityKey: await _identityKeyStore.getIdentityKeyPair(), + ourSignedPreKey: await ourSignedPreKey, + ourRatchetKey: await ourSignedPreKey, + ourOneTimePreKey: ourOneTimePreKey, + ); + + RatchetingSession.initializeSessionBob( + sessionRecord.sessionState, parameters); + + sessionRecord.sessionState.localRegistrationId = + await _identityKeyStore.getLocalRegistrationId(); + sessionRecord.sessionState.remoteRegistrationId = + message.getRegistrationId(); + sessionRecord.sessionState.aliceBaseKey = message.getBaseKey().serialize(); + + if (message.getPreKeyId().isPresent) { + return message.getPreKeyId(); + } else { + return const Optional.empty(); + } + } + + Future processPreKeyBundle(PreKeyBundle preKey) async { + if (!await _identityKeyStore.isTrustedIdentity( + _remoteAddress, preKey.getIdentityKey(), Direction.sending)) { + throw UntrustedIdentityException( + _remoteAddress.getName(), preKey.getIdentityKey()); + } + + if (preKey.getSignedPreKey() != null && + !Curve.verifySignature( + preKey.getIdentityKey().publicKey, + preKey.getSignedPreKey()!.serialize(), + preKey.getSignedPreKeySignature())) { + throw InvalidKeyException('Invalid signature on device key!'); + } + + if (preKey.getSignedPreKey() == null) { + throw InvalidKeyException('No signed prekey!'); + } + + final sessionRecord = await _sessionStore.loadSession(_remoteAddress); + final ourBaseKey = Curve.generateKeyPair(); + final theirSignedPreKey = preKey.getSignedPreKey(); + final theirOneTimePreKey = Optional.ofNullable(preKey.getPreKey()); + final theirOneTimePreKeyId = theirOneTimePreKey.isPresent + ? Optional.ofNullable(preKey.getPreKeyId()) + : const Optional.empty(); + + final parameters = AliceSignalProtocolParameters( + ourBaseKey: ourBaseKey, + ourIdentityKey: await _identityKeyStore.getIdentityKeyPair(), + theirIdentityKey: preKey.getIdentityKey(), + theirSignedPreKey: theirSignedPreKey!, + theirRatchetKey: theirSignedPreKey, + theirOneTimePreKey: theirOneTimePreKey, + ); + + if (!sessionRecord.isFresh()) sessionRecord.archiveCurrentState(); + + RatchetingSession.initializeSessionAlice( + sessionRecord.sessionState, parameters); + + sessionRecord.sessionState.setUnacknowledgedPreKeyMessage( + theirOneTimePreKeyId, preKey.getSignedPreKeyId(), ourBaseKey.publicKey); + sessionRecord.sessionState.localRegistrationId = + await _identityKeyStore.getLocalRegistrationId(); + sessionRecord.sessionState.remoteRegistrationId = + preKey.getRegistrationId(); + sessionRecord.sessionState.aliceBaseKey = ourBaseKey.publicKey.serialize(); + + await _identityKeyStore.saveIdentity( + _remoteAddress, preKey.getIdentityKey()); + await _sessionStore.storeSession(_remoteAddress, sessionRecord); + } +} diff --git a/libsignal_protocol_dart/lib/src/session_cipher.dart b/libsignal_protocol_dart/lib/src/session_cipher.dart new file mode 100644 index 0000000..7a0fd37 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/session_cipher.dart @@ -0,0 +1,290 @@ +import 'dart:collection'; +import 'dart:core'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'cbc.dart'; +import 'decryption_callback.dart'; +import 'duplicate_message_exception.dart'; +import 'ecc/curve.dart'; +import 'ecc/ec_public_key.dart'; +import 'invalid_key_exception.dart'; +import 'invalid_message_exception.dart'; +import 'no_session_exception.dart'; +import 'protocol/ciphertext_message.dart'; +import 'protocol/pre_key_signal_message.dart'; +import 'protocol/signal_message.dart'; +import 'ratchet/chain_key.dart'; +import 'ratchet/message_keys.dart'; +import 'session_builder.dart'; +import 'signal_protocol_address.dart'; +import 'state/identity_key_store.dart'; +import 'state/pre_key_store.dart'; +import 'state/session_record.dart'; +import 'state/session_state.dart'; +import 'state/session_store.dart'; +import 'state/signal_protocol_store.dart'; +import 'state/signed_pre_key_store.dart'; +import 'untrusted_identity_exception.dart'; + +class SessionCipher { + SessionCipher( + this._sessionStore, + this._preKeyStore, + SignedPreKeyStore signedPreKeyStore, + this._identityKeyStore, + this._remoteAddress) { + _sessionBuilder = SessionBuilder(_sessionStore, _preKeyStore, + signedPreKeyStore, _identityKeyStore, _remoteAddress); + } + + SessionCipher.fromStore( + SignalProtocolStore store, SignalProtocolAddress remoteAddress) + : this(store, store, store, store, remoteAddress); + + static final Object sessionLock = Object(); + + SessionStore _sessionStore; + IdentityKeyStore _identityKeyStore; + late SessionBuilder _sessionBuilder; + PreKeyStore _preKeyStore; + SignalProtocolAddress _remoteAddress; + + Future encrypt(Uint8List paddedMessage) async { + final sessionRecord = await _sessionStore.loadSession(_remoteAddress); + final sessionState = sessionRecord.sessionState; + final chainKey = sessionState.getSenderChainKey(); + final messageKeys = chainKey.getMessageKeys(); + final senderEphemeral = sessionState.getSenderRatchetKey(); + final previousCounter = sessionState.previousCounter; + final sessionVersion = sessionState.getSessionVersion(); + + final ciphertextBody = getCiphertext(messageKeys, paddedMessage); + CiphertextMessage ciphertextMessage = SignalMessage( + sessionVersion, + messageKeys.getMacKey(), + senderEphemeral, + chainKey.index, + previousCounter, + ciphertextBody, + sessionState.getLocalIdentityKey(), + sessionState.getRemoteIdentityKey()); + if (sessionState.hasUnacknowledgedPreKeyMessage()) { + final items = sessionState.getUnacknowledgedPreKeyMessageItems(); + final localRegistrationId = sessionState.localRegistrationId; + + ciphertextMessage = PreKeySignalMessage.from( + sessionVersion, + localRegistrationId, + items.getPreKeyId(), + items.getSignedPreKeyId(), + items.getBaseKey(), + sessionState.getLocalIdentityKey(), + ciphertextMessage as SignalMessage); + } + + final nextChainKey = chainKey.getNextChainKey(); + sessionState.setSenderChainKey(nextChainKey); + + if (!await _identityKeyStore.isTrustedIdentity(_remoteAddress, + sessionState.getRemoteIdentityKey(), Direction.sending)) { + throw UntrustedIdentityException( + _remoteAddress.getName(), sessionState.getRemoteIdentityKey()); + } + + await _identityKeyStore.saveIdentity( + _remoteAddress, sessionState.getRemoteIdentityKey()); + await _sessionStore.storeSession(_remoteAddress, sessionRecord); + return ciphertextMessage; + } + + Future decrypt(PreKeySignalMessage ciphertext) async => + decryptWithCallback(ciphertext, () {}()); + + Future decryptWithCallback( + PreKeySignalMessage ciphertext, DecryptionCallback? callback) async { + final sessionRecord = await _sessionStore.loadSession(_remoteAddress); + final unsignedPreKeyId = + await _sessionBuilder.process(sessionRecord, ciphertext); + final plaintext = _decrypt(sessionRecord, ciphertext.getWhisperMessage()); + + if (callback != null) { + callback(plaintext); + } + + await _sessionStore.storeSession(_remoteAddress, sessionRecord); + + if (unsignedPreKeyId.isPresent) { + await _preKeyStore.removePreKey(unsignedPreKeyId.value); + } + + return plaintext; + } + + Future decryptFromSignal(SignalMessage cipherText) async => + decryptFromSignalWithCallback(cipherText, () {}()); + + Future decryptFromSignalWithCallback( + SignalMessage cipherText, DecryptionCallback? callback) async { + if (!await _sessionStore.containsSession(_remoteAddress)) { + throw NoSessionException('No session for: $_remoteAddress'); + } + + final sessionRecord = await _sessionStore.loadSession(_remoteAddress); + final plaintext = _decrypt(sessionRecord, cipherText); + + if (!await _identityKeyStore.isTrustedIdentity( + _remoteAddress, + sessionRecord.sessionState.getRemoteIdentityKey(), + Direction.receiving)) { + throw UntrustedIdentityException(_remoteAddress.getName(), + sessionRecord.sessionState.getRemoteIdentityKey()); + } + + await _identityKeyStore.saveIdentity( + _remoteAddress, sessionRecord.sessionState.getRemoteIdentityKey()); + + if (callback != null) { + callback(plaintext); + } + + await _sessionStore.storeSession(_remoteAddress, sessionRecord); + + return plaintext; + } + + Uint8List _decrypt(SessionRecord sessionRecord, SignalMessage cipherText) { + final previousStates = sessionRecord.previousSessionStates; + final exceptions = []; + + try { + final sessionState = + SessionState.fromSessionState(sessionRecord.sessionState); + final plaintext = _decryptFromState(sessionState, cipherText); + + sessionRecord.state = sessionState; + return plaintext; + } on InvalidMessageException catch (e) { + exceptions.add(e); + } + // ignore: deprecated_member_use + final pStates = HasNextIterator(previousStates.iterator); + while (pStates.hasNext) { + try { + final promotedState = SessionState.fromSessionState(pStates.next()); + final plaintext = _decryptFromState(promotedState, cipherText); + + previousStates.remove(promotedState); + sessionRecord.promoteState(promotedState); + + return plaintext; + } on InvalidMessageException catch (e) { + exceptions.add(e); + } + } + + throw InvalidMessageException('No valid sessions. $exceptions[0]'); + } + + Uint8List _decryptFromState( + SessionState sessionState, SignalMessage ciphertextMessage) { + if (!sessionState.hasSenderChain()) { + throw InvalidMessageException('Uninitialized session!'); + } + + if (ciphertextMessage.getMessageVersion() != + sessionState.getSessionVersion()) { + throw InvalidMessageException( + 'Message version $ciphertextMessage.getMessageVersion(), but session version $sessionState.getSessionVersion()'); + } + + final theirEphemeral = ciphertextMessage.getSenderRatchetKey(); + final counter = ciphertextMessage.getCounter(); + final chainKey = _getOrCreateChainKey(sessionState, theirEphemeral); + final messageKeys = _getOrCreateMessageKeys( + sessionState, theirEphemeral, chainKey!, counter); + + ciphertextMessage.verifyMac(sessionState.getRemoteIdentityKey()!, + sessionState.getLocalIdentityKey(), messageKeys!.getMacKey()); + + final plaintext = _getPlaintext(messageKeys, ciphertextMessage.getBody()); + + sessionState.clearUnacknowledgedPreKeyMessage(); + + return plaintext; + } + + Future getRemoteRegistrationId() async { + final record = await _sessionStore.loadSession(_remoteAddress); + return record.sessionState.remoteRegistrationId; + } + + Future getSessionVersion() async { + if (!await _sessionStore.containsSession(_remoteAddress)) { + // throw IllegalStateException("No session for ($_remoteAddress)!"); + } + + final record = await _sessionStore.loadSession(_remoteAddress); + return record.sessionState.getSessionVersion(); + } + + ChainKey? _getOrCreateChainKey( + SessionState sessionState, ECPublicKey theirEphemeral) { + try { + if (sessionState.hasReceiverChain(theirEphemeral)) { + return sessionState.getReceiverChainKey(theirEphemeral); + } else { + final rootKey = sessionState.getRootKey(); + final ourEphemeral = sessionState.getSenderRatchetKeyPair(); + final receiverChain = rootKey.createChain(theirEphemeral, ourEphemeral); + final ourNewEphemeral = Curve.generateKeyPair(); + final senderChain = + receiverChain.$1.createChain(theirEphemeral, ourNewEphemeral); + + sessionState + ..rootKey = senderChain.$1 + ..addReceiverChain(theirEphemeral, receiverChain.$2) + ..previousCounter = max(sessionState.getSenderChainKey().index - 1, 0) + ..setSenderChain(ourNewEphemeral, senderChain.$2); + + return receiverChain.$2; + } + } on InvalidKeyException { + rethrow; + } + } + + MessageKeys? _getOrCreateMessageKeys(SessionState sessionState, + ECPublicKey theirEphemeral, ChainKey chainKey, int counter) { + if (chainKey.index > counter) { + if (sessionState.hasMessageKeys(theirEphemeral, counter)) { + return sessionState.removeMessageKeys(theirEphemeral, counter); + } else { + throw DuplicateMessageException( + 'Received message with old counter: ${chainKey.index}, $counter'); + } + } + + if (counter - chainKey.index > 2000) { + throw InvalidMessageException('Over 2000 messages into the future!'); + } + + while (chainKey.index < counter) { + final messageKeys = chainKey.getMessageKeys(); + sessionState.setMessageKeys(theirEphemeral, messageKeys); + // ignore: parameter_assignments + chainKey = chainKey.getNextChainKey(); + } + + sessionState.setReceiverChainKey( + theirEphemeral, chainKey.getNextChainKey()); + return chainKey.getMessageKeys(); + } + + Uint8List getCiphertext(MessageKeys messageKeys, Uint8List plaintext) => + aesCbcEncrypt(messageKeys.getCipherKey(), messageKeys.getIv(), plaintext); + + Uint8List _getPlaintext(MessageKeys messageKeys, Uint8List cipherText) => + aesCbcDecrypt( + messageKeys.getCipherKey(), messageKeys.getIv(), cipherText); +} diff --git a/libsignal_protocol_dart/lib/src/signal_protocol_address.dart b/libsignal_protocol_dart/lib/src/signal_protocol_address.dart new file mode 100644 index 0000000..f0dd6e9 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/signal_protocol_address.dart @@ -0,0 +1,26 @@ +import 'package:meta/meta.dart'; + +@immutable +class SignalProtocolAddress { + const SignalProtocolAddress(this._name, this._deviceId); + + final String _name; + final int _deviceId; + + String getName() => _name; + + int getDeviceId() => _deviceId; + + @override + String toString() => '$_name:$_deviceId'; + + @override + bool operator ==(Object other) { + if (other is! SignalProtocolAddress) return false; + + return _name == other._name && _deviceId == other._deviceId; + } + + @override + int get hashCode => _name.hashCode ^ _deviceId; +} diff --git a/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart new file mode 100644 index 0000000..65f7476 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart @@ -0,0 +1,225 @@ +import 'dart:core' as $core; +import 'dart:core'; + +import 'package:protobuf/protobuf.dart' as $pb; + +class LogicalFingerprint extends $pb.GeneratedMessage { + factory LogicalFingerprint({ + $core.List<$core.int>? content, + }) { + final _result = create(); + if (content != null) { + _result.content = content; + } + return _result; + } + + LogicalFingerprint._() : super(); + + factory LogicalFingerprint.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory LogicalFingerprint.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'LogicalFingerprint', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'content', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + LogicalFingerprint clone() => LogicalFingerprint()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + LogicalFingerprint copyWith(void Function(LogicalFingerprint) updates) => + super.copyWith((message) => updates(message as LogicalFingerprint)) + as LogicalFingerprint; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static LogicalFingerprint create() => LogicalFingerprint._(); + + @override + LogicalFingerprint createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static LogicalFingerprint getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static LogicalFingerprint? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get content => $_getN(0); + + @$pb.TagNumber(1) + set content($core.List<$core.int> v) { + $_setBytes(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasContent() => $_has(0); + + @$pb.TagNumber(1) + void clearContent() => clearField(1); +} + +class CombinedFingerprints extends $pb.GeneratedMessage { + factory CombinedFingerprints({ + $core.int? version, + LogicalFingerprint? localFingerprint, + LogicalFingerprint? remoteFingerprint, + }) { + final _result = create(); + if (version != null) { + _result.version = version; + } + if (localFingerprint != null) { + _result.localFingerprint = localFingerprint; + } + if (remoteFingerprint != null) { + _result.remoteFingerprint = remoteFingerprint; + } + return _result; + } + + CombinedFingerprints._() : super(); + + factory CombinedFingerprints.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory CombinedFingerprints.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'CombinedFingerprints', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'version', + $pb.PbFieldType.OU3) + ..aOM( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localFingerprint', + protoName: 'localFingerprint', + subBuilder: LogicalFingerprint.create) + ..aOM( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'remoteFingerprint', + protoName: 'remoteFingerprint', + subBuilder: LogicalFingerprint.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + CombinedFingerprints clone() => + CombinedFingerprints()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + CombinedFingerprints copyWith(void Function(CombinedFingerprints) updates) => + super.copyWith((message) => updates(message as CombinedFingerprints)) + as CombinedFingerprints; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static CombinedFingerprints create() => CombinedFingerprints._(); + + @override + CombinedFingerprints createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static CombinedFingerprints getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static CombinedFingerprints? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get version => $_getIZ(0); + + @$pb.TagNumber(1) + set version($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasVersion() => $_has(0); + + @$pb.TagNumber(1) + void clearVersion() => clearField(1); + + @$pb.TagNumber(2) + LogicalFingerprint get localFingerprint => $_getN(1); + + @$pb.TagNumber(2) + set localFingerprint(LogicalFingerprint v) { + setField(2, v); + } + + @$pb.TagNumber(2) + $core.bool hasLocalFingerprint() => $_has(1); + + @$pb.TagNumber(2) + void clearLocalFingerprint() => clearField(2); + + @$pb.TagNumber(2) + LogicalFingerprint ensureLocalFingerprint() => $_ensure(1); + + @$pb.TagNumber(3) + LogicalFingerprint get remoteFingerprint => $_getN(2); + + @$pb.TagNumber(3) + set remoteFingerprint(LogicalFingerprint v) { + setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasRemoteFingerprint() => $_has(2); + + @$pb.TagNumber(3) + void clearRemoteFingerprint() => clearField(3); + + @$pb.TagNumber(3) + LogicalFingerprint ensureRemoteFingerprint() => $_ensure(2); +} diff --git a/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbenum.dart b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbenum.dart new file mode 100644 index 0000000..2427c36 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbenum.dart @@ -0,0 +1,5 @@ +// Generated code. Do not modify. +// source: FingerprintProtocol.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields diff --git a/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbjson.dart b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbjson.dart new file mode 100644 index 0000000..0b868c8 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbjson.dart @@ -0,0 +1,43 @@ +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use logicalFingerprintDescriptor instead') +const logicalFingerprint$json = { + '1': 'LogicalFingerprint', + '2': [ + {'1': 'content', '3': 1, '4': 1, '5': 12, '10': 'content'}, + ], +}; + +/// Descriptor for `LogicalFingerprint`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List logicalFingerprintDescriptor = + $convert.base64Decode( + 'ChJMb2dpY2FsRmluZ2VycHJpbnQSGAoHY29udGVudBgBIAEoDFIHY29udGVudA=='); +@$core.Deprecated('Use combinedFingerprintsDescriptor instead') +const sombinedFingerprints$json = { + '1': 'CombinedFingerprints', + '2': [ + {'1': 'version', '3': 1, '4': 1, '5': 13, '10': 'version'}, + { + '1': 'localFingerprint', + '3': 2, + '4': 1, + '5': 11, + '6': '.textsecure.LogicalFingerprint', + '10': 'localFingerprint' + }, + { + '1': 'remoteFingerprint', + '3': 3, + '4': 1, + '5': 11, + '6': '.textsecure.LogicalFingerprint', + '10': 'remoteFingerprint' + }, + ], +}; + +/// Descriptor for `CombinedFingerprints`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List combinedFingerprintsDescriptor = $convert.base64Decode( + 'ChRDb21iaW5lZEZpbmdlcnByaW50cxIYCgd2ZXJzaW9uGAEgASgNUgd2ZXJzaW9uEkoKEGxvY2FsRmluZ2VycHJpbnQYAiABKAsyHi50ZXh0c2VjdXJlLkxvZ2ljYWxGaW5nZXJwcmludFIQbG9jYWxGaW5nZXJwcmludBJMChFyZW1vdGVGaW5nZXJwcmludBgDIAEoCzIeLnRleHRzZWN1cmUuTG9naWNhbEZpbmdlcnByaW50UhFyZW1vdGVGaW5nZXJwcmludA=='); diff --git a/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbserver.dart b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbserver.dart new file mode 100644 index 0000000..a0f7ec9 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pbserver.dart @@ -0,0 +1,7 @@ +// Generated code. Do not modify. +// source: FingerprintProtocol.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'fingerprint_protocol.pb.dart'; diff --git a/libsignal_protocol_dart/lib/src/state/identity_key_store.dart b/libsignal_protocol_dart/lib/src/state/identity_key_store.dart new file mode 100644 index 0000000..f542af6 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/identity_key_store.dart @@ -0,0 +1,20 @@ +import '../identity_key.dart'; +import '../identity_key_pair.dart'; +import '../signal_protocol_address.dart'; + +enum Direction { sending, receiving } + +abstract class IdentityKeyStore { + Future getIdentityKeyPair(); + Future getLocalRegistrationId(); + Future saveIdentity( + SignalProtocolAddress address, + IdentityKey? identityKey, + ); + Future isTrustedIdentity( + SignalProtocolAddress address, + IdentityKey? identityKey, + Direction direction, + ); + Future getIdentity(SignalProtocolAddress address); +} diff --git a/libsignal_protocol_dart/lib/src/state/impl/in_memory_identity_key_store.dart b/libsignal_protocol_dart/lib/src/state/impl/in_memory_identity_key_store.dart new file mode 100644 index 0000000..8dc8c50 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/impl/in_memory_identity_key_store.dart @@ -0,0 +1,51 @@ +import 'dart:collection'; + +import '../../eq.dart'; +import '../../identity_key.dart'; +import '../../identity_key_pair.dart'; +import '../../signal_protocol_address.dart'; +import '../identity_key_store.dart'; + +class InMemoryIdentityKeyStore extends IdentityKeyStore { + InMemoryIdentityKeyStore(this.identityKeyPair, this.localRegistrationId); + + final trustedKeys = HashMap(); + + final IdentityKeyPair identityKeyPair; + final int localRegistrationId; + + @override + Future getIdentity(SignalProtocolAddress address) async => + trustedKeys[address]!; + + @override + Future getIdentityKeyPair() async => identityKeyPair; + + @override + Future getLocalRegistrationId() async => localRegistrationId; + + @override + Future isTrustedIdentity(SignalProtocolAddress address, + IdentityKey? identityKey, Direction? direction) async { + final trusted = trustedKeys[address]; + if (identityKey == null) { + return false; + } + return trusted == null || eq(trusted.serialize(), identityKey.serialize()); + } + + @override + Future saveIdentity( + SignalProtocolAddress address, IdentityKey? identityKey) async { + final existing = trustedKeys[address]; + if (identityKey == null) { + return false; + } + if (identityKey != existing) { + trustedKeys[address] = identityKey; + return true; + } else { + return false; + } + } +} diff --git a/libsignal_protocol_dart/lib/src/state/impl/in_memory_pre_key_store.dart b/libsignal_protocol_dart/lib/src/state/impl/in_memory_pre_key_store.dart new file mode 100644 index 0000000..69c65b0 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/impl/in_memory_pre_key_store.dart @@ -0,0 +1,32 @@ +import 'dart:collection'; +import 'dart:typed_data'; + +import '../../invalid_key_id_exception.dart'; +import '../pre_key_record.dart'; +import '../pre_key_store.dart'; + +class InMemoryPreKeyStore extends PreKeyStore { + final store = HashMap(); + + @override + Future containsPreKey(int preKeyId) async => + store.containsKey(preKeyId); + + @override + Future loadPreKey(int preKeyId) async { + if (!store.containsKey(preKeyId)) { + throw InvalidKeyIdException('No such prekeyrecord! - $preKeyId'); + } + return PreKeyRecord.fromBuffer(store[preKeyId]!); + } + + @override + Future removePreKey(int preKeyId) async { + store.remove(preKeyId); + } + + @override + Future storePreKey(int preKeyId, PreKeyRecord record) async { + store[preKeyId] = record.serialize(); + } +} diff --git a/libsignal_protocol_dart/lib/src/state/impl/in_memory_session_store.dart b/libsignal_protocol_dart/lib/src/state/impl/in_memory_session_store.dart new file mode 100644 index 0000000..9d2c057 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/impl/in_memory_session_store.dart @@ -0,0 +1,63 @@ +import 'dart:collection'; +import 'dart:typed_data'; + +import '../../signal_protocol_address.dart'; +import '../session_record.dart'; +import '../session_store.dart'; + +class InMemorySessionStore extends SessionStore { + InMemorySessionStore(); + + HashMap sessions = + HashMap(); + + @override + Future containsSession(SignalProtocolAddress address) async => + sessions.containsKey(address); + + @override + Future deleteAllSessions(String name) async { + for (final k in sessions.keys.toList()) { + if (k.getName() == name) { + sessions.remove(k); + } + } + } + + @override + Future deleteSession(SignalProtocolAddress address) async { + sessions.remove(address); + } + + @override + Future> getSubDeviceSessions(String name) async { + final deviceIds = []; + + for (final key in sessions.keys) { + if (key.getName() == name && key.getDeviceId() != 1) { + deviceIds.add(key.getDeviceId()); + } + } + + return deviceIds; + } + + @override + Future loadSession(SignalProtocolAddress address) async { + try { + if (await containsSession(address)) { + return SessionRecord.fromSerialized(sessions[address]!); + } else { + return SessionRecord(); + } + } on Exception catch (e) { + throw AssertionError(e); + } + } + + @override + Future storeSession( + SignalProtocolAddress address, SessionRecord record) async { + sessions[address] = record.serialize(); + } +} diff --git a/libsignal_protocol_dart/lib/src/state/impl/in_memory_signal_protocol_store.dart b/libsignal_protocol_dart/lib/src/state/impl/in_memory_signal_protocol_store.dart new file mode 100644 index 0000000..cb37a6d --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/impl/in_memory_signal_protocol_store.dart @@ -0,0 +1,119 @@ +import 'dart:core'; + +import '../../identity_key.dart'; +import '../../identity_key_pair.dart'; +import '../../signal_protocol_address.dart'; +import '../identity_key_store.dart'; +import '../pre_key_record.dart'; +import '../session_record.dart'; +import '../signal_protocol_store.dart'; +import '../signed_pre_key_record.dart'; +import 'in_memory_identity_key_store.dart'; +import 'in_memory_pre_key_store.dart'; +import 'in_memory_session_store.dart'; +import 'in_memory_signed_pre_key_store.dart'; + +class InMemorySignalProtocolStore implements SignalProtocolStore { + InMemorySignalProtocolStore( + IdentityKeyPair identityKeyPair, int registrationId) { + _identityKeyStore = + InMemoryIdentityKeyStore(identityKeyPair, registrationId); + } + + final preKeyStore = InMemoryPreKeyStore(); + final sessionStore = InMemorySessionStore(); + final signedPreKeyStore = InMemorySignedPreKeyStore(); + + late IdentityKeyStore _identityKeyStore; + + @override + Future getIdentityKeyPair() async => + _identityKeyStore.getIdentityKeyPair(); + + @override + Future getLocalRegistrationId() async => + _identityKeyStore.getLocalRegistrationId(); + + @override + Future saveIdentity( + SignalProtocolAddress address, IdentityKey? identityKey) async => + _identityKeyStore.saveIdentity(address, identityKey); + + @override + Future isTrustedIdentity(SignalProtocolAddress address, + IdentityKey? identityKey, Direction direction) async => + _identityKeyStore.isTrustedIdentity(address, identityKey, direction); + + @override + Future getIdentity(SignalProtocolAddress address) async => + _identityKeyStore.getIdentity(address); + + @override + Future loadPreKey(int preKeyId) async => + preKeyStore.loadPreKey(preKeyId); + + @override + Future storePreKey(int preKeyId, PreKeyRecord record) async { + await preKeyStore.storePreKey(preKeyId, record); + } + + @override + Future containsPreKey(int preKeyId) async => + preKeyStore.containsPreKey(preKeyId); + + @override + Future removePreKey(int preKeyId) async { + await preKeyStore.removePreKey(preKeyId); + } + + @override + Future loadSession(SignalProtocolAddress address) async => + sessionStore.loadSession(address); + + @override + Future> getSubDeviceSessions(String name) async => + sessionStore.getSubDeviceSessions(name); + + @override + Future storeSession( + SignalProtocolAddress address, SessionRecord record) async { + await sessionStore.storeSession(address, record); + } + + @override + Future containsSession(SignalProtocolAddress address) async => + sessionStore.containsSession(address); + + @override + Future deleteSession(SignalProtocolAddress address) async { + await sessionStore.deleteSession(address); + } + + @override + Future deleteAllSessions(String name) async { + await sessionStore.deleteAllSessions(name); + } + + @override + Future loadSignedPreKey(int signedPreKeyId) async => + signedPreKeyStore.loadSignedPreKey(signedPreKeyId); + + @override + Future> loadSignedPreKeys() async => + signedPreKeyStore.loadSignedPreKeys(); + + @override + Future storeSignedPreKey( + int signedPreKeyId, SignedPreKeyRecord record) async { + await signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record); + } + + @override + Future containsSignedPreKey(int signedPreKeyId) async => + signedPreKeyStore.containsSignedPreKey(signedPreKeyId); + + @override + Future removeSignedPreKey(int signedPreKeyId) async { + await signedPreKeyStore.removeSignedPreKey(signedPreKeyId); + } +} diff --git a/libsignal_protocol_dart/lib/src/state/impl/in_memory_signed_pre_key_store.dart b/libsignal_protocol_dart/lib/src/state/impl/in_memory_signed_pre_key_store.dart new file mode 100644 index 0000000..8a6f0f8 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/impl/in_memory_signed_pre_key_store.dart @@ -0,0 +1,43 @@ +import 'dart:collection'; +import 'dart:typed_data'; + +import '../../invalid_key_id_exception.dart'; +import '../signed_pre_key_record.dart'; +import '../signed_pre_key_store.dart'; + +class InMemorySignedPreKeyStore extends SignedPreKeyStore { + final store = HashMap(); + + @override + Future loadSignedPreKey(int signedPreKeyId) async { + if (!store.containsKey(signedPreKeyId)) { + throw InvalidKeyIdException( + 'No such signedprekeyrecord! $signedPreKeyId'); + } + return SignedPreKeyRecord.fromSerialized(store[signedPreKeyId]!); + } + + @override + Future> loadSignedPreKeys() async { + final results = []; + for (final serialized in store.values) { + results.add(SignedPreKeyRecord.fromSerialized(serialized)); + } + return results; + } + + @override + Future storeSignedPreKey( + int signedPreKeyId, SignedPreKeyRecord record) async { + store[signedPreKeyId] = record.serialize(); + } + + @override + Future containsSignedPreKey(int signedPreKeyId) async => + store.containsKey(signedPreKeyId); + + @override + Future removeSignedPreKey(int signedPreKeyId) async { + store.remove(signedPreKeyId); + } +} diff --git a/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart new file mode 100644 index 0000000..3328eee --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart @@ -0,0 +1,2301 @@ +import 'dart:core' as $core; +import 'dart:core'; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +class SessionStructureChainChainKey extends $pb.GeneratedMessage { + factory SessionStructureChainChainKey({ + $core.int? index, + $core.List<$core.int>? key, + }) { + final _result = create(); + if (index != null) { + _result.index = index; + } + if (key != null) { + _result.key = key; + } + return _result; + } + + SessionStructureChainChainKey._() : super(); + + factory SessionStructureChainChainKey.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SessionStructureChainChainKey.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SessionStructure.Chain.ChainKey', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'index', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'key', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SessionStructureChainChainKey clone() => + SessionStructureChainChainKey()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SessionStructureChainChainKey copyWith( + void Function(SessionStructureChainChainKey) updates) => + super.copyWith( + (message) => updates(message as SessionStructureChainChainKey)) + as SessionStructureChainChainKey; // ignore: deprecated_member_use + + @override + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SessionStructureChainChainKey create() => + SessionStructureChainChainKey._(); + + @override + SessionStructureChainChainKey createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SessionStructureChainChainKey getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SessionStructureChainChainKey? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get index => $_getIZ(0); + + @$pb.TagNumber(1) + set index($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasIndex() => $_has(0); + + @$pb.TagNumber(1) + void clearIndex() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get key => $_getN(1); + + @$pb.TagNumber(2) + set key($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasKey() => $_has(1); + + @$pb.TagNumber(2) + void clearKey() => clearField(2); +} + +class SessionStructureChainMessageKey extends $pb.GeneratedMessage { + factory SessionStructureChainMessageKey({ + $core.int? index, + $core.List<$core.int>? cipherKey, + $core.List<$core.int>? macKey, + $core.List<$core.int>? iv, + }) { + final _result = create(); + if (index != null) { + _result.index = index; + } + if (cipherKey != null) { + _result.cipherKey = cipherKey; + } + if (macKey != null) { + _result.macKey = macKey; + } + if (iv != null) { + _result.iv = iv; + } + return _result; + } + + SessionStructureChainMessageKey._() : super(); + + factory SessionStructureChainMessageKey.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SessionStructureChainMessageKey.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SessionStructure.Chain.MessageKey', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'index', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'cipherKey', + $pb.PbFieldType.OY, + protoName: 'cipherKey') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'macKey', + $pb.PbFieldType.OY, + protoName: 'macKey') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'iv', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SessionStructureChainMessageKey clone() => + SessionStructureChainMessageKey()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SessionStructureChainMessageKey copyWith( + void Function(SessionStructureChainMessageKey) updates) => + super.copyWith( + (message) => updates(message as SessionStructureChainMessageKey)) + as SessionStructureChainMessageKey; // ignore: deprecated_member_use + @override + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SessionStructureChainMessageKey create() => + SessionStructureChainMessageKey._(); + + @override + SessionStructureChainMessageKey createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SessionStructureChainMessageKey getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor( + create); + static SessionStructureChainMessageKey? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get index => $_getIZ(0); + + @$pb.TagNumber(1) + set index($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasIndex() => $_has(0); + + @$pb.TagNumber(1) + void clearIndex() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get cipherKey => $_getN(1); + + @$pb.TagNumber(2) + set cipherKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasCipherKey() => $_has(1); + + @$pb.TagNumber(2) + void clearCipherKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get macKey => $_getN(2); + + @$pb.TagNumber(3) + set macKey($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasMacKey() => $_has(2); + + @$pb.TagNumber(3) + void clearMacKey() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get iv => $_getN(3); + + @$pb.TagNumber(4) + set iv($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasIv() => $_has(3); + + @$pb.TagNumber(4) + void clearIv() => clearField(4); +} + +class SessionStructureChain extends $pb.GeneratedMessage { + factory SessionStructureChain({ + $core.List<$core.int>? senderRatchetKey, + $core.List<$core.int>? senderRatchetKeyPrivate, + SessionStructureChainChainKey? chainKey, + $core.Iterable? messageKeys, + }) { + final _result = create(); + if (senderRatchetKey != null) { + _result.senderRatchetKey = senderRatchetKey; + } + if (senderRatchetKeyPrivate != null) { + _result.senderRatchetKeyPrivate = senderRatchetKeyPrivate; + } + if (chainKey != null) { + _result.chainKey = chainKey; + } + if (messageKeys != null) { + _result.messageKeys.addAll(messageKeys); + } + return _result; + } + + SessionStructureChain._() : super(); + + factory SessionStructureChain.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SessionStructureChain.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SessionStructure.Chain', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderRatchetKey', + $pb.PbFieldType.OY, + protoName: 'senderRatchetKey') + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderRatchetKeyPrivate', + $pb.PbFieldType.OY, + protoName: 'senderRatchetKeyPrivate') + ..aOM( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'chainKey', + protoName: 'chainKey', + subBuilder: SessionStructureChainChainKey.create) + ..pc( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'messageKeys', + $pb.PbFieldType.PM, + protoName: 'messageKeys', + subBuilder: SessionStructureChainMessageKey.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SessionStructureChain clone() => + SessionStructureChain()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SessionStructureChain copyWith( + void Function(SessionStructureChain) updates) => + super.copyWith((message) => updates(message as SessionStructureChain)) + as SessionStructureChain; // ignore: deprecated_member_use + @override + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SessionStructureChain create() => SessionStructureChain._(); + + @override + SessionStructureChain createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SessionStructureChain getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SessionStructureChain? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get senderRatchetKey => $_getN(0); + + @$pb.TagNumber(1) + set senderRatchetKey($core.List<$core.int> v) { + $_setBytes(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasSenderRatchetKey() => $_has(0); + + @$pb.TagNumber(1) + void clearSenderRatchetKey() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get senderRatchetKeyPrivate => $_getN(1); + + @$pb.TagNumber(2) + set senderRatchetKeyPrivate($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasSenderRatchetKeyPrivate() => $_has(1); + + @$pb.TagNumber(2) + void clearSenderRatchetKeyPrivate() => clearField(2); + + @$pb.TagNumber(3) + SessionStructureChainChainKey get chainKey => $_getN(2); + + @$pb.TagNumber(3) + set chainKey(SessionStructureChainChainKey v) { + setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasChainKey() => $_has(2); + + @$pb.TagNumber(3) + void clearChainKey() => clearField(3); + + @$pb.TagNumber(3) + SessionStructureChainChainKey ensureChainKey() => $_ensure(2); + + @$pb.TagNumber(4) + $core.List get messageKeys => $_getList(3); +} + +class SessionStructurePendingKeyExchange extends $pb.GeneratedMessage { + factory SessionStructurePendingKeyExchange({ + $core.int? sequence, + $core.List<$core.int>? localBaseKey, + $core.List<$core.int>? localBaseKeyPrivate, + $core.List<$core.int>? localRatchetKey, + $core.List<$core.int>? localRatchetKeyPrivate, + $core.List<$core.int>? localIdentityKey, + $core.List<$core.int>? localIdentityKeyPrivate, + }) { + final _result = create(); + if (sequence != null) { + _result.sequence = sequence; + } + if (localBaseKey != null) { + _result.localBaseKey = localBaseKey; + } + if (localBaseKeyPrivate != null) { + _result.localBaseKeyPrivate = localBaseKeyPrivate; + } + if (localRatchetKey != null) { + _result.localRatchetKey = localRatchetKey; + } + if (localRatchetKeyPrivate != null) { + _result.localRatchetKeyPrivate = localRatchetKeyPrivate; + } + if (localIdentityKey != null) { + _result.localIdentityKey = localIdentityKey; + } + if (localIdentityKeyPrivate != null) { + _result.localIdentityKeyPrivate = localIdentityKeyPrivate; + } + return _result; + } + + SessionStructurePendingKeyExchange._() : super(); + + factory SessionStructurePendingKeyExchange.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SessionStructurePendingKeyExchange.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SessionStructure.PendingKeyExchange', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'sequence', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localBaseKey', + $pb.PbFieldType.OY, + protoName: 'localBaseKey') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localBaseKeyPrivate', + $pb.PbFieldType.OY, + protoName: 'localBaseKeyPrivate') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localRatchetKey', + $pb.PbFieldType.OY, + protoName: 'localRatchetKey') + ..a<$core.List<$core.int>>( + 5, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localRatchetKeyPrivate', + $pb.PbFieldType.OY, + protoName: 'localRatchetKeyPrivate') + ..a<$core.List<$core.int>>( + 7, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localIdentityKey', + $pb.PbFieldType.OY, + protoName: 'localIdentityKey') + ..a<$core.List<$core.int>>( + 8, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localIdentityKeyPrivate', + $pb.PbFieldType.OY, + protoName: 'localIdentityKeyPrivate') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SessionStructurePendingKeyExchange clone() => + SessionStructurePendingKeyExchange()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SessionStructurePendingKeyExchange copyWith( + void Function(SessionStructurePendingKeyExchange) updates) => + super.copyWith((message) => + updates(message as SessionStructurePendingKeyExchange)) + as SessionStructurePendingKeyExchange; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SessionStructurePendingKeyExchange create() => + SessionStructurePendingKeyExchange._(); + + @override + SessionStructurePendingKeyExchange createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SessionStructurePendingKeyExchange getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor( + create); + static SessionStructurePendingKeyExchange? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get sequence => $_getIZ(0); + + @$pb.TagNumber(1) + set sequence($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasSequence() => $_has(0); + + @$pb.TagNumber(1) + void clearSequence() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get localBaseKey => $_getN(1); + + @$pb.TagNumber(2) + set localBaseKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasLocalBaseKey() => $_has(1); + + @$pb.TagNumber(2) + void clearLocalBaseKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get localBaseKeyPrivate => $_getN(2); + + @$pb.TagNumber(3) + set localBaseKeyPrivate($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasLocalBaseKeyPrivate() => $_has(2); + + @$pb.TagNumber(3) + void clearLocalBaseKeyPrivate() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get localRatchetKey => $_getN(3); + + @$pb.TagNumber(4) + set localRatchetKey($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasLocalRatchetKey() => $_has(3); + + @$pb.TagNumber(4) + void clearLocalRatchetKey() => clearField(4); + + @$pb.TagNumber(5) + $core.List<$core.int> get localRatchetKeyPrivate => $_getN(4); + + @$pb.TagNumber(5) + set localRatchetKeyPrivate($core.List<$core.int> v) { + $_setBytes(4, v); + } + + @$pb.TagNumber(5) + $core.bool hasLocalRatchetKeyPrivate() => $_has(4); + + @$pb.TagNumber(5) + void clearLocalRatchetKeyPrivate() => clearField(5); + + @$pb.TagNumber(7) + $core.List<$core.int> get localIdentityKey => $_getN(5); + + @$pb.TagNumber(7) + set localIdentityKey($core.List<$core.int> v) { + $_setBytes(5, v); + } + + @$pb.TagNumber(7) + $core.bool hasLocalIdentityKey() => $_has(5); + + @$pb.TagNumber(7) + void clearLocalIdentityKey() => clearField(7); + + @$pb.TagNumber(8) + $core.List<$core.int> get localIdentityKeyPrivate => $_getN(6); + + @$pb.TagNumber(8) + set localIdentityKeyPrivate($core.List<$core.int> v) { + $_setBytes(6, v); + } + + @$pb.TagNumber(8) + $core.bool hasLocalIdentityKeyPrivate() => $_has(6); + + @$pb.TagNumber(8) + void clearLocalIdentityKeyPrivate() => clearField(8); +} + +class SessionStructurePendingPreKey extends $pb.GeneratedMessage { + factory SessionStructurePendingPreKey({ + $core.int? preKeyId, + $core.List<$core.int>? baseKey, + $core.int? signedPreKeyId, + }) { + final _result = create(); + if (preKeyId != null) { + _result.preKeyId = preKeyId; + } + if (baseKey != null) { + _result.baseKey = baseKey; + } + if (signedPreKeyId != null) { + _result.signedPreKeyId = signedPreKeyId; + } + return _result; + } + + SessionStructurePendingPreKey._() : super(); + + factory SessionStructurePendingPreKey.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SessionStructurePendingPreKey.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SessionStructure.PendingPreKey', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'preKeyId', + $pb.PbFieldType.OU3, + protoName: 'preKeyId') + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'baseKey', + $pb.PbFieldType.OY, + protoName: 'baseKey') + ..a<$core.int>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'signedPreKeyId', + $pb.PbFieldType.O3, + protoName: 'signedPreKeyId') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SessionStructurePendingPreKey clone() => + SessionStructurePendingPreKey()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SessionStructurePendingPreKey copyWith( + void Function(SessionStructurePendingPreKey) updates) => + super.copyWith( + (message) => updates(message as SessionStructurePendingPreKey)) + as SessionStructurePendingPreKey; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SessionStructurePendingPreKey create() => + SessionStructurePendingPreKey._(); + + @override + SessionStructurePendingPreKey createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SessionStructurePendingPreKey getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SessionStructurePendingPreKey? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get preKeyId => $_getIZ(0); + + @$pb.TagNumber(1) + set preKeyId($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasPreKeyId() => $_has(0); + + @$pb.TagNumber(1) + void clearPreKeyId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get baseKey => $_getN(1); + + @$pb.TagNumber(2) + set baseKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasBaseKey() => $_has(1); + + @$pb.TagNumber(2) + void clearBaseKey() => clearField(2); + + @$pb.TagNumber(3) + $core.int get signedPreKeyId => $_getIZ(2); + + @$pb.TagNumber(3) + set signedPreKeyId($core.int v) { + $_setSignedInt32(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasSignedPreKeyId() => $_has(2); + + @$pb.TagNumber(3) + void clearSignedPreKeyId() => clearField(3); +} + +class SessionStructure extends $pb.GeneratedMessage { + factory SessionStructure({ + $core.int? sessionVersion, + $core.List<$core.int>? localIdentityPublic, + $core.List<$core.int>? remoteIdentityPublic, + $core.List<$core.int>? rootKey, + $core.int? previousCounter, + SessionStructureChain? senderChain, + $core.Iterable? receiverChains, + SessionStructurePendingKeyExchange? pendingKeyExchange, + SessionStructurePendingPreKey? pendingPreKey, + $core.int? remoteRegistrationId, + $core.int? localRegistrationId, + $core.bool? needsRefresh, + $core.List<$core.int>? aliceBaseKey, + }) { + final _result = create(); + if (sessionVersion != null) { + _result.sessionVersion = sessionVersion; + } + if (localIdentityPublic != null) { + _result.localIdentityPublic = localIdentityPublic; + } + if (remoteIdentityPublic != null) { + _result.remoteIdentityPublic = remoteIdentityPublic; + } + if (rootKey != null) { + _result.rootKey = rootKey; + } + if (previousCounter != null) { + _result.previousCounter = previousCounter; + } + if (senderChain != null) { + _result.senderChain = senderChain; + } + if (receiverChains != null) { + _result.receiverChains.addAll(receiverChains); + } + if (pendingKeyExchange != null) { + _result.pendingKeyExchange = pendingKeyExchange; + } + if (pendingPreKey != null) { + _result.pendingPreKey = pendingPreKey; + } + if (remoteRegistrationId != null) { + _result.remoteRegistrationId = remoteRegistrationId; + } + if (localRegistrationId != null) { + _result.localRegistrationId = localRegistrationId; + } + if (needsRefresh != null) { + _result.needsRefresh = needsRefresh; + } + if (aliceBaseKey != null) { + _result.aliceBaseKey = aliceBaseKey; + } + return _result; + } + + SessionStructure._() : super(); + + factory SessionStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SessionStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SessionStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'sessionVersion', + $pb.PbFieldType.OU3, + protoName: 'sessionVersion') + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localIdentityPublic', + $pb.PbFieldType.OY, + protoName: 'localIdentityPublic') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'remoteIdentityPublic', + $pb.PbFieldType.OY, + protoName: 'remoteIdentityPublic') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'rootKey', + $pb.PbFieldType.OY, + protoName: 'rootKey') + ..a<$core.int>( + 5, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'previousCounter', + $pb.PbFieldType.OU3, + protoName: 'previousCounter') + ..aOM( + 6, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderChain', + protoName: 'senderChain', + subBuilder: SessionStructureChain.create) + ..pc( + 7, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'receiverChains', + $pb.PbFieldType.PM, + protoName: 'receiverChains', + subBuilder: SessionStructureChain.create) + ..aOM( + 8, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'pendingKeyExchange', + protoName: 'pendingKeyExchange', + subBuilder: SessionStructurePendingKeyExchange.create) + ..aOM( + 9, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'pendingPreKey', + protoName: 'pendingPreKey', + subBuilder: SessionStructurePendingPreKey.create) + ..a<$core.int>( + 10, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'remoteRegistrationId', + $pb.PbFieldType.OU3, + protoName: 'remoteRegistrationId') + ..a<$core.int>( + 11, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'localRegistrationId', + $pb.PbFieldType.OU3, + protoName: 'localRegistrationId') + ..aOB( + 12, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'needsRefresh', + protoName: 'needsRefresh') + ..a<$core.List<$core.int>>( + 13, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'aliceBaseKey', + $pb.PbFieldType.OY, + protoName: 'aliceBaseKey') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SessionStructure clone() => SessionStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SessionStructure copyWith(void Function(SessionStructure) updates) => + super.copyWith((message) => updates(message as SessionStructure)) + as SessionStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SessionStructure create() => SessionStructure._(); + + @override + SessionStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SessionStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SessionStructure? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get sessionVersion => $_getIZ(0); + + @$pb.TagNumber(1) + set sessionVersion($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasSessionVersion() => $_has(0); + + @$pb.TagNumber(1) + void clearSessionVersion() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get localIdentityPublic => $_getN(1); + + @$pb.TagNumber(2) + set localIdentityPublic($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasLocalIdentityPublic() => $_has(1); + + @$pb.TagNumber(2) + void clearLocalIdentityPublic() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get remoteIdentityPublic => $_getN(2); + + @$pb.TagNumber(3) + set remoteIdentityPublic($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasRemoteIdentityPublic() => $_has(2); + + @$pb.TagNumber(3) + void clearRemoteIdentityPublic() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get rootKey => $_getN(3); + + @$pb.TagNumber(4) + set rootKey($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasRootKey() => $_has(3); + + @$pb.TagNumber(4) + void clearRootKey() => clearField(4); + + @$pb.TagNumber(5) + $core.int get previousCounter => $_getIZ(4); + + @$pb.TagNumber(5) + set previousCounter($core.int v) { + $_setUnsignedInt32(4, v); + } + + @$pb.TagNumber(5) + $core.bool hasPreviousCounter() => $_has(4); + + @$pb.TagNumber(5) + void clearPreviousCounter() => clearField(5); + + @$pb.TagNumber(6) + SessionStructureChain get senderChain => $_getN(5); + + @$pb.TagNumber(6) + set senderChain(SessionStructureChain v) { + setField(6, v); + } + + @$pb.TagNumber(6) + $core.bool hasSenderChain() => $_has(5); + + @$pb.TagNumber(6) + void clearSenderChain() => clearField(6); + + @$pb.TagNumber(6) + SessionStructureChain ensureSenderChain() => $_ensure(5); + + @$pb.TagNumber(7) + $core.List get receiverChains => $_getList(6); + + @$pb.TagNumber(8) + SessionStructurePendingKeyExchange get pendingKeyExchange => $_getN(7); + + @$pb.TagNumber(8) + set pendingKeyExchange(SessionStructurePendingKeyExchange v) { + setField(8, v); + } + + @$pb.TagNumber(8) + $core.bool hasPendingKeyExchange() => $_has(7); + + @$pb.TagNumber(8) + void clearPendingKeyExchange() => clearField(8); + + @$pb.TagNumber(8) + SessionStructurePendingKeyExchange ensurePendingKeyExchange() => $_ensure(7); + + @$pb.TagNumber(9) + SessionStructurePendingPreKey get pendingPreKey => $_getN(8); + + @$pb.TagNumber(9) + set pendingPreKey(SessionStructurePendingPreKey v) { + setField(9, v); + } + + @$pb.TagNumber(9) + $core.bool hasPendingPreKey() => $_has(8); + + @$pb.TagNumber(9) + void clearPendingPreKey() => clearField(9); + + @$pb.TagNumber(9) + SessionStructurePendingPreKey ensurePendingPreKey() => $_ensure(8); + + @$pb.TagNumber(10) + $core.int get remoteRegistrationId => $_getIZ(9); + + @$pb.TagNumber(10) + set remoteRegistrationId($core.int v) { + $_setUnsignedInt32(9, v); + } + + @$pb.TagNumber(10) + $core.bool hasRemoteRegistrationId() => $_has(9); + + @$pb.TagNumber(10) + void clearRemoteRegistrationId() => clearField(10); + + @$pb.TagNumber(11) + $core.int get localRegistrationId => $_getIZ(10); + + @$pb.TagNumber(11) + set localRegistrationId($core.int v) { + $_setUnsignedInt32(10, v); + } + + @$pb.TagNumber(11) + $core.bool hasLocalRegistrationId() => $_has(10); + + @$pb.TagNumber(11) + void clearLocalRegistrationId() => clearField(11); + + @$pb.TagNumber(12) + $core.bool get needsRefresh => $_getBF(11); + + @$pb.TagNumber(12) + set needsRefresh($core.bool v) { + $_setBool(11, v); + } + + @$pb.TagNumber(12) + $core.bool hasNeedsRefresh() => $_has(11); + + @$pb.TagNumber(12) + void clearNeedsRefresh() => clearField(12); + + @$pb.TagNumber(13) + $core.List<$core.int> get aliceBaseKey => $_getN(12); + + @$pb.TagNumber(13) + set aliceBaseKey($core.List<$core.int> v) { + $_setBytes(12, v); + } + + @$pb.TagNumber(13) + $core.bool hasAliceBaseKey() => $_has(12); + + @$pb.TagNumber(13) + void clearAliceBaseKey() => clearField(13); +} + +class RecordStructure extends $pb.GeneratedMessage { + factory RecordStructure({ + SessionStructure? currentSession, + $core.Iterable? previousSessions, + }) { + final _result = create(); + if (currentSession != null) { + _result.currentSession = currentSession; + } + if (previousSessions != null) { + _result.previousSessions.addAll(previousSessions); + } + return _result; + } + + RecordStructure._() : super(); + + factory RecordStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory RecordStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'RecordStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..aOM( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'currentSession', + protoName: 'currentSession', + subBuilder: SessionStructure.create) + ..pc( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'previousSessions', + $pb.PbFieldType.PM, + protoName: 'previousSessions', + subBuilder: SessionStructure.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + RecordStructure clone() => RecordStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + RecordStructure copyWith(void Function(RecordStructure) updates) => + super.copyWith((message) => updates(message as RecordStructure)) + as RecordStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static RecordStructure create() => RecordStructure._(); + + @override + RecordStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static RecordStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static RecordStructure? _defaultInstance; + + @$pb.TagNumber(1) + SessionStructure get currentSession => $_getN(0); + + @$pb.TagNumber(1) + set currentSession(SessionStructure v) { + setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCurrentSession() => $_has(0); + + @$pb.TagNumber(1) + void clearCurrentSession() => clearField(1); + + @$pb.TagNumber(1) + SessionStructure ensureCurrentSession() => $_ensure(0); + + @$pb.TagNumber(2) + $core.List get previousSessions => $_getList(1); +} + +class PreKeyRecordStructure extends $pb.GeneratedMessage { + factory PreKeyRecordStructure({ + $core.int? id, + $core.List<$core.int>? publicKey, + $core.List<$core.int>? privateKey, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (publicKey != null) { + _result.publicKey = publicKey; + } + if (privateKey != null) { + _result.privateKey = privateKey; + } + return _result; + } + + PreKeyRecordStructure._() : super(); + + factory PreKeyRecordStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory PreKeyRecordStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'PreKeyRecordStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'id', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'publicKey', + $pb.PbFieldType.OY, + protoName: 'publicKey') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'privateKey', + $pb.PbFieldType.OY, + protoName: 'privateKey') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + PreKeyRecordStructure clone() => + PreKeyRecordStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + PreKeyRecordStructure copyWith( + void Function(PreKeyRecordStructure) updates) => + super.copyWith((message) => updates(message as PreKeyRecordStructure)) + as PreKeyRecordStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static PreKeyRecordStructure create() => PreKeyRecordStructure._(); + + @override + PreKeyRecordStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static PreKeyRecordStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static PreKeyRecordStructure? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get id => $_getIZ(0); + + @$pb.TagNumber(1) + set id($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get publicKey => $_getN(1); + + @$pb.TagNumber(2) + set publicKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasPublicKey() => $_has(1); + + @$pb.TagNumber(2) + void clearPublicKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get privateKey => $_getN(2); + + @$pb.TagNumber(3) + set privateKey($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasPrivateKey() => $_has(2); + + @$pb.TagNumber(3) + void clearPrivateKey() => clearField(3); +} + +class SignedPreKeyRecordStructure extends $pb.GeneratedMessage { + factory SignedPreKeyRecordStructure({ + $core.int? id, + $core.List<$core.int>? publicKey, + $core.List<$core.int>? privateKey, + $core.List<$core.int>? signature, + $fixnum.Int64? timestamp, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (publicKey != null) { + _result.publicKey = publicKey; + } + if (privateKey != null) { + _result.privateKey = privateKey; + } + if (signature != null) { + _result.signature = signature; + } + if (timestamp != null) { + _result.timestamp = timestamp; + } + return _result; + } + + SignedPreKeyRecordStructure._() : super(); + + factory SignedPreKeyRecordStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SignedPreKeyRecordStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SignedPreKeyRecordStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'id', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'publicKey', + $pb.PbFieldType.OY, + protoName: 'publicKey') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'privateKey', + $pb.PbFieldType.OY, + protoName: 'privateKey') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'signature', + $pb.PbFieldType.OY) + ..a<$fixnum.Int64>( + 5, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'timestamp', + $pb.PbFieldType.OF6, + defaultOrMaker: $fixnum.Int64.ZERO) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SignedPreKeyRecordStructure clone() => + SignedPreKeyRecordStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SignedPreKeyRecordStructure copyWith( + void Function(SignedPreKeyRecordStructure) updates) => + super.copyWith( + (message) => updates(message as SignedPreKeyRecordStructure)) + as SignedPreKeyRecordStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SignedPreKeyRecordStructure create() => + SignedPreKeyRecordStructure._(); + + @override + SignedPreKeyRecordStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SignedPreKeyRecordStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SignedPreKeyRecordStructure? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get id => $_getIZ(0); + + @$pb.TagNumber(1) + set id($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get publicKey => $_getN(1); + + @$pb.TagNumber(2) + set publicKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasPublicKey() => $_has(1); + + @$pb.TagNumber(2) + void clearPublicKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get privateKey => $_getN(2); + + @$pb.TagNumber(3) + set privateKey($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasPrivateKey() => $_has(2); + + @$pb.TagNumber(3) + void clearPrivateKey() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get signature => $_getN(3); + + @$pb.TagNumber(4) + set signature($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasSignature() => $_has(3); + + @$pb.TagNumber(4) + void clearSignature() => clearField(4); + + @$pb.TagNumber(5) + $fixnum.Int64 get timestamp => $_getI64(4); + + @$pb.TagNumber(5) + set timestamp($fixnum.Int64 v) { + $_setInt64(4, v); + } + + @$pb.TagNumber(5) + $core.bool hasTimestamp() => $_has(4); + + @$pb.TagNumber(5) + void clearTimestamp() => clearField(5); +} + +class IdentityKeyPairStructure extends $pb.GeneratedMessage { + factory IdentityKeyPairStructure({ + $core.List<$core.int>? publicKey, + $core.List<$core.int>? privateKey, + }) { + final _result = create(); + if (publicKey != null) { + _result.publicKey = publicKey; + } + if (privateKey != null) { + _result.privateKey = privateKey; + } + return _result; + } + + IdentityKeyPairStructure._() : super(); + + factory IdentityKeyPairStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory IdentityKeyPairStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'IdentityKeyPairStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'publicKey', + $pb.PbFieldType.OY, + protoName: 'publicKey') + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'privateKey', + $pb.PbFieldType.OY, + protoName: 'privateKey') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + IdentityKeyPairStructure clone() => + IdentityKeyPairStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + IdentityKeyPairStructure copyWith( + void Function(IdentityKeyPairStructure) updates) => + super.copyWith((message) => updates(message as IdentityKeyPairStructure)) + as IdentityKeyPairStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static IdentityKeyPairStructure create() => IdentityKeyPairStructure._(); + + @override + IdentityKeyPairStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static IdentityKeyPairStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static IdentityKeyPairStructure? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get publicKey => $_getN(0); + + @$pb.TagNumber(1) + set publicKey($core.List<$core.int> v) { + $_setBytes(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasPublicKey() => $_has(0); + + @$pb.TagNumber(1) + void clearPublicKey() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get privateKey => $_getN(1); + + @$pb.TagNumber(2) + set privateKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasPrivateKey() => $_has(1); + + @$pb.TagNumber(2) + void clearPrivateKey() => clearField(2); +} + +class SenderKeyStateStructureSenderChainKey extends $pb.GeneratedMessage { + factory SenderKeyStateStructureSenderChainKey({ + $core.int? iteration, + $core.List<$core.int>? seed, + }) { + final _result = create(); + if (iteration != null) { + _result.iteration = iteration; + } + if (seed != null) { + _result.seed = seed; + } + return _result; + } + + SenderKeyStateStructureSenderChainKey._() : super(); + + factory SenderKeyStateStructureSenderChainKey.fromBuffer( + $core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyStateStructureSenderChainKey.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyStateStructure.SenderChainKey', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'iteration', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'seed', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructureSenderChainKey clone() => + SenderKeyStateStructureSenderChainKey()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructureSenderChainKey copyWith( + void Function(SenderKeyStateStructureSenderChainKey) updates) => + super.copyWith((message) => + updates(message as SenderKeyStateStructureSenderChainKey)) + as SenderKeyStateStructureSenderChainKey; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructureSenderChainKey create() => + SenderKeyStateStructureSenderChainKey._(); + + @override + SenderKeyStateStructureSenderChainKey createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructureSenderChainKey getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + SenderKeyStateStructureSenderChainKey>(create); + static SenderKeyStateStructureSenderChainKey? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get iteration => $_getIZ(0); + + @$pb.TagNumber(1) + set iteration($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasIteration() => $_has(0); + + @$pb.TagNumber(1) + void clearIteration() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get seed => $_getN(1); + + @$pb.TagNumber(2) + set seed($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasSeed() => $_has(1); + + @$pb.TagNumber(2) + void clearSeed() => clearField(2); +} + +class SenderKeyStateStructureSenderMessageKey extends $pb.GeneratedMessage { + factory SenderKeyStateStructureSenderMessageKey({ + $core.int? iteration, + $core.List<$core.int>? seed, + }) { + final _result = create(); + if (iteration != null) { + _result.iteration = iteration; + } + if (seed != null) { + _result.seed = seed; + } + return _result; + } + + SenderKeyStateStructureSenderMessageKey._() : super(); + + factory SenderKeyStateStructureSenderMessageKey.fromBuffer( + $core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyStateStructureSenderMessageKey.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyStateStructure.SenderMessageKey', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'iteration', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'seed', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructureSenderMessageKey clone() => + SenderKeyStateStructureSenderMessageKey()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructureSenderMessageKey copyWith( + void Function(SenderKeyStateStructureSenderMessageKey) updates) => + super.copyWith((message) => + updates(message as SenderKeyStateStructureSenderMessageKey)) + as SenderKeyStateStructureSenderMessageKey; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructureSenderMessageKey create() => + SenderKeyStateStructureSenderMessageKey._(); + + @override + SenderKeyStateStructureSenderMessageKey createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructureSenderMessageKey getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + SenderKeyStateStructureSenderMessageKey>(create); + static SenderKeyStateStructureSenderMessageKey? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get iteration => $_getIZ(0); + + @$pb.TagNumber(1) + set iteration($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasIteration() => $_has(0); + + @$pb.TagNumber(1) + void clearIteration() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get seed => $_getN(1); + + @$pb.TagNumber(2) + set seed($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasSeed() => $_has(1); + + @$pb.TagNumber(2) + void clearSeed() => clearField(2); +} + +class SenderKeyStateStructureSenderSigningKey extends $pb.GeneratedMessage { + factory SenderKeyStateStructureSenderSigningKey({ + $core.List<$core.int>? public, + $core.List<$core.int>? private, + }) { + final _result = create(); + if (public != null) { + _result.public = public; + } + if (private != null) { + _result.private = private; + } + return _result; + } + + SenderKeyStateStructureSenderSigningKey._() : super(); + + factory SenderKeyStateStructureSenderSigningKey.fromBuffer( + $core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyStateStructureSenderSigningKey.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyStateStructure.SenderSigningKey', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'public', + $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'private', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructureSenderSigningKey clone() => + SenderKeyStateStructureSenderSigningKey()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructureSenderSigningKey copyWith( + void Function(SenderKeyStateStructureSenderSigningKey) updates) => + super.copyWith((message) => + updates(message as SenderKeyStateStructureSenderSigningKey)) + as SenderKeyStateStructureSenderSigningKey; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructureSenderSigningKey create() => + SenderKeyStateStructureSenderSigningKey._(); + + @override + SenderKeyStateStructureSenderSigningKey createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructureSenderSigningKey getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + SenderKeyStateStructureSenderSigningKey>(create); + static SenderKeyStateStructureSenderSigningKey? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get public => $_getN(0); + + @$pb.TagNumber(1) + set public($core.List<$core.int> v) { + $_setBytes(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasPublic() => $_has(0); + + @$pb.TagNumber(1) + void clearPublic() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get private => $_getN(1); + + @$pb.TagNumber(2) + set private($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasPrivate() => $_has(1); + + @$pb.TagNumber(2) + void clearPrivate() => clearField(2); +} + +class SenderKeyStateStructure extends $pb.GeneratedMessage { + factory SenderKeyStateStructure({ + $core.int? senderKeyId, + SenderKeyStateStructureSenderChainKey? senderChainKey, + SenderKeyStateStructureSenderSigningKey? senderSigningKey, + $core.Iterable? senderMessageKeys, + }) { + final _result = create(); + if (senderKeyId != null) { + _result.senderKeyId = senderKeyId; + } + if (senderChainKey != null) { + _result.senderChainKey = senderChainKey; + } + if (senderSigningKey != null) { + _result.senderSigningKey = senderSigningKey; + } + if (senderMessageKeys != null) { + _result.senderMessageKeys.addAll(senderMessageKeys); + } + return _result; + } + + SenderKeyStateStructure._() : super(); + + factory SenderKeyStateStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyStateStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyStateStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderKeyId', + $pb.PbFieldType.OU3, + protoName: 'senderKeyId') + ..aOM( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderChainKey', + protoName: 'senderChainKey', + subBuilder: SenderKeyStateStructureSenderChainKey.create) + ..aOM( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderSigningKey', + protoName: 'senderSigningKey', + subBuilder: SenderKeyStateStructureSenderSigningKey.create) + ..pc( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderMessageKeys', + $pb.PbFieldType.PM, + protoName: 'senderMessageKeys', + subBuilder: SenderKeyStateStructureSenderMessageKey.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructure clone() => + SenderKeyStateStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyStateStructure copyWith( + void Function(SenderKeyStateStructure) updates) => + super.copyWith((message) => updates(message as SenderKeyStateStructure)) + as SenderKeyStateStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructure create() => SenderKeyStateStructure._(); + + @override + SenderKeyStateStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyStateStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SenderKeyStateStructure? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get senderKeyId => $_getIZ(0); + + @$pb.TagNumber(1) + set senderKeyId($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasSenderKeyId() => $_has(0); + + @$pb.TagNumber(1) + void clearSenderKeyId() => clearField(1); + + @$pb.TagNumber(2) + SenderKeyStateStructureSenderChainKey get senderChainKey => $_getN(1); + + @$pb.TagNumber(2) + set senderChainKey(SenderKeyStateStructureSenderChainKey v) { + setField(2, v); + } + + @$pb.TagNumber(2) + $core.bool hasSenderChainKey() => $_has(1); + + @$pb.TagNumber(2) + void clearSenderChainKey() => clearField(2); + + @$pb.TagNumber(2) + SenderKeyStateStructureSenderChainKey ensureSenderChainKey() => $_ensure(1); + + @$pb.TagNumber(3) + SenderKeyStateStructureSenderSigningKey get senderSigningKey => $_getN(2); + + @$pb.TagNumber(3) + set senderSigningKey(SenderKeyStateStructureSenderSigningKey v) { + setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasSenderSigningKey() => $_has(2); + + @$pb.TagNumber(3) + void clearSenderSigningKey() => clearField(3); + + @$pb.TagNumber(3) + SenderKeyStateStructureSenderSigningKey ensureSenderSigningKey() => + $_ensure(2); + + @$pb.TagNumber(4) + $core.List get senderMessageKeys => + $_getList(3); +} + +class SenderKeyRecordStructure extends $pb.GeneratedMessage { + factory SenderKeyRecordStructure({ + $core.Iterable? senderKeyStates, + }) { + final _result = create(); + if (senderKeyStates != null) { + _result.senderKeyStates.addAll(senderKeyStates); + } + return _result; + } + + SenderKeyRecordStructure._() : super(); + + factory SenderKeyRecordStructure.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyRecordStructure.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyRecordStructure', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..pc( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'senderKeyStates', + $pb.PbFieldType.PM, + protoName: 'senderKeyStates', + subBuilder: SenderKeyStateStructure.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyRecordStructure clone() => + SenderKeyRecordStructure()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyRecordStructure copyWith( + void Function(SenderKeyRecordStructure) updates) => + super.copyWith((message) => updates(message as SenderKeyRecordStructure)) + as SenderKeyRecordStructure; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyRecordStructure create() => SenderKeyRecordStructure._(); + + @override + SenderKeyRecordStructure createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyRecordStructure getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SenderKeyRecordStructure? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get senderKeyStates => $_getList(0); +} diff --git a/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbenum.dart b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbenum.dart new file mode 100644 index 0000000..8ad5fc0 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbenum.dart @@ -0,0 +1,5 @@ +// Generated code. Do not modify. +// source: LocalStorageProtocol.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields diff --git a/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbjson.dart b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbjson.dart new file mode 100644 index 0000000..1a900a4 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbjson.dart @@ -0,0 +1,348 @@ +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use sessionStructureDescriptor instead') +const sessionStructure$json = { + '1': 'SessionStructure', + '2': [ + {'1': 'sessionVersion', '3': 1, '4': 1, '5': 13, '10': 'sessionVersion'}, + { + '1': 'localIdentityPublic', + '3': 2, + '4': 1, + '5': 12, + '10': 'localIdentityPublic' + }, + { + '1': 'remoteIdentityPublic', + '3': 3, + '4': 1, + '5': 12, + '10': 'remoteIdentityPublic' + }, + {'1': 'rootKey', '3': 4, '4': 1, '5': 12, '10': 'rootKey'}, + {'1': 'previousCounter', '3': 5, '4': 1, '5': 13, '10': 'previousCounter'}, + { + '1': 'senderChain', + '3': 6, + '4': 1, + '5': 11, + '6': '.textsecure.SessionStructure.Chain', + '10': 'senderChain' + }, + { + '1': 'receiverChains', + '3': 7, + '4': 3, + '5': 11, + '6': '.textsecure.SessionStructure.Chain', + '10': 'receiverChains' + }, + { + '1': 'pendingKeyExchange', + '3': 8, + '4': 1, + '5': 11, + '6': '.textsecure.SessionStructure.PendingKeyExchange', + '10': 'pendingKeyExchange' + }, + { + '1': 'pendingPreKey', + '3': 9, + '4': 1, + '5': 11, + '6': '.textsecure.SessionStructure.PendingPreKey', + '10': 'pendingPreKey' + }, + { + '1': 'remoteRegistrationId', + '3': 10, + '4': 1, + '5': 13, + '10': 'remoteRegistrationId' + }, + { + '1': 'localRegistrationId', + '3': 11, + '4': 1, + '5': 13, + '10': 'localRegistrationId' + }, + {'1': 'needsRefresh', '3': 12, '4': 1, '5': 8, '10': 'needsRefresh'}, + {'1': 'aliceBaseKey', '3': 13, '4': 1, '5': 12, '10': 'aliceBaseKey'}, + ], + '3': [ + sessionStructureChain$json, + sessionStructurePendingKeyExchange$json, + sessionStructurePendingPreKey$json + ], +}; + +@$core.Deprecated('Use sessionStructureDescriptor instead') +const sessionStructureChain$json = { + '1': 'Chain', + '2': [ + { + '1': 'senderRatchetKey', + '3': 1, + '4': 1, + '5': 12, + '10': 'senderRatchetKey' + }, + { + '1': 'senderRatchetKeyPrivate', + '3': 2, + '4': 1, + '5': 12, + '10': 'senderRatchetKeyPrivate' + }, + { + '1': 'chainKey', + '3': 3, + '4': 1, + '5': 11, + '6': '.textsecure.SessionStructure.Chain.ChainKey', + '10': 'chainKey' + }, + { + '1': 'messageKeys', + '3': 4, + '4': 3, + '5': 11, + '6': '.textsecure.SessionStructure.Chain.MessageKey', + '10': 'messageKeys' + }, + ], + '3': [ + sessionStructureChainChainKey$json, + sessionStructureChainMessageKey$json + ], +}; + +@$core.Deprecated('Use sessionStructureDescriptor instead') +const sessionStructureChainChainKey$json = { + '1': 'ChainKey', + '2': [ + {'1': 'index', '3': 1, '4': 1, '5': 13, '10': 'index'}, + {'1': 'key', '3': 2, '4': 1, '5': 12, '10': 'key'}, + ], +}; + +@$core.Deprecated('Use sessionStructureDescriptor instead') +const sessionStructureChainMessageKey$json = { + '1': 'MessageKey', + '2': [ + {'1': 'index', '3': 1, '4': 1, '5': 13, '10': 'index'}, + {'1': 'cipherKey', '3': 2, '4': 1, '5': 12, '10': 'cipherKey'}, + {'1': 'macKey', '3': 3, '4': 1, '5': 12, '10': 'macKey'}, + {'1': 'iv', '3': 4, '4': 1, '5': 12, '10': 'iv'}, + ], +}; + +@$core.Deprecated('Use sessionStructureDescriptor instead') +const sessionStructurePendingKeyExchange$json = { + '1': 'PendingKeyExchange', + '2': [ + {'1': 'sequence', '3': 1, '4': 1, '5': 13, '10': 'sequence'}, + {'1': 'localBaseKey', '3': 2, '4': 1, '5': 12, '10': 'localBaseKey'}, + { + '1': 'localBaseKeyPrivate', + '3': 3, + '4': 1, + '5': 12, + '10': 'localBaseKeyPrivate' + }, + {'1': 'localRatchetKey', '3': 4, '4': 1, '5': 12, '10': 'localRatchetKey'}, + { + '1': 'localRatchetKeyPrivate', + '3': 5, + '4': 1, + '5': 12, + '10': 'localRatchetKeyPrivate' + }, + { + '1': 'localIdentityKey', + '3': 7, + '4': 1, + '5': 12, + '10': 'localIdentityKey' + }, + { + '1': 'localIdentityKeyPrivate', + '3': 8, + '4': 1, + '5': 12, + '10': 'localIdentityKeyPrivate' + }, + ], +}; + +@$core.Deprecated('Use sessionStructureDescriptor instead') +const sessionStructurePendingPreKey$json = { + '1': 'PendingPreKey', + '2': [ + {'1': 'preKeyId', '3': 1, '4': 1, '5': 13, '10': 'preKeyId'}, + {'1': 'signedPreKeyId', '3': 3, '4': 1, '5': 5, '10': 'signedPreKeyId'}, + {'1': 'baseKey', '3': 2, '4': 1, '5': 12, '10': 'baseKey'}, + ], +}; + +/// Descriptor for `SessionStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List sessionStructureDescriptor = $convert.base64Decode( + 'ChBTZXNzaW9uU3RydWN0dXJlEiYKDnNlc3Npb25WZXJzaW9uGAEgASgNUg5zZXNzaW9uVmVyc2lvbhIwChNsb2NhbElkZW50aXR5UHVibGljGAIgASgMUhNsb2NhbElkZW50aXR5UHVibGljEjIKFHJlbW90ZUlkZW50aXR5UHVibGljGAMgASgMUhRyZW1vdGVJZGVudGl0eVB1YmxpYxIYCgdyb290S2V5GAQgASgMUgdyb290S2V5EigKD3ByZXZpb3VzQ291bnRlchgFIAEoDVIPcHJldmlvdXNDb3VudGVyEkQKC3NlbmRlckNoYWluGAYgASgLMiIudGV4dHNlY3VyZS5TZXNzaW9uU3RydWN0dXJlLkNoYWluUgtzZW5kZXJDaGFpbhJKCg5yZWNlaXZlckNoYWlucxgHIAMoCzIiLnRleHRzZWN1cmUuU2Vzc2lvblN0cnVjdHVyZS5DaGFpblIOcmVjZWl2ZXJDaGFpbnMSXwoScGVuZGluZ0tleUV4Y2hhbmdlGAggASgLMi8udGV4dHNlY3VyZS5TZXNzaW9uU3RydWN0dXJlLlBlbmRpbmdLZXlFeGNoYW5nZVIScGVuZGluZ0tleUV4Y2hhbmdlElAKDXBlbmRpbmdQcmVLZXkYCSABKAsyKi50ZXh0c2VjdXJlLlNlc3Npb25TdHJ1Y3R1cmUuUGVuZGluZ1ByZUtleVINcGVuZGluZ1ByZUtleRIyChRyZW1vdGVSZWdpc3RyYXRpb25JZBgKIAEoDVIUcmVtb3RlUmVnaXN0cmF0aW9uSWQSMAoTbG9jYWxSZWdpc3RyYXRpb25JZBgLIAEoDVITbG9jYWxSZWdpc3RyYXRpb25JZBIiCgxuZWVkc1JlZnJlc2gYDCABKAhSDG5lZWRzUmVmcmVzaBIiCgxhbGljZUJhc2VLZXkYDSABKAxSDGFsaWNlQmFzZUtleRqlAwoFQ2hhaW4SKgoQc2VuZGVyUmF0Y2hldEtleRgBIAEoDFIQc2VuZGVyUmF0Y2hldEtleRI4ChdzZW5kZXJSYXRjaGV0S2V5UHJpdmF0ZRgCIAEoDFIXc2VuZGVyUmF0Y2hldEtleVByaXZhdGUSRwoIY2hhaW5LZXkYAyABKAsyKy50ZXh0c2VjdXJlLlNlc3Npb25TdHJ1Y3R1cmUuQ2hhaW4uQ2hhaW5LZXlSCGNoYWluS2V5Ek8KC21lc3NhZ2VLZXlzGAQgAygLMi0udGV4dHNlY3VyZS5TZXNzaW9uU3RydWN0dXJlLkNoYWluLk1lc3NhZ2VLZXlSC21lc3NhZ2VLZXlzGjIKCENoYWluS2V5EhQKBWluZGV4GAEgASgNUgVpbmRleBIQCgNrZXkYAiABKAxSA2tleRpoCgpNZXNzYWdlS2V5EhQKBWluZGV4GAEgASgNUgVpbmRleBIcCgljaXBoZXJLZXkYAiABKAxSCWNpcGhlcktleRIWCgZtYWNLZXkYAyABKAxSBm1hY0tleRIOCgJpdhgEIAEoDFICaXYazgIKElBlbmRpbmdLZXlFeGNoYW5nZRIaCghzZXF1ZW5jZRgBIAEoDVIIc2VxdWVuY2USIgoMbG9jYWxCYXNlS2V5GAIgASgMUgxsb2NhbEJhc2VLZXkSMAoTbG9jYWxCYXNlS2V5UHJpdmF0ZRgDIAEoDFITbG9jYWxCYXNlS2V5UHJpdmF0ZRIoCg9sb2NhbFJhdGNoZXRLZXkYBCABKAxSD2xvY2FsUmF0Y2hldEtleRI2ChZsb2NhbFJhdGNoZXRLZXlQcml2YXRlGAUgASgMUhZsb2NhbFJhdGNoZXRLZXlQcml2YXRlEioKEGxvY2FsSWRlbnRpdHlLZXkYByABKAxSEGxvY2FsSWRlbnRpdHlLZXkSOAoXbG9jYWxJZGVudGl0eUtleVByaXZhdGUYCCABKAxSF2xvY2FsSWRlbnRpdHlLZXlQcml2YXRlGm0KDVBlbmRpbmdQcmVLZXkSGgoIcHJlS2V5SWQYASABKA1SCHByZUtleUlkEiYKDnNpZ25lZFByZUtleUlkGAMgASgFUg5zaWduZWRQcmVLZXlJZBIYCgdiYXNlS2V5GAIgASgMUgdiYXNlS2V5'); +@$core.Deprecated('Use recordStructureDescriptor instead') +const recordStructure$json = { + '1': 'RecordStructure', + '2': [ + { + '1': 'currentSession', + '3': 1, + '4': 1, + '5': 11, + '6': '.textsecure.SessionStructure', + '10': 'currentSession' + }, + { + '1': 'previousSessions', + '3': 2, + '4': 3, + '5': 11, + '6': '.textsecure.SessionStructure', + '10': 'previousSessions' + }, + ], +}; + +/// Descriptor for `RecordStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List recordStructureDescriptor = $convert.base64Decode( + 'Cg9SZWNvcmRTdHJ1Y3R1cmUSRAoOY3VycmVudFNlc3Npb24YASABKAsyHC50ZXh0c2VjdXJlLlNlc3Npb25TdHJ1Y3R1cmVSDmN1cnJlbnRTZXNzaW9uEkgKEHByZXZpb3VzU2Vzc2lvbnMYAiADKAsyHC50ZXh0c2VjdXJlLlNlc3Npb25TdHJ1Y3R1cmVSEHByZXZpb3VzU2Vzc2lvbnM='); +@$core.Deprecated('Use preKeyRecordStructureDescriptor instead') +const preKeyRecordStructure$json = { + '1': 'PreKeyRecordStructure', + '2': [ + {'1': 'id', '3': 1, '4': 1, '5': 13, '10': 'id'}, + {'1': 'publicKey', '3': 2, '4': 1, '5': 12, '10': 'publicKey'}, + {'1': 'privateKey', '3': 3, '4': 1, '5': 12, '10': 'privateKey'}, + ], +}; + +/// Descriptor for `PreKeyRecordStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List preKeyRecordStructureDescriptor = $convert.base64Decode( + 'ChVQcmVLZXlSZWNvcmRTdHJ1Y3R1cmUSDgoCaWQYASABKA1SAmlkEhwKCXB1YmxpY0tleRgCIAEoDFIJcHVibGljS2V5Eh4KCnByaXZhdGVLZXkYAyABKAxSCnByaXZhdGVLZXk='); +@$core.Deprecated('Use signedPreKeyRecordStructureDescriptor instead') +const signedPreKeyRecordStructure$json = { + '1': 'SignedPreKeyRecordStructure', + '2': [ + {'1': 'id', '3': 1, '4': 1, '5': 13, '10': 'id'}, + {'1': 'publicKey', '3': 2, '4': 1, '5': 12, '10': 'publicKey'}, + {'1': 'privateKey', '3': 3, '4': 1, '5': 12, '10': 'privateKey'}, + {'1': 'signature', '3': 4, '4': 1, '5': 12, '10': 'signature'}, + {'1': 'timestamp', '3': 5, '4': 1, '5': 6, '10': 'timestamp'}, + ], +}; + +/// Descriptor for `SignedPreKeyRecordStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List signedPreKeyRecordStructureDescriptor = + $convert.base64Decode( + 'ChtTaWduZWRQcmVLZXlSZWNvcmRTdHJ1Y3R1cmUSDgoCaWQYASABKA1SAmlkEhwKCXB1YmxpY0tleRgCIAEoDFIJcHVibGljS2V5Eh4KCnByaXZhdGVLZXkYAyABKAxSCnByaXZhdGVLZXkSHAoJc2lnbmF0dXJlGAQgASgMUglzaWduYXR1cmUSHAoJdGltZXN0YW1wGAUgASgGUgl0aW1lc3RhbXA='); +@$core.Deprecated('Use identityKeyPairStructureDescriptor instead') +const identityKeyPairStructure$json = { + '1': 'IdentityKeyPairStructure', + '2': [ + {'1': 'publicKey', '3': 1, '4': 1, '5': 12, '10': 'publicKey'}, + {'1': 'privateKey', '3': 2, '4': 1, '5': 12, '10': 'privateKey'}, + ], +}; + +/// Descriptor for `IdentityKeyPairStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List identityKeyPairStructureDescriptor = + $convert.base64Decode( + 'ChhJZGVudGl0eUtleVBhaXJTdHJ1Y3R1cmUSHAoJcHVibGljS2V5GAEgASgMUglwdWJsaWNLZXkSHgoKcHJpdmF0ZUtleRgCIAEoDFIKcHJpdmF0ZUtleQ=='); +@$core.Deprecated('Use senderKeyStateStructureDescriptor instead') +const senderKeyStateStructure$json = { + '1': 'SenderKeyStateStructure', + '2': [ + {'1': 'senderKeyId', '3': 1, '4': 1, '5': 13, '10': 'senderKeyId'}, + { + '1': 'senderChainKey', + '3': 2, + '4': 1, + '5': 11, + '6': '.textsecure.SenderKeyStateStructure.SenderChainKey', + '10': 'senderChainKey' + }, + { + '1': 'senderSigningKey', + '3': 3, + '4': 1, + '5': 11, + '6': '.textsecure.SenderKeyStateStructure.SenderSigningKey', + '10': 'senderSigningKey' + }, + { + '1': 'senderMessageKeys', + '3': 4, + '4': 3, + '5': 11, + '6': '.textsecure.SenderKeyStateStructure.SenderMessageKey', + '10': 'senderMessageKeys' + }, + ], + '3': [ + senderKeyStateStructureSenderChainKey$json, + senderKeyStateStructureSenderMessageKey$json, + senderKeyStateStructureSenderSigningKey$json + ], +}; + +@$core.Deprecated('Use senderKeyStateStructureDescriptor instead') +const senderKeyStateStructureSenderChainKey$json = { + '1': 'SenderChainKey', + '2': [ + {'1': 'iteration', '3': 1, '4': 1, '5': 13, '10': 'iteration'}, + {'1': 'seed', '3': 2, '4': 1, '5': 12, '10': 'seed'}, + ], +}; + +@$core.Deprecated('Use senderKeyStateStructureDescriptor instead') +const senderKeyStateStructureSenderMessageKey$json = { + '1': 'SenderMessageKey', + '2': [ + {'1': 'iteration', '3': 1, '4': 1, '5': 13, '10': 'iteration'}, + {'1': 'seed', '3': 2, '4': 1, '5': 12, '10': 'seed'}, + ], +}; + +@$core.Deprecated('Use senderKeyStateStructureDescriptor instead') +const senderKeyStateStructureSenderSigningKey$json = { + '1': 'SenderSigningKey', + '2': [ + {'1': 'public', '3': 1, '4': 1, '5': 12, '10': 'public'}, + {'1': 'private', '3': 2, '4': 1, '5': 12, '10': 'private'}, + ], +}; + +/// Descriptor for `SenderKeyStateStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List senderKeyStateStructureDescriptor = + $convert.base64Decode( + 'ChdTZW5kZXJLZXlTdGF0ZVN0cnVjdHVyZRIgCgtzZW5kZXJLZXlJZBgBIAEoDVILc2VuZGVyS2V5SWQSWgoOc2VuZGVyQ2hhaW5LZXkYAiABKAsyMi50ZXh0c2VjdXJlLlNlbmRlcktleVN0YXRlU3RydWN0dXJlLlNlbmRlckNoYWluS2V5Ug5zZW5kZXJDaGFpbktleRJgChBzZW5kZXJTaWduaW5nS2V5GAMgASgLMjQudGV4dHNlY3VyZS5TZW5kZXJLZXlTdGF0ZVN0cnVjdHVyZS5TZW5kZXJTaWduaW5nS2V5UhBzZW5kZXJTaWduaW5nS2V5EmIKEXNlbmRlck1lc3NhZ2VLZXlzGAQgAygLMjQudGV4dHNlY3VyZS5TZW5kZXJLZXlTdGF0ZVN0cnVjdHVyZS5TZW5kZXJNZXNzYWdlS2V5UhFzZW5kZXJNZXNzYWdlS2V5cxpCCg5TZW5kZXJDaGFpbktleRIcCglpdGVyYXRpb24YASABKA1SCWl0ZXJhdGlvbhISCgRzZWVkGAIgASgMUgRzZWVkGkQKEFNlbmRlck1lc3NhZ2VLZXkSHAoJaXRlcmF0aW9uGAEgASgNUglpdGVyYXRpb24SEgoEc2VlZBgCIAEoDFIEc2VlZBpEChBTZW5kZXJTaWduaW5nS2V5EhYKBnB1YmxpYxgBIAEoDFIGcHVibGljEhgKB3ByaXZhdGUYAiABKAxSB3ByaXZhdGU='); +@$core.Deprecated('Use senderKeyRecordStructureDescriptor instead') +const senderKeyRecordStructure$json = { + '1': 'SenderKeyRecordStructure', + '2': [ + { + '1': 'senderKeyStates', + '3': 1, + '4': 3, + '5': 11, + '6': '.textsecure.SenderKeyStateStructure', + '10': 'senderKeyStates' + }, + ], +}; + +/// Descriptor for `SenderKeyRecordStructure`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List senderKeyRecordStructureDescriptor = + $convert.base64Decode( + 'ChhTZW5kZXJLZXlSZWNvcmRTdHJ1Y3R1cmUSTQoPc2VuZGVyS2V5U3RhdGVzGAEgAygLMiMudGV4dHNlY3VyZS5TZW5kZXJLZXlTdGF0ZVN0cnVjdHVyZVIPc2VuZGVyS2V5U3RhdGVz'); diff --git a/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbserver.dart b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbserver.dart new file mode 100644 index 0000000..b4dccdd --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pbserver.dart @@ -0,0 +1,7 @@ +// Generated code. Do not modify. +// source: LocalStorageProtocol.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'local_storage_protocol.pb.dart'; diff --git a/libsignal_protocol_dart/lib/src/state/pre_key_bundle.dart b/libsignal_protocol_dart/lib/src/state/pre_key_bundle.dart new file mode 100644 index 0000000..6b0fe5e --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/pre_key_bundle.dart @@ -0,0 +1,45 @@ +import 'dart:typed_data'; + +import '../ecc/ec_public_key.dart'; +import '../identity_key.dart'; + +class PreKeyBundle { + PreKeyBundle( + this._registrationId, + this._deviceId, + this._preKeyId, + this._preKeyPublic, + this._signedPreKeyId, + this._signedPreKeyPublic, + this._signedPreKeySignature, + this._identityKey); + + final int _registrationId; + + final int _deviceId; + + final int? _preKeyId; + final ECPublicKey? _preKeyPublic; + + final int _signedPreKeyId; + final ECPublicKey? _signedPreKeyPublic; + final Uint8List? _signedPreKeySignature; + + final IdentityKey _identityKey; + + int getDeviceId() => _deviceId; + + int? getPreKeyId() => _preKeyId; + + ECPublicKey? getPreKey() => _preKeyPublic; + + int getSignedPreKeyId() => _signedPreKeyId; + + ECPublicKey? getSignedPreKey() => _signedPreKeyPublic; + + Uint8List? getSignedPreKeySignature() => _signedPreKeySignature; + + IdentityKey getIdentityKey() => _identityKey; + + int getRegistrationId() => _registrationId; +} diff --git a/libsignal_protocol_dart/lib/src/state/pre_key_record.dart b/libsignal_protocol_dart/lib/src/state/pre_key_record.dart new file mode 100644 index 0000000..6635b7c --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/pre_key_record.dart @@ -0,0 +1,37 @@ +import 'dart:typed_data'; +import '../ecc/curve.dart'; +import '../ecc/ec_key_pair.dart'; +import '../invalid_key_exception.dart'; +import 'local_storage_protocol.pb.dart'; + +class PreKeyRecord { + PreKeyRecord(int id, ECKeyPair keyPair) { + _structure = PreKeyRecordStructure.create() + ..id = id + ..publicKey = keyPair.publicKey.serialize() + ..privateKey = keyPair.privateKey.serialize() + ..toBuilder(); + } + + PreKeyRecord.fromBuffer(Uint8List serialized) { + _structure = PreKeyRecordStructure.fromBuffer(serialized); + } + + late PreKeyRecordStructure _structure; + + int get id => _structure.id; + + ECKeyPair getKeyPair() { + try { + final publicKey = + Curve.decodePoint(Uint8List.fromList(_structure.publicKey), 0); + final privateKey = + Curve.decodePrivatePoint(Uint8List.fromList(_structure.privateKey)); + return ECKeyPair(publicKey, privateKey); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } + + Uint8List serialize() => _structure.writeToBuffer(); +} diff --git a/libsignal_protocol_dart/lib/src/state/pre_key_store.dart b/libsignal_protocol_dart/lib/src/state/pre_key_store.dart new file mode 100644 index 0000000..b88c78f --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/pre_key_store.dart @@ -0,0 +1,12 @@ +import 'pre_key_record.dart'; + +abstract mixin class PreKeyStore { + Future loadPreKey( + int preKeyId); // throws InvalidKeyIdException; + + Future storePreKey(int preKeyId, PreKeyRecord record); + + Future containsPreKey(int preKeyId); + + Future removePreKey(int preKeyId); +} diff --git a/libsignal_protocol_dart/lib/src/state/session_record.dart b/libsignal_protocol_dart/lib/src/state/session_record.dart new file mode 100644 index 0000000..6f0694c --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/session_record.dart @@ -0,0 +1,86 @@ +import 'dart:collection'; +import 'dart:typed_data'; + +import '../eq.dart'; +import 'local_storage_protocol.pb.dart'; +import 'session_state.dart'; + +class SessionRecord { + SessionRecord() { + _fresh = true; + } + + SessionRecord.fromSessionState(SessionState sessionState) { + _sessionState = sessionState; + _fresh = false; + } + + SessionRecord.fromSerialized(Uint8List serialized) { + final record = RecordStructure.fromBuffer(serialized); + _sessionState = SessionState.fromStructure(record.currentSession); + _fresh = false; + + for (final previousStructure in record.previousSessions) { + _previousStates.add(SessionState.fromStructure(previousStructure)); + } + } + + static const int archivedStatesMaxLength = 40; + var _sessionState = SessionState(); + final _previousStates = LinkedList(); + bool _fresh = false; + + bool hasSessionState(int version, Uint8List aliceBaseKey) { + if (_sessionState.getSessionVersion() == version && + eq(aliceBaseKey, _sessionState.aliceBaseKey)) { + return true; + } + + for (final state in _previousStates) { + if (state.getSessionVersion() == version && + eq(aliceBaseKey, _sessionState.aliceBaseKey)) { + return true; + } + } + return false; + } + + SessionState get sessionState => _sessionState; + + LinkedList get previousSessionStates => _previousStates; + + void removePreviousSessionStates() { + _previousStates.clear(); + } + + bool isFresh() => _fresh; + + void archiveCurrentState() { + promoteState(SessionState()); + } + + void promoteState(SessionState promotedState) { + _previousStates.addFirst(_sessionState); + _sessionState = promotedState; + + if (_previousStates.length > archivedStatesMaxLength) { + _previousStates.remove(_previousStates.last); + } + } + + set state(SessionState sessionState) { + _sessionState = sessionState; + } + + Uint8List serialize() { + final previousStructures = []; + for (final previousState in _previousStates) { + previousStructures.add(previousState.structure); + } + final record = RecordStructure.create() + ..currentSession = _sessionState.structure + ..previousSessions.addAll(previousStructures); + + return record.toBuilder().writeToBuffer(); + } +} diff --git a/libsignal_protocol_dart/lib/src/state/session_state.dart b/libsignal_protocol_dart/lib/src/state/session_state.dart new file mode 100644 index 0000000..f5f7a4a --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/session_state.dart @@ -0,0 +1,399 @@ +import 'dart:collection'; +import 'dart:typed_data'; + +import 'package:optional/optional.dart'; + +import '../ecc/curve.dart'; +import '../ecc/ec_key_pair.dart'; +import '../ecc/ec_public_key.dart'; +import '../entry.dart'; +import '../eq.dart'; +import '../identity_key.dart'; +import '../identity_key_pair.dart'; +import '../invalid_key_exception.dart'; +import '../kdf/hkdf.dart'; +import '../ratchet/chain_key.dart'; +import '../ratchet/message_keys.dart'; +import '../ratchet/root_key.dart'; +import '../util/log.dart' as $log; +import 'local_storage_protocol.pb.dart'; + +base class SessionState extends LinkedListEntry { + SessionState() { + _sessionStructure = SessionStructure.create(); + } + + SessionState.fromStructure(SessionStructure sessionStructure) { + _sessionStructure = sessionStructure; + } + + SessionState.fromSessionState(SessionState copy) { + _sessionStructure = copy.structure; + } + + static const int maxMessageKeys = 2000; + + late SessionStructure _sessionStructure; + + SessionStructure get structure => _sessionStructure; + + Uint8List get aliceBaseKey => + Uint8List.fromList(_sessionStructure.aliceBaseKey); + + set aliceBaseKey(Uint8List aliceBaseKey) { + _sessionStructure.aliceBaseKey = aliceBaseKey; + } + + set sessionVersion(int version) => _sessionStructure.sessionVersion = version; + + int getSessionVersion() { + final sessionVersion = _sessionStructure.sessionVersion; + if (sessionVersion == 0) { + return 2; + } else { + return sessionVersion; + } + } + + set remoteIdentityKey(IdentityKey identityKey) => + _sessionStructure.remoteIdentityPublic = identityKey.serialize(); + + set localIdentityKey(IdentityKey identityKey) => + _sessionStructure.localIdentityPublic = identityKey.serialize(); + + IdentityKey? getRemoteIdentityKey() { + try { + if (!_sessionStructure.hasRemoteIdentityPublic()) { + return null; + } + return IdentityKey.fromBytes( + Uint8List.fromList(_sessionStructure.remoteIdentityPublic), 0); + } on InvalidKeyException catch (e) { + $log.log(e); + return null; + } + } + + IdentityKey getLocalIdentityKey() { + try { + return IdentityKey.fromBytes( + Uint8List.fromList(_sessionStructure.localIdentityPublic), 0); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } + + int get previousCounter => _sessionStructure.previousCounter; + + set previousCounter(int previousCounter) => + _sessionStructure.previousCounter = previousCounter; + + RootKey getRootKey() => RootKey(HKDF.createFor(getSessionVersion()), + Uint8List.fromList(_sessionStructure.rootKey)); + + set rootKey(RootKey rootKey) => + _sessionStructure.rootKey = rootKey.getKeyBytes(); + + ECPublicKey getSenderRatchetKey() { + try { + return Curve.decodePoint( + Uint8List.fromList(_sessionStructure.senderChain.senderRatchetKey), + 0); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } + + ECKeyPair getSenderRatchetKeyPair() { + final publicKey = getSenderRatchetKey(); + final privateKey = Curve.decodePrivatePoint(Uint8List.fromList( + _sessionStructure.senderChain.senderRatchetKeyPrivate)); + return ECKeyPair(publicKey, privateKey); + } + + bool hasReceiverChain(ECPublicKey senderEphemeral) => + _getReceiverChain(senderEphemeral) != null; + + bool hasSenderChain() => _sessionStructure.hasSenderChain(); + + (SessionStructureChain, int)? _getReceiverChain(ECPublicKey senderEphemeral) { + final receiverChains = _sessionStructure.receiverChains; + var index = 0; + + for (final receiverChain in receiverChains) { + try { + final chainSenderRatchetKey = Curve.decodePoint( + Uint8List.fromList(receiverChain.senderRatchetKey), 0); + + if (eq( + chainSenderRatchetKey.serialize(), senderEphemeral.serialize())) { + return (receiverChain, index); + } + } on InvalidKeyException catch (e) { + $log.log(e); + } + index++; + } + + return null; + } + + ChainKey? getReceiverChainKey(ECPublicKey senderEphemeral) { + final receiverChainAndIndex = _getReceiverChain(senderEphemeral); + final receiverChain = receiverChainAndIndex?.$1; + + if (receiverChain == null) { + return null; + } else { + return ChainKey( + HKDF.createFor(getSessionVersion()), + Uint8List.fromList(receiverChain.chainKey.key), + receiverChain.chainKey.index); + } + } + + void addReceiverChain(ECPublicKey senderRatchetKey, ChainKey chainKey) { + final chainKeyStructure = SessionStructureChainChainKey.create() + ..key = chainKey.key; + + final chain = SessionStructureChain.create() + ..chainKey = chainKeyStructure + ..senderRatchetKey = senderRatchetKey.serialize(); + + _sessionStructure.receiverChains.add(chain); + + if (_sessionStructure.receiverChains.length > 5) { + _sessionStructure.receiverChains.removeAt(0); + } + } + + void setSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey) { + final chainKeyStructure = SessionStructureChainChainKey.create() + ..key = chainKey.key + ..index = chainKey.index; + + final senderChain = SessionStructureChain.create() + ..senderRatchetKey = senderRatchetKeyPair.publicKey.serialize() + ..senderRatchetKeyPrivate = senderRatchetKeyPair.privateKey.serialize() + ..chainKey = chainKeyStructure; + _sessionStructure.senderChain = senderChain; + } + + ChainKey getSenderChainKey() { + final chainKeyStructure = _sessionStructure.senderChain.chainKey; + return ChainKey(HKDF.createFor(getSessionVersion()), + Uint8List.fromList(chainKeyStructure.key), chainKeyStructure.index); + } + + void setSenderChainKey(ChainKey nextChainKey) { + final chainKey = SessionStructureChainChainKey.create() + ..key = nextChainKey.key + ..index = nextChainKey.index; + + _sessionStructure.senderChain.chainKey = chainKey; + } + + bool hasMessageKeys(ECPublicKey senderEphemeral, int counter) { + final chainAndIndex = _getReceiverChain(senderEphemeral); + if (chainAndIndex == null) { + return false; + } + final chain = chainAndIndex.$1; + + final messageKeyList = chain.messageKeys; + for (final messageKey in messageKeyList) { + if (messageKey.index == counter) { + return true; + } + } + return false; + } + + MessageKeys? removeMessageKeys(ECPublicKey senderEphemeral, int counter) { + final chainAndIndex = _getReceiverChain(senderEphemeral); + if (chainAndIndex == null) { + return null; + } + final chain = chainAndIndex.$1; + + final messageKeyList = LinkedList>(); + chain.messageKeys.forEach((element) { + messageKeyList.add(Entry(element)); + }); + final messageKeyIterator = messageKeyList.iterator; + MessageKeys? result; + while (messageKeyIterator.moveNext()) { + final entry = messageKeyIterator.current; + final messageKey = entry.value; + if (messageKey.index == counter) { + final cipherKey = Uint8List.fromList(messageKey.cipherKey); + final macKey = Uint8List.fromList(messageKey.macKey); + final iv = Uint8List.fromList(messageKey.iv); + final index = messageKey.index; + result = MessageKeys(cipherKey, macKey, iv, index); + + messageKeyList.remove(entry); + break; + } + } + + chain.messageKeys.clear(); + messageKeyList.forEach((entry) { + chain.messageKeys.add(entry.value); + }); + + _sessionStructure.receiverChains + .setAll(chainAndIndex.$2, [chain]); + return result; + } + + void setMessageKeys(ECPublicKey senderEphemeral, MessageKeys messageKeys) { + final chainAndIndex = _getReceiverChain(senderEphemeral); + if (chainAndIndex == null) { + return; + } + final chain = chainAndIndex.$1; + final messageKeyStructure = SessionStructureChainMessageKey.create() + ..cipherKey = Uint8List.fromList(messageKeys.getCipherKey()) + ..macKey = Uint8List.fromList(messageKeys.getMacKey()) + ..index = messageKeys.getCounter() + ..iv = Uint8List.fromList(messageKeys.getIv()); + + chain.messageKeys.add(messageKeyStructure); + + if (chain.messageKeys.length > maxMessageKeys) { + chain.messageKeys.removeAt(0); + } + + _sessionStructure.receiverChains + .setAll(chainAndIndex.$2, [chain]); + } + + void setReceiverChainKey(ECPublicKey senderEphemeral, ChainKey chainKey) { + final chainAndIndex = _getReceiverChain(senderEphemeral); + final chain = chainAndIndex!.$1; + + final chainKeyStructure = SessionStructureChainChainKey.create() + ..key = chainKey.key + ..index = chainKey.index; + + chain.chainKey = chainKeyStructure; + _sessionStructure.receiverChains + .setAll(chainAndIndex.$2, [chain]); + } + + void setPendingKeyExchange(int sequence, ECKeyPair ourBaseKey, + ECKeyPair ourRatchetKey, IdentityKeyPair ourIdentityKey) { + final structure = SessionStructurePendingKeyExchange.create() + ..sequence = sequence + ..localBaseKey = ourBaseKey.publicKey.serialize() + ..localBaseKeyPrivate = ourBaseKey.privateKey.serialize() + ..localRatchetKey = ourRatchetKey.publicKey.serialize() + ..localRatchetKeyPrivate = ourRatchetKey.privateKey.serialize() + ..localIdentityKey = ourIdentityKey.getPublicKey().serialize() + ..localIdentityKeyPrivate = ourIdentityKey.getPrivateKey().serialize(); + + _sessionStructure.pendingKeyExchange = structure; + } + + int getPendingKeyExchangeSequence() => + _sessionStructure.pendingKeyExchange.sequence; + + ECKeyPair getPendingKeyExchangeBaseKey() { + final publicKey = Curve.decodePoint( + Uint8List.fromList(_sessionStructure.pendingKeyExchange.localBaseKey), + 0); + + final privateKey = Curve.decodePrivatePoint(Uint8List.fromList( + _sessionStructure.pendingKeyExchange.localBaseKeyPrivate)); + + return ECKeyPair(publicKey, privateKey); + } + + ECKeyPair getPendingKeyExchangeRatchetKey() { + final publicKey = Curve.decodePointList( + _sessionStructure.pendingKeyExchange.localRatchetKey, 0); + + final privateKey = Curve.decodePrivatePoint(Uint8List.fromList( + _sessionStructure.pendingKeyExchange.localRatchetKeyPrivate)); + + return ECKeyPair(publicKey, privateKey); + } + + IdentityKeyPair getPendingKeyExchangeIdentityKey() { + final publicKey = IdentityKey.fromBytes( + Uint8List.fromList( + _sessionStructure.pendingKeyExchange.localIdentityKey), + 0); + final privateKey = Curve.decodePrivatePoint(Uint8List.fromList( + _sessionStructure.pendingKeyExchange.localIdentityKeyPrivate)); + return IdentityKeyPair(publicKey, privateKey); + } + + bool hasPendingKeyExchange() => _sessionStructure.hasPendingKeyExchange(); + + void setUnacknowledgedPreKeyMessage( + Optional preKeyId, int signedPreKeyId, ECPublicKey baseKey) { + final pending = SessionStructurePendingPreKey.create() + ..signedPreKeyId = signedPreKeyId + ..baseKey = baseKey.serialize(); + + if (preKeyId.isPresent) { + pending.preKeyId = preKeyId.value; + } + + _sessionStructure.pendingPreKey = pending; + } + + bool hasUnacknowledgedPreKeyMessage() => _sessionStructure.hasPendingPreKey(); + + UnacknowledgedPreKeyMessageItems getUnacknowledgedPreKeyMessageItems() { + try { + Optional preKeyId; + + if (_sessionStructure.pendingPreKey.hasPreKeyId()) { + preKeyId = Optional.of(_sessionStructure.pendingPreKey.preKeyId); + } else { + preKeyId = const Optional.empty(); + } + + return UnacknowledgedPreKeyMessageItems( + preKeyId, + _sessionStructure.pendingPreKey.signedPreKeyId, + Curve.decodePointList(_sessionStructure.pendingPreKey.baseKey, 0)); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } + + void clearUnacknowledgedPreKeyMessage() { + _sessionStructure.clearPendingPreKey(); + } + + set remoteRegistrationId(int registrationId) => + _sessionStructure..remoteRegistrationId = registrationId; + + int get remoteRegistrationId => _sessionStructure.remoteRegistrationId; + + set localRegistrationId(int registrationId) => + _sessionStructure.localRegistrationId = registrationId; + + int get localRegistrationId => _sessionStructure.localRegistrationId; + + Uint8List serialize() => _sessionStructure.writeToBuffer(); +} + +class UnacknowledgedPreKeyMessageItems { + UnacknowledgedPreKeyMessageItems( + this._preKeyId, this._signedPreKeyId, this._baseKey); + + final Optional _preKeyId; + final int _signedPreKeyId; + final ECPublicKey _baseKey; + + Optional getPreKeyId() => _preKeyId; + + int getSignedPreKeyId() => _signedPreKeyId; + + ECPublicKey getBaseKey() => _baseKey; +} diff --git a/libsignal_protocol_dart/lib/src/state/session_store.dart b/libsignal_protocol_dart/lib/src/state/session_store.dart new file mode 100644 index 0000000..dce4ee8 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/session_store.dart @@ -0,0 +1,18 @@ +import '../signal_protocol_address.dart'; + +import 'session_record.dart'; + +abstract mixin class SessionStore { + Future loadSession(SignalProtocolAddress address); + + Future> getSubDeviceSessions(String name); + + Future storeSession( + SignalProtocolAddress address, SessionRecord record); + + Future containsSession(SignalProtocolAddress address); + + Future deleteSession(SignalProtocolAddress address); + + Future deleteAllSessions(String name); +} diff --git a/libsignal_protocol_dart/lib/src/state/signal_protocol_store.dart b/libsignal_protocol_dart/lib/src/state/signal_protocol_store.dart new file mode 100644 index 0000000..ad8312d --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/signal_protocol_store.dart @@ -0,0 +1,7 @@ +import 'identity_key_store.dart'; +import 'pre_key_store.dart'; +import 'session_store.dart'; +import 'signed_pre_key_store.dart'; + +abstract class SignalProtocolStore extends IdentityKeyStore + with PreKeyStore, SessionStore, SignedPreKeyStore {} diff --git a/libsignal_protocol_dart/lib/src/state/signed_pre_key_record.dart b/libsignal_protocol_dart/lib/src/state/signed_pre_key_record.dart new file mode 100644 index 0000000..50e68cc --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/signed_pre_key_record.dart @@ -0,0 +1,45 @@ +import 'dart:typed_data'; + +import 'package:fixnum/fixnum.dart'; +import '../ecc/curve.dart'; +import '../ecc/ec_key_pair.dart'; +import '../invalid_key_exception.dart'; +import 'local_storage_protocol.pb.dart'; + +class SignedPreKeyRecord { + SignedPreKeyRecord( + int id, Int64 timestamp, ECKeyPair keyPair, Uint8List signature) { + _structure = SignedPreKeyRecordStructure.create() + ..id = id + ..timestamp = timestamp + ..publicKey = keyPair.publicKey.serialize() + ..privateKey = keyPair.privateKey.serialize() + ..signature = signature; + } + + SignedPreKeyRecord.fromSerialized(Uint8List serialized) { + _structure = SignedPreKeyRecordStructure.fromBuffer(serialized); + } + + late SignedPreKeyRecordStructure _structure; + + int get id => _structure.id; + + Int64 get timestamp => _structure.timestamp; + + ECKeyPair getKeyPair() { + try { + final publicKey = Curve.decodePointList(_structure.publicKey, 0); + final privateKey = + Curve.decodePrivatePoint(Uint8List.fromList(_structure.privateKey)); + + return ECKeyPair(publicKey, privateKey); + } on InvalidKeyException catch (e) { + throw AssertionError(e); + } + } + + Uint8List get signature => Uint8List.fromList(_structure.signature); + + Uint8List serialize() => _structure.writeToBuffer(); +} diff --git a/libsignal_protocol_dart/lib/src/state/signed_pre_key_store.dart b/libsignal_protocol_dart/lib/src/state/signed_pre_key_store.dart new file mode 100644 index 0000000..2374e9e --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/signed_pre_key_store.dart @@ -0,0 +1,15 @@ +import 'signed_pre_key_record.dart'; + +abstract mixin class SignedPreKeyStore { + Future loadSignedPreKey( + int signedPreKeyId, + ); //throws InvalidKeyIdException; + + Future> loadSignedPreKeys(); + + Future storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record); + + Future containsSignedPreKey(int signedPreKeyId); + + Future removeSignedPreKey(int signedPreKeyId); +} diff --git a/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart new file mode 100644 index 0000000..4dfedc0 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart @@ -0,0 +1,956 @@ +import 'dart:core' as $core; +import 'dart:core'; + +import 'package:protobuf/protobuf.dart' as $pb; + +class SignalMessage extends $pb.GeneratedMessage { + factory SignalMessage({ + $core.List<$core.int>? ratchetKey, + $core.int? counter, + $core.int? previousCounter, + $core.List<$core.int>? ciphertext, + }) { + final _result = create(); + if (ratchetKey != null) { + _result.ratchetKey = ratchetKey; + } + if (counter != null) { + _result.counter = counter; + } + if (previousCounter != null) { + _result.previousCounter = previousCounter; + } + if (ciphertext != null) { + _result.ciphertext = ciphertext; + } + return _result; + } + + SignalMessage._() : super(); + + factory SignalMessage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SignalMessage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SignalMessage', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'ratchetKey', + $pb.PbFieldType.OY, + protoName: 'ratchetKey') + ..a<$core.int>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'counter', + $pb.PbFieldType.OU3) + ..a<$core.int>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'previousCounter', + $pb.PbFieldType.OU3, + protoName: 'previousCounter') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'ciphertext', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SignalMessage clone() => SignalMessage()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SignalMessage copyWith(void Function(SignalMessage) updates) => + super.copyWith((message) => updates(message as SignalMessage)) + as SignalMessage; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SignalMessage create() => SignalMessage._(); + + @override + SignalMessage createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SignalMessage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SignalMessage? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get ratchetKey => $_getN(0); + + @$pb.TagNumber(1) + set ratchetKey($core.List<$core.int> v) { + $_setBytes(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasRatchetKey() => $_has(0); + + @$pb.TagNumber(1) + void clearRatchetKey() => clearField(1); + + @$pb.TagNumber(2) + $core.int get counter => $_getIZ(1); + + @$pb.TagNumber(2) + set counter($core.int v) { + $_setUnsignedInt32(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasCounter() => $_has(1); + + @$pb.TagNumber(2) + void clearCounter() => clearField(2); + + @$pb.TagNumber(3) + $core.int get previousCounter => $_getIZ(2); + + @$pb.TagNumber(3) + set previousCounter($core.int v) { + $_setUnsignedInt32(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasPreviousCounter() => $_has(2); + + @$pb.TagNumber(3) + void clearPreviousCounter() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get ciphertext => $_getN(3); + + @$pb.TagNumber(4) + set ciphertext($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasCiphertext() => $_has(3); + + @$pb.TagNumber(4) + void clearCiphertext() => clearField(4); +} + +class PreKeySignalMessage extends $pb.GeneratedMessage { + factory PreKeySignalMessage({ + $core.int? preKeyId, + $core.List<$core.int>? baseKey, + $core.List<$core.int>? identityKey, + $core.List<$core.int>? message, + $core.int? registrationId, + $core.int? signedPreKeyId, + }) { + final _result = create(); + if (preKeyId != null) { + _result.preKeyId = preKeyId; + } + if (baseKey != null) { + _result.baseKey = baseKey; + } + if (identityKey != null) { + _result.identityKey = identityKey; + } + if (message != null) { + _result.message = message; + } + if (registrationId != null) { + _result.registrationId = registrationId; + } + if (signedPreKeyId != null) { + _result.signedPreKeyId = signedPreKeyId; + } + return _result; + } + + PreKeySignalMessage._() : super(); + + factory PreKeySignalMessage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory PreKeySignalMessage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'PreKeySignalMessage', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'preKeyId', + $pb.PbFieldType.OU3, + protoName: 'preKeyId') + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'baseKey', + $pb.PbFieldType.OY, + protoName: 'baseKey') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'identityKey', + $pb.PbFieldType.OY, + protoName: 'identityKey') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'message', + $pb.PbFieldType.OY) + ..a<$core.int>( + 5, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'registrationId', + $pb.PbFieldType.OU3, + protoName: 'registrationId') + ..a<$core.int>( + 6, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'signedPreKeyId', + $pb.PbFieldType.OU3, + protoName: 'signedPreKeyId') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + PreKeySignalMessage clone() => PreKeySignalMessage()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + PreKeySignalMessage copyWith(void Function(PreKeySignalMessage) updates) => + super.copyWith((message) => updates(message as PreKeySignalMessage)) + as PreKeySignalMessage; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static PreKeySignalMessage create() => PreKeySignalMessage._(); + + @override + PreKeySignalMessage createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static PreKeySignalMessage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static PreKeySignalMessage? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get preKeyId => $_getIZ(0); + + @$pb.TagNumber(1) + set preKeyId($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasPreKeyId() => $_has(0); + + @$pb.TagNumber(1) + void clearPreKeyId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get baseKey => $_getN(1); + + @$pb.TagNumber(2) + set baseKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasBaseKey() => $_has(1); + + @$pb.TagNumber(2) + void clearBaseKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get identityKey => $_getN(2); + + @$pb.TagNumber(3) + set identityKey($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasIdentityKey() => $_has(2); + + @$pb.TagNumber(3) + void clearIdentityKey() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get message => $_getN(3); + + @$pb.TagNumber(4) + set message($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasMessage() => $_has(3); + + @$pb.TagNumber(4) + void clearMessage() => clearField(4); + + @$pb.TagNumber(5) + $core.int get registrationId => $_getIZ(4); + + @$pb.TagNumber(5) + set registrationId($core.int v) { + $_setUnsignedInt32(4, v); + } + + @$pb.TagNumber(5) + $core.bool hasRegistrationId() => $_has(4); + + @$pb.TagNumber(5) + void clearRegistrationId() => clearField(5); + + @$pb.TagNumber(6) + $core.int get signedPreKeyId => $_getIZ(5); + + @$pb.TagNumber(6) + set signedPreKeyId($core.int v) { + $_setUnsignedInt32(5, v); + } + + @$pb.TagNumber(6) + $core.bool hasSignedPreKeyId() => $_has(5); + + @$pb.TagNumber(6) + void clearSignedPreKeyId() => clearField(6); +} + +class KeyExchangeMessage extends $pb.GeneratedMessage { + factory KeyExchangeMessage({ + $core.int? id, + $core.List<$core.int>? baseKey, + $core.List<$core.int>? ratchetKey, + $core.List<$core.int>? identityKey, + $core.List<$core.int>? baseKeySignature, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (baseKey != null) { + _result.baseKey = baseKey; + } + if (ratchetKey != null) { + _result.ratchetKey = ratchetKey; + } + if (identityKey != null) { + _result.identityKey = identityKey; + } + if (baseKeySignature != null) { + _result.baseKeySignature = baseKeySignature; + } + return _result; + } + + KeyExchangeMessage._() : super(); + + factory KeyExchangeMessage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory KeyExchangeMessage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'KeyExchangeMessage', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'id', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'baseKey', + $pb.PbFieldType.OY, + protoName: 'baseKey') + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'ratchetKey', + $pb.PbFieldType.OY, + protoName: 'ratchetKey') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'identityKey', + $pb.PbFieldType.OY, + protoName: 'identityKey') + ..a<$core.List<$core.int>>( + 5, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'baseKeySignature', + $pb.PbFieldType.OY, + protoName: 'baseKeySignature') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + KeyExchangeMessage clone() => KeyExchangeMessage()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + KeyExchangeMessage copyWith(void Function(KeyExchangeMessage) updates) => + super.copyWith((message) => updates(message as KeyExchangeMessage)) + as KeyExchangeMessage; // ignore: deprecated_member_use + + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static KeyExchangeMessage create() => KeyExchangeMessage._(); + + @override + KeyExchangeMessage createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static KeyExchangeMessage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static KeyExchangeMessage? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get id => $_getIZ(0); + + @$pb.TagNumber(1) + set id($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get baseKey => $_getN(1); + + @$pb.TagNumber(2) + set baseKey($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasBaseKey() => $_has(1); + + @$pb.TagNumber(2) + void clearBaseKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get ratchetKey => $_getN(2); + + @$pb.TagNumber(3) + set ratchetKey($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasRatchetKey() => $_has(2); + + @$pb.TagNumber(3) + void clearRatchetKey() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get identityKey => $_getN(3); + + @$pb.TagNumber(4) + set identityKey($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasIdentityKey() => $_has(3); + + @$pb.TagNumber(4) + void clearIdentityKey() => clearField(4); + + @$pb.TagNumber(5) + $core.List<$core.int> get baseKeySignature => $_getN(4); + + @$pb.TagNumber(5) + set baseKeySignature($core.List<$core.int> v) { + $_setBytes(4, v); + } + + @$pb.TagNumber(5) + $core.bool hasBaseKeySignature() => $_has(4); + + @$pb.TagNumber(5) + void clearBaseKeySignature() => clearField(5); +} + +class SenderKeyMessage extends $pb.GeneratedMessage { + factory SenderKeyMessage({ + $core.int? id, + $core.int? iteration, + $core.List<$core.int>? ciphertext, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (iteration != null) { + _result.iteration = iteration; + } + if (ciphertext != null) { + _result.ciphertext = ciphertext; + } + return _result; + } + + SenderKeyMessage._() : super(); + + factory SenderKeyMessage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyMessage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyMessage', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'id', + $pb.PbFieldType.OU3) + ..a<$core.int>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'iteration', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'ciphertext', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyMessage clone() => SenderKeyMessage()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyMessage copyWith(void Function(SenderKeyMessage) updates) => + super.copyWith((message) => updates(message as SenderKeyMessage)) + as SenderKeyMessage; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyMessage create() => SenderKeyMessage._(); + + @override + SenderKeyMessage createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyMessage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SenderKeyMessage? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get id => $_getIZ(0); + + @$pb.TagNumber(1) + set id($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get iteration => $_getIZ(1); + + @$pb.TagNumber(2) + set iteration($core.int v) { + $_setUnsignedInt32(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasIteration() => $_has(1); + + @$pb.TagNumber(2) + void clearIteration() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get ciphertext => $_getN(2); + + @$pb.TagNumber(3) + set ciphertext($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasCiphertext() => $_has(2); + + @$pb.TagNumber(3) + void clearCiphertext() => clearField(3); +} + +class SenderKeyDistributionMessage extends $pb.GeneratedMessage { + factory SenderKeyDistributionMessage({ + $core.int? id, + $core.int? iteration, + $core.List<$core.int>? chainKey, + $core.List<$core.int>? signingKey, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (iteration != null) { + _result.iteration = iteration; + } + if (chainKey != null) { + _result.chainKey = chainKey; + } + if (signingKey != null) { + _result.signingKey = signingKey; + } + return _result; + } + + SenderKeyDistributionMessage._() : super(); + + factory SenderKeyDistributionMessage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory SenderKeyDistributionMessage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'SenderKeyDistributionMessage', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'id', + $pb.PbFieldType.OU3) + ..a<$core.int>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'iteration', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 3, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'chainKey', + $pb.PbFieldType.OY, + protoName: 'chainKey') + ..a<$core.List<$core.int>>( + 4, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'signingKey', + $pb.PbFieldType.OY, + protoName: 'signingKey') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + SenderKeyDistributionMessage clone() => + SenderKeyDistributionMessage()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + SenderKeyDistributionMessage copyWith( + void Function(SenderKeyDistributionMessage) updates) => + super.copyWith( + (message) => updates(message as SenderKeyDistributionMessage)) + as SenderKeyDistributionMessage; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SenderKeyDistributionMessage create() => + SenderKeyDistributionMessage._(); + + @override + SenderKeyDistributionMessage createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static SenderKeyDistributionMessage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SenderKeyDistributionMessage? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get id => $_getIZ(0); + + @$pb.TagNumber(1) + set id($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get iteration => $_getIZ(1); + + @$pb.TagNumber(2) + set iteration($core.int v) { + $_setUnsignedInt32(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasIteration() => $_has(1); + + @$pb.TagNumber(2) + void clearIteration() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get chainKey => $_getN(2); + + @$pb.TagNumber(3) + set chainKey($core.List<$core.int> v) { + $_setBytes(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasChainKey() => $_has(2); + + @$pb.TagNumber(3) + void clearChainKey() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get signingKey => $_getN(3); + + @$pb.TagNumber(4) + set signingKey($core.List<$core.int> v) { + $_setBytes(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasSigningKey() => $_has(3); + + @$pb.TagNumber(4) + void clearSigningKey() => clearField(4); +} + +class DeviceConsistencyCodeMessage extends $pb.GeneratedMessage { + factory DeviceConsistencyCodeMessage({ + $core.int? generation, + $core.List<$core.int>? signature, + }) { + final _result = create(); + if (generation != null) { + _result.generation = generation; + } + if (signature != null) { + _result.signature = signature; + } + return _result; + } + + DeviceConsistencyCodeMessage._() : super(); + + factory DeviceConsistencyCodeMessage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + + factory DeviceConsistencyCodeMessage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + const $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'DeviceConsistencyCodeMessage', + package: const $pb.PackageName( + $core.bool.fromEnvironment('protobuf.omit_message_names') + ? '' + : 'textsecure'), + createEmptyInstance: create) + ..a<$core.int>( + 1, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'generation', + $pb.PbFieldType.OU3) + ..a<$core.List<$core.int>>( + 2, + const $core.bool.fromEnvironment('protobuf.omit_field_names') + ? '' + : 'signature', + $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + @override + DeviceConsistencyCodeMessage clone() => + DeviceConsistencyCodeMessage()..mergeFromMessage(this); + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + @override + DeviceConsistencyCodeMessage copyWith( + void Function(DeviceConsistencyCodeMessage) updates) => + super.copyWith( + (message) => updates(message as DeviceConsistencyCodeMessage)) + as DeviceConsistencyCodeMessage; // ignore: deprecated_member_use + @override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static DeviceConsistencyCodeMessage create() => + DeviceConsistencyCodeMessage._(); + + @override + DeviceConsistencyCodeMessage createEmptyInstance() => create(); + + static $pb.PbList createRepeated() => + $pb.PbList(); + + @$core.pragma('dart2js:noInline') + static DeviceConsistencyCodeMessage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static DeviceConsistencyCodeMessage? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get generation => $_getIZ(0); + + @$pb.TagNumber(1) + set generation($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasGeneration() => $_has(0); + + @$pb.TagNumber(1) + void clearGeneration() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get signature => $_getN(1); + + @$pb.TagNumber(2) + set signature($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasSignature() => $_has(1); + + @$pb.TagNumber(2) + void clearSignature() => clearField(2); +} diff --git a/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbenum.dart b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbenum.dart new file mode 100644 index 0000000..74caa45 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbenum.dart @@ -0,0 +1,5 @@ +// Generated code. Do not modify. +// source: WhisperTextProtocol.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields diff --git a/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbjson.dart b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbjson.dart new file mode 100644 index 0000000..18ccbc3 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbjson.dart @@ -0,0 +1,96 @@ +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use signalMessageDescriptor instead') +const signalMessage$json = { + '1': 'SignalMessage', + '2': [ + {'1': 'ratchetKey', '3': 1, '4': 1, '5': 12, '10': 'ratchetKey'}, + {'1': 'counter', '3': 2, '4': 1, '5': 13, '10': 'counter'}, + {'1': 'previousCounter', '3': 3, '4': 1, '5': 13, '10': 'previousCounter'}, + {'1': 'ciphertext', '3': 4, '4': 1, '5': 12, '10': 'ciphertext'}, + ], +}; + +/// Descriptor for `SignalMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List signalMessageDescriptor = $convert.base64Decode( + 'Cg1TaWduYWxNZXNzYWdlEh4KCnJhdGNoZXRLZXkYASABKAxSCnJhdGNoZXRLZXkSGAoHY291bnRlchgCIAEoDVIHY291bnRlchIoCg9wcmV2aW91c0NvdW50ZXIYAyABKA1SD3ByZXZpb3VzQ291bnRlchIeCgpjaXBoZXJ0ZXh0GAQgASgMUgpjaXBoZXJ0ZXh0'); +@$core.Deprecated('Use preKeySignalMessageDescriptor instead') +const preKeySignalMessage$json = { + '1': 'PreKeySignalMessage', + '2': [ + {'1': 'registrationId', '3': 5, '4': 1, '5': 13, '10': 'registrationId'}, + {'1': 'preKeyId', '3': 1, '4': 1, '5': 13, '10': 'preKeyId'}, + {'1': 'signedPreKeyId', '3': 6, '4': 1, '5': 13, '10': 'signedPreKeyId'}, + {'1': 'baseKey', '3': 2, '4': 1, '5': 12, '10': 'baseKey'}, + {'1': 'identityKey', '3': 3, '4': 1, '5': 12, '10': 'identityKey'}, + {'1': 'message', '3': 4, '4': 1, '5': 12, '10': 'message'}, + ], +}; + +/// Descriptor for `PreKeySignalMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List preKeySignalMessageDescriptor = $convert.base64Decode( + 'ChNQcmVLZXlTaWduYWxNZXNzYWdlEiYKDnJlZ2lzdHJhdGlvbklkGAUgASgNUg5yZWdpc3RyYXRpb25JZBIaCghwcmVLZXlJZBgBIAEoDVIIcHJlS2V5SWQSJgoOc2lnbmVkUHJlS2V5SWQYBiABKA1SDnNpZ25lZFByZUtleUlkEhgKB2Jhc2VLZXkYAiABKAxSB2Jhc2VLZXkSIAoLaWRlbnRpdHlLZXkYAyABKAxSC2lkZW50aXR5S2V5EhgKB21lc3NhZ2UYBCABKAxSB21lc3NhZ2U='); +@$core.Deprecated('Use keyExchangeMessageDescriptor instead') +const keyExchangeMessage$json = { + '1': 'KeyExchangeMessage', + '2': [ + {'1': 'id', '3': 1, '4': 1, '5': 13, '10': 'id'}, + {'1': 'baseKey', '3': 2, '4': 1, '5': 12, '10': 'baseKey'}, + {'1': 'ratchetKey', '3': 3, '4': 1, '5': 12, '10': 'ratchetKey'}, + {'1': 'identityKey', '3': 4, '4': 1, '5': 12, '10': 'identityKey'}, + { + '1': 'baseKeySignature', + '3': 5, + '4': 1, + '5': 12, + '10': 'baseKeySignature' + }, + ], +}; + +/// Descriptor for `KeyExchangeMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List keyExchangeMessageDescriptor = $convert.base64Decode( + 'ChJLZXlFeGNoYW5nZU1lc3NhZ2USDgoCaWQYASABKA1SAmlkEhgKB2Jhc2VLZXkYAiABKAxSB2Jhc2VLZXkSHgoKcmF0Y2hldEtleRgDIAEoDFIKcmF0Y2hldEtleRIgCgtpZGVudGl0eUtleRgEIAEoDFILaWRlbnRpdHlLZXkSKgoQYmFzZUtleVNpZ25hdHVyZRgFIAEoDFIQYmFzZUtleVNpZ25hdHVyZQ=='); +@$core.Deprecated('Use senderKeyMessageDescriptor instead') +const senderKeyMessage$json = { + '1': 'SenderKeyMessage', + '2': [ + {'1': 'id', '3': 1, '4': 1, '5': 13, '10': 'id'}, + {'1': 'iteration', '3': 2, '4': 1, '5': 13, '10': 'iteration'}, + {'1': 'ciphertext', '3': 3, '4': 1, '5': 12, '10': 'ciphertext'}, + ], +}; + +/// Descriptor for `SenderKeyMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List senderKeyMessageDescriptor = $convert.base64Decode( + 'ChBTZW5kZXJLZXlNZXNzYWdlEg4KAmlkGAEgASgNUgJpZBIcCglpdGVyYXRpb24YAiABKA1SCWl0ZXJhdGlvbhIeCgpjaXBoZXJ0ZXh0GAMgASgMUgpjaXBoZXJ0ZXh0'); +@$core.Deprecated('Use senderKeyDistributionMessageDescriptor instead') +const senderKeyDistributionMessage$json = { + '1': 'SenderKeyDistributionMessage', + '2': [ + {'1': 'id', '3': 1, '4': 1, '5': 13, '10': 'id'}, + {'1': 'iteration', '3': 2, '4': 1, '5': 13, '10': 'iteration'}, + {'1': 'chainKey', '3': 3, '4': 1, '5': 12, '10': 'chainKey'}, + {'1': 'signingKey', '3': 4, '4': 1, '5': 12, '10': 'signingKey'}, + ], +}; + +/// Descriptor for `SenderKeyDistributionMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List senderKeyDistributionMessageDescriptor = + $convert.base64Decode( + 'ChxTZW5kZXJLZXlEaXN0cmlidXRpb25NZXNzYWdlEg4KAmlkGAEgASgNUgJpZBIcCglpdGVyYXRpb24YAiABKA1SCWl0ZXJhdGlvbhIaCghjaGFpbktleRgDIAEoDFIIY2hhaW5LZXkSHgoKc2lnbmluZ0tleRgEIAEoDFIKc2lnbmluZ0tleQ=='); +@$core.Deprecated('Use deviceConsistencyCodeMessageDescriptor instead') +const deviceConsistencyCodeMessage$json = { + '1': 'DeviceConsistencyCodeMessage', + '2': [ + {'1': 'generation', '3': 1, '4': 1, '5': 13, '10': 'generation'}, + {'1': 'signature', '3': 2, '4': 1, '5': 12, '10': 'signature'}, + ], +}; + +/// Descriptor for `DeviceConsistencyCodeMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List deviceConsistencyCodeMessageDescriptor = + $convert.base64Decode( + 'ChxEZXZpY2VDb25zaXN0ZW5jeUNvZGVNZXNzYWdlEh4KCmdlbmVyYXRpb24YASABKA1SCmdlbmVyYXRpb24SHAoJc2lnbmF0dXJlGAIgASgMUglzaWduYXR1cmU='); diff --git a/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbserver.dart b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbserver.dart new file mode 100644 index 0000000..1705a8b --- /dev/null +++ b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pbserver.dart @@ -0,0 +1,7 @@ +// Generated code. Do not modify. +// source: WhisperTextProtocol.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'whisper_text_protocol.pb.dart'; diff --git a/libsignal_protocol_dart/lib/src/untrusted_identity_exception.dart b/libsignal_protocol_dart/lib/src/untrusted_identity_exception.dart new file mode 100644 index 0000000..702a6b1 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/untrusted_identity_exception.dart @@ -0,0 +1,8 @@ +import 'identity_key.dart'; + +class UntrustedIdentityException implements Exception { + UntrustedIdentityException(this.name, this.key); + + final String name; + final IdentityKey? key; +} diff --git a/libsignal_protocol_dart/lib/src/util/byte_util.dart b/libsignal_protocol_dart/lib/src/util/byte_util.dart new file mode 100644 index 0000000..8de40ac --- /dev/null +++ b/libsignal_protocol_dart/lib/src/util/byte_util.dart @@ -0,0 +1,87 @@ +import 'dart:typed_data'; + +import 'package:adaptive_number/adaptive_number.dart'; +import 'package:convert/convert.dart'; + +class ByteUtil { + static Uint8List combine(List elements) { + final results = []; + elements.forEach(results.addAll); + return Uint8List.fromList(results); + } + + static Uint8List shortToByteArray(int value) { + final bytes = Uint8List(2); + bytes[0] = value >> 8; + bytes[1] = value; + return bytes; + } + + static Uint8List intToByteArray(int value) { + final bytes = Uint8List(4); + bytes[0] = value >> 24; + bytes[1] = value >> 16; + bytes[2] = value >> 8; + bytes[3] = value; + return bytes; + } + + static Uint8List trim(Uint8List input, int length) => + input.sublist(0, length); + + static List splitTwo( + Uint8List input, int firstLength, int secondLength) { + final first = input.sublist(0, firstLength); + final second = input.sublist(firstLength, firstLength + secondLength); + return [first, second]; + } + + static List split( + Uint8List input, int firstLength, int secondLength, int thirdLength) { + if (firstLength < 0 || + secondLength < 0 || + thirdLength < 0 || + input.length < firstLength + secondLength + thirdLength) { + throw Exception('Input too small: ${hex.encode(input)}'); + } + final first = input.sublist(0, firstLength); + final second = input.sublist(firstLength, firstLength + secondLength); + final third = input.sublist( + firstLength + secondLength, firstLength + secondLength + thirdLength); + return [first, second, third]; + } + + static int intsToByteHighAndLow(int highValue, int lowValue) => + ((highValue << 4) | lowValue) & 0xFF; + + static int highBitsToInt(int value) => (value & 0xFF) >> 4; + + static int lowBitsToInt(int value) => value & 0xF; + + static int highBitsToMedium(int value) => value >> 12; + + static int lowBitsToMedium(int value) => value & 0xFFF; + + static int byteArray5ToLong(Uint8List bytes, int offset) { + final v1 = (Number(bytes[offset]) & Number(0xff)) << 32; + final v2 = (Number(bytes[offset + 1]) & Number(0xff)) << 24; + final v3 = (Number(bytes[offset + 2]) & Number(0xff)) << 16; + final v4 = (Number(bytes[offset + 3]) & Number(0xff)) << 8; + final v5 = Number(bytes[offset + 4]) & Number(0xff); + return (v1 | v2 | v3 | v4 | v5).intValue; + } + + static int compare(Uint8List left, Uint8List right) { + // ignore: parameter_assignments, avoid_multiple_declarations_per_line + for (var i = 0, j = 0; i < left.length && j < right.length; i++, j++) { + final a = left[i] & 0xff; + final b = right[j] & 0xff; + + if (a != b) { + return a - b; + } + } + + return left.length - right.length; + } +} diff --git a/libsignal_protocol_dart/lib/src/util/identity_key_comparator.dart b/libsignal_protocol_dart/lib/src/util/identity_key_comparator.dart new file mode 100644 index 0000000..dccd3af --- /dev/null +++ b/libsignal_protocol_dart/lib/src/util/identity_key_comparator.dart @@ -0,0 +1,5 @@ +import '../identity_key.dart'; +import 'byte_util.dart'; + +int identityKeyComparator(IdentityKey a, IdentityKey b) => + ByteUtil.compare(a.publicKey.serialize(), b.publicKey.serialize()); diff --git a/libsignal_protocol_dart/lib/src/util/key_helper.dart b/libsignal_protocol_dart/lib/src/util/key_helper.dart new file mode 100644 index 0000000..6ea8555 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/util/key_helper.dart @@ -0,0 +1,69 @@ +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:fixnum/fixnum.dart'; + +import '../ecc/curve.dart'; +import '../ecc/ec_key_pair.dart'; +import '../identity_key.dart'; +import '../identity_key_pair.dart'; +import '../state/pre_key_record.dart'; +import '../state/signed_pre_key_record.dart'; +import 'medium.dart'; + +IdentityKeyPair generateIdentityKeyPair() { + final keyPair = Curve.generateKeyPair(); + final publicKey = IdentityKey(keyPair.publicKey); + return IdentityKeyPair(publicKey, keyPair.privateKey); +} + +IdentityKeyPair generateIdentityKeyPairFromPrivate(List private) { + final keyPair = Curve.generateKeyPairFromPrivate(private); + final publicKey = IdentityKey(keyPair.publicKey); + return IdentityKeyPair(publicKey, keyPair.privateKey); +} + +int integerMax = 0x7fffffff; + +// ignore: avoid_positional_boolean_parameters +int generateRegistrationId(bool extendedRange) { + if (extendedRange) { + return _random.nextInt(integerMax - 1) + 1; + } else { + return _random.nextInt(16380) + 1; + } +} + +List generatePreKeys(int start, int count) { + final results = []; + // ignore: parameter_assignments + start--; + for (var i = 0; i < count; i++) { + results.add(PreKeyRecord( + ((start + i).remainder(maxValue - 1)) + 1, Curve.generateKeyPair())); + } + return results; +} + +SignedPreKeyRecord generateSignedPreKey( + IdentityKeyPair identityKeyPair, int signedPreKeyId) { + final keyPair = Curve.generateKeyPair(); + final signature = Curve.calculateSignature( + identityKeyPair.getPrivateKey(), keyPair.publicKey.serialize()); + + return SignedPreKeyRecord(signedPreKeyId, + Int64(DateTime.now().millisecondsSinceEpoch), keyPair, signature); +} + +ECKeyPair generateSenderSigningKey() => Curve.generateKeyPair(); + +Uint8List generateSenderKey() => generateRandomBytes(); + +int generateSenderKeyId() => _random.nextInt(integerMax); + +final Random _random = Random.secure(); + +Uint8List generateRandomBytes([int length = 32]) { + final values = List.generate(length, (i) => _random.nextInt(256)); + return Uint8List.fromList(values); +} diff --git a/libsignal_protocol_dart/lib/src/util/log.dart b/libsignal_protocol_dart/lib/src/util/log.dart new file mode 100644 index 0000000..1fb28a8 --- /dev/null +++ b/libsignal_protocol_dart/lib/src/util/log.dart @@ -0,0 +1,8 @@ +bool enabled = false; + +void log(Object? object) { + if (enabled) { + // ignore: avoid_print + print(object); + } +} diff --git a/libsignal_protocol_dart/lib/src/util/medium.dart b/libsignal_protocol_dart/lib/src/util/medium.dart new file mode 100644 index 0000000..95ce4df --- /dev/null +++ b/libsignal_protocol_dart/lib/src/util/medium.dart @@ -0,0 +1 @@ +const int maxValue = 0xFFFFFF; diff --git a/libsignal_protocol_dart/pubspec.yaml b/libsignal_protocol_dart/pubspec.yaml new file mode 100644 index 0000000..e039de7 --- /dev/null +++ b/libsignal_protocol_dart/pubspec.yaml @@ -0,0 +1,28 @@ +name: libsignal_protocol_dart +description: Signal Protocol libray for Dart native and Flutter, pure Dart implementation of the the Signal Protocol +version: 0.7.4 +repository: https://github.com/MixinNetwork/libsignal_protocol_dart +topics: + - crypto + +environment: + sdk: '>=3.4.0 <4.0.0' + + +dependencies: + adaptive_number: ^1.0.0 + collection: ^1.19.0 + convert: ^3.1.2 + crypto: ^3.0.6 + ed25519_edwards: ^0.3.1 + fixnum: ^1.1.1 + meta: ^1.16.0 + optional: ^6.1.0+1 + pointycastle: ^4.0.0 + protobuf: ^4.0.0 + x25519: ^0.1.1 + + +dev_dependencies: + test: ^1.25.8 + very_good_analysis: ^8.0.0 diff --git a/libsignal_protocol_dart/test/devices/device_consistency_test.dart b/libsignal_protocol_dart/test/devices/device_consistency_test.dart new file mode 100644 index 0000000..82622d9 --- /dev/null +++ b/libsignal_protocol_dart/test/devices/device_consistency_test.dart @@ -0,0 +1,86 @@ +import 'package:libsignal_protocol_dart/src/devices/device_consistency_code_generator.dart'; +import 'package:libsignal_protocol_dart/src/devices/device_consistency_commitment.dart'; +import 'package:libsignal_protocol_dart/src/devices/device_consistency_signature.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:libsignal_protocol_dart/src/protocol/device_consistency_message.dart'; +import 'package:libsignal_protocol_dart/src/util/key_helper.dart'; +import 'package:test/test.dart'; + +void main() { + String generateCode(DeviceConsistencyCommitment commitment, + List messages) { + final signatures = []; + for (final message in messages) { + signatures.add(message.signature); + } + return DeviceConsistencyCodeGenerator.generateFor(commitment, signatures); + } + + test('testDeviceConsistency', () { + final deviceOne = generateIdentityKeyPair(); + final deviceTwo = generateIdentityKeyPair(); + final deviceThree = generateIdentityKeyPair(); + + final keyList = [ + deviceOne.getPublicKey(), + deviceTwo.getPublicKey(), + deviceThree.getPublicKey() + ]..shuffle(); + final deviceOneCommitment = DeviceConsistencyCommitment(1, keyList); + + keyList.shuffle(); + final deviceTwoCommitment = DeviceConsistencyCommitment(1, keyList); + + keyList.shuffle(); + final deviceThreeCommitment = DeviceConsistencyCommitment(1, keyList); + + expect(deviceOneCommitment.serialized, deviceTwoCommitment.serialized); + expect(deviceTwoCommitment.serialized, deviceThreeCommitment.serialized); + + final deviceOneMessage = + DeviceConsistencyMessage(deviceOneCommitment, deviceOne); + final deviceTwoMessage = + DeviceConsistencyMessage(deviceOneCommitment, deviceTwo); + final deviceThreeMessage = + DeviceConsistencyMessage(deviceOneCommitment, deviceThree); + + final receivedDeviceOneMessage = DeviceConsistencyMessage.fromSerialized( + deviceOneCommitment, + deviceOneMessage.serialized, + deviceOne.getPublicKey()); + final receivedDeviceTwoMessage = DeviceConsistencyMessage.fromSerialized( + deviceOneCommitment, + deviceTwoMessage.serialized, + deviceTwo.getPublicKey()); + final receivedDeviceThreeMessage = DeviceConsistencyMessage.fromSerialized( + deviceOneCommitment, + deviceThreeMessage.serialized, + deviceThree.getPublicKey()); + + expect(deviceOneMessage.signature.vrfOutput, + receivedDeviceOneMessage.signature.vrfOutput); + expect(deviceTwoMessage.signature.vrfOutput, + receivedDeviceTwoMessage.signature.vrfOutput); + expect(deviceThreeMessage.signature.vrfOutput, + receivedDeviceThreeMessage.signature.vrfOutput); + + final codeOne = generateCode(deviceOneCommitment, [ + deviceOneMessage, + receivedDeviceTwoMessage, + receivedDeviceThreeMessage + ]); + final codeTwo = generateCode(deviceTwoCommitment, [ + deviceTwoMessage, + receivedDeviceThreeMessage, + receivedDeviceOneMessage + ]); + final codeThree = generateCode(deviceThreeCommitment, [ + deviceThreeMessage, + receivedDeviceTwoMessage, + receivedDeviceOneMessage + ]); + + expect(codeOne, codeTwo); + expect(codeTwo, codeThree); + }); +} diff --git a/libsignal_protocol_dart/test/ecc/curve25519_test.dart b/libsignal_protocol_dart/test/ecc/curve25519_test.dart new file mode 100644 index 0000000..30685d9 --- /dev/null +++ b/libsignal_protocol_dart/test/ecc/curve25519_test.dart @@ -0,0 +1,459 @@ +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/invalid_key_exception.dart'; +import 'package:test/test.dart'; + +void main() { + test('testAgreement', () { + final alicePublic = Uint8List.fromList([ + 0x05, + 0x1b, + 0xb7, + 0x59, + 0x66, + 0xf2, + 0xe9, + 0x3a, + 0x36, + 0x91, + 0xdf, + 0xff, + 0x94, + 0x2b, + 0xb2, + 0xa4, + 0x66, + 0xa1, + 0xc0, + 0x8b, + 0x8d, + 0x78, + 0xca, + 0x3f, + 0x4d, + 0x6d, + 0xf8, + 0xb8, + 0xbf, + 0xa2, + 0xe4, + 0xee, + 0x28 + ]); + + final alicePrivate = Uint8List.fromList([ + 0xc8, + 0x06, + 0x43, + 0x9d, + 0xc9, + 0xd2, + 0xc4, + 0x76, + 0xff, + 0xed, + 0x8f, + 0x25, + 0x80, + 0xc0, + 0x88, + 0x8d, + 0x58, + 0xab, + 0x40, + 0x6b, + 0xf7, + 0xae, + 0x36, + 0x98, + 0x87, + 0x90, + 0x21, + 0xb9, + 0x6b, + 0xb4, + 0xbf, + 0x59 + ]); + + final bobPublic = Uint8List.fromList([ + 0x05, + 0x65, + 0x36, + 0x14, + 0x99, + 0x3d, + 0x2b, + 0x15, + 0xee, + 0x9e, + 0x5f, + 0xd3, + 0xd8, + 0x6c, + 0xe7, + 0x19, + 0xef, + 0x4e, + 0xc1, + 0xda, + 0xae, + 0x18, + 0x86, + 0xa8, + 0x7b, + 0x3f, + 0x5f, + 0xa9, + 0x56, + 0x5a, + 0x27, + 0xa2, + 0x2f + ]); + + final bobPrivate = Uint8List.fromList([ + 0xb0, + 0x3b, + 0x34, + 0xc3, + 0x3a, + 0x1c, + 0x44, + 0xf2, + 0x25, + 0xb6, + 0x62, + 0xd2, + 0xbf, + 0x48, + 0x59, + 0xb8, + 0x13, + 0x54, + 0x11, + 0xfa, + 0x7b, + 0x03, + 0x86, + 0xd4, + 0x5f, + 0xb7, + 0x5d, + 0xc5, + 0xb9, + 0x1b, + 0x44, + 0x66 + ]); + + final shared = Uint8List.fromList([ + 0x32, + 0x5f, + 0x23, + 0x93, + 0x28, + 0x94, + 0x1c, + 0xed, + 0x6e, + 0x67, + 0x3b, + 0x86, + 0xba, + 0x41, + 0x01, + 0x74, + 0x48, + 0xe9, + 0x9b, + 0x64, + 0x9a, + 0x9c, + 0x38, + 0x06, + 0xc1, + 0xdd, + 0x7c, + 0xa4, + 0xc4, + 0x77, + 0xe6, + 0x29 + ]); + + final alicePublicKey = Curve.decodePoint(alicePublic, 0); + final alicePrivateKey = Curve.decodePrivatePoint(alicePrivate); + + final bobPublicKey = Curve.decodePoint(bobPublic, 0); + final bobPrivateKey = Curve.decodePrivatePoint(bobPrivate); + + final sharedOne = Curve.calculateAgreement(alicePublicKey, bobPrivateKey); + final sharedTwo = Curve.calculateAgreement(bobPublicKey, alicePrivateKey); + + expect(sharedOne, shared); + expect(sharedTwo, shared); + }); + + test('testRandomAgreements', () { + for (var i = 0; i < 50; i++) { + final alice = Curve.generateKeyPair(); + final bob = Curve.generateKeyPair(); + + final sharedAlice = + Curve.calculateAgreement(bob.publicKey, alice.privateKey); + final sharedBob = + Curve.calculateAgreement(alice.publicKey, bob.privateKey); + + expect(sharedAlice, sharedBob); + } + }); + + test('testSignature', () { + final aliceIdentityPrivate = Uint8List.fromList([ + 0xc0, + 0x97, + 0x24, + 0x84, + 0x12, + 0xe5, + 0x8b, + 0xf0, + 0x5d, + 0xf4, + 0x87, + 0x96, + 0x82, + 0x05, + 0x13, + 0x27, + 0x94, + 0x17, + 0x8e, + 0x36, + 0x76, + 0x37, + 0xf5, + 0x81, + 0x8f, + 0x81, + 0xe0, + 0xe6, + 0xce, + 0x73, + 0xe8, + 0x65 + ]); + + final aliceIdentityPublic = Uint8List.fromList([ + 0x05, + 0xab, + 0x7e, + 0x71, + 0x7d, + 0x4a, + 0x16, + 0x3b, + 0x7d, + 0x9a, + 0x1d, + 0x80, + 0x71, + 0xdf, + 0xe9, + 0xdc, + 0xf8, + 0xcd, + 0xcd, + 0x1c, + 0xea, + 0x33, + 0x39, + 0xb6, + 0x35, + 0x6b, + 0xe8, + 0x4d, + 0x88, + 0x7e, + 0x32, + 0x2c, + 0x64 + ]); + + final aliceEphemeralPublic = Uint8List.fromList([ + 0x05, + 0xed, + 0xce, + 0x9d, + 0x9c, + 0x41, + 0x5c, + 0xa7, + 0x8c, + 0xb7, + 0x25, + 0x2e, + 0x72, + 0xc2, + 0xc4, + 0xa5, + 0x54, + 0xd3, + 0xeb, + 0x29, + 0x48, + 0x5a, + 0x0e, + 0x1d, + 0x50, + 0x31, + 0x18, + 0xd1, + 0xa8, + 0x2d, + 0x99, + 0xfb, + 0x4a + ]); + + final aliceSignature = Uint8List.fromList([ + 0x5d, + 0xe8, + 0x8c, + 0xa9, + 0xa8, + 0x9b, + 0x4a, + 0x11, + 0x5d, + 0xa7, + 0x91, + 0x09, + 0xc6, + 0x7c, + 0x9c, + 0x74, + 0x64, + 0xa3, + 0xe4, + 0x18, + 0x02, + 0x74, + 0xf1, + 0xcb, + 0x8c, + 0x63, + 0xc2, + 0x98, + 0x4e, + 0x28, + 0x6d, + 0xfb, + 0xed, + 0xe8, + 0x2d, + 0xeb, + 0x9d, + 0xcd, + 0x9f, + 0xae, + 0x0b, + 0xfb, + 0xb8, + 0x21, + 0x56, + 0x9b, + 0x3d, + 0x90, + 0x01, + 0xbd, + 0x81, + 0x30, + 0xcd, + 0x11, + 0xd4, + 0x86, + 0xce, + 0xf0, + 0x47, + 0xbd, + 0x60, + 0xb8, + 0x6e, + 0x88 + ]); + + // ignore: unused_local_variable + final alicePrivateKey = Curve.decodePrivatePoint(aliceIdentityPrivate); + final alicePublicKey = Curve.decodePoint(aliceIdentityPublic, 0); + final aliceEphemeral = Curve.decodePoint(aliceEphemeralPublic, 0); + + if (!Curve.verifySignature( + alicePublicKey, aliceEphemeral.serialize(), aliceSignature)) { + throw AssertionError('Sig verification failed!'); + } + + for (var i = 0; i < aliceSignature.length; i++) { + final modifiedSignature = Uint8List(aliceSignature.length); + Curve.arraycopy( + aliceSignature, 0, modifiedSignature, 0, modifiedSignature.length); + + modifiedSignature[i] ^= 0x01; + + if (Curve.verifySignature( + alicePublicKey, aliceEphemeral.serialize(), modifiedSignature)) { + throw AssertionError('Sig verification succeeded!'); + } + } + }); + + test('testDecodeSize', () { + final keyPair = Curve.generateKeyPair(); + final serializedPublic = keyPair.publicKey.serialize(); + + final justRight = Curve.decodePoint(serializedPublic, 0); + + try { + // ignore: unused_local_variable + final tooSmall = Curve.decodePoint(serializedPublic, 1); + throw AssertionError("Shouldn't decode"); + } on InvalidKeyException { + // good + } + + try { + // ignore: unused_local_variable + final empty = Curve.decodePoint(Uint8List(0), 0); + throw AssertionError("Shouldn't parse"); + } on InvalidKeyException { + // good + } + + try { + final badKeyType = Uint8List(33); + Curve.arraycopy( + serializedPublic, 0, badKeyType, 0, serializedPublic.length); + badKeyType[0] = 0x01; + Curve.decodePoint(badKeyType, 0); + throw AssertionError('Should be bad key type'); + } on InvalidKeyException { + // good + } + + final extraSpace = Uint8List(serializedPublic.length + 1); + Curve.arraycopy( + serializedPublic, 0, extraSpace, 0, serializedPublic.length); + final extra = Curve.decodePoint(extraSpace, 0); + + final offsetSpace = Uint8List(serializedPublic.length + 1); + Curve.arraycopy( + serializedPublic, 0, offsetSpace, 1, serializedPublic.length); + final offset = Curve.decodePoint(offsetSpace, 1); + + expect(serializedPublic, justRight.serialize()); + expect(extra.serialize(), serializedPublic); + expect(offset.serialize(), serializedPublic); + }); +} diff --git a/libsignal_protocol_dart/test/fingerprint/numeric_fingerprint_generator_test.dart b/libsignal_protocol_dart/test/fingerprint/numeric_fingerprint_generator_test.dart new file mode 100644 index 0000000..5af9059 --- /dev/null +++ b/libsignal_protocol_dart/test/fingerprint/numeric_fingerprint_generator_test.dart @@ -0,0 +1,553 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/fingerprint/numeric_fingerprint_generator.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:test/test.dart'; + +Uint8List aliceIdentity = Uint8List.fromList([ + 0x05, + 0x06, + 0x86, + 0x3b, + 0xc6, + 0x6d, + 0x02, + 0xb4, + 0x0d, + 0x27, + 0xb8, + 0xd4, + 0x9c, + 0xa7, + 0xc0, + 0x9e, + 0x92, + 0x39, + 0x23, + 0x6f, + 0x9d, + 0x7d, + 0x25, + 0xd6, + 0xfc, + 0xca, + 0x5c, + 0xe1, + 0x3c, + 0x70, + 0x64, + 0xd8, + 0x68 +]); +Uint8List bobIdentity = Uint8List.fromList([ + 0x05, + 0xf7, + 0x81, + 0xb6, + 0xfb, + 0x32, + 0xfe, + 0xd9, + 0xba, + 0x1c, + 0xf2, + 0xde, + 0x97, + 0x8d, + 0x4d, + 0x5d, + 0xa2, + 0x8d, + 0xc3, + 0x40, + 0x46, + 0xae, + 0x81, + 0x44, + 0x02, + 0xb5, + 0xc0, + 0xdb, + 0xd9, + 0x6f, + 0xda, + 0x90, + 0x7b +]); + +int version1 = 1; +String displayableFingerprintV1 = + '300354477692869396892869876765458257569162576843440918079131'; +Uint8List aliceScannableFingerprintV1 = Uint8List.fromList([ + 0x08, + 0x01, + 0x12, + 0x22, + 0x0a, + 0x20, + 0x1e, + 0x30, + 0x1a, + 0x03, + 0x53, + 0xdc, + 0xe3, + 0xdb, + 0xe7, + 0x68, + 0x4c, + 0xb8, + 0x33, + 0x6e, + 0x85, + 0x13, + 0x6c, + 0xdc, + 0x0e, + 0xe9, + 0x62, + 0x19, + 0x49, + 0x4a, + 0xda, + 0x30, + 0x5d, + 0x62, + 0xa7, + 0xbd, + 0x61, + 0xdf, + 0x1a, + 0x22, + 0x0a, + 0x20, + 0xd6, + 0x2c, + 0xbf, + 0x73, + 0xa1, + 0x15, + 0x92, + 0x01, + 0x5b, + 0x6b, + 0x9f, + 0x16, + 0x82, + 0xac, + 0x30, + 0x6f, + 0xea, + 0x3a, + 0xaf, + 0x38, + 0x85, + 0xb8, + 0x4d, + 0x12, + 0xbc, + 0xa6, + 0x31, + 0xe9, + 0xd4, + 0xfb, + 0x3a, + 0x4d +]); +Uint8List bobScannableFingerprintV1 = Uint8List.fromList([ + 0x08, + 0x01, + 0x12, + 0x22, + 0x0a, + 0x20, + 0xd6, + 0x2c, + 0xbf, + 0x73, + 0xa1, + 0x15, + 0x92, + 0x01, + 0x5b, + 0x6b, + 0x9f, + 0x16, + 0x82, + 0xac, + 0x30, + 0x6f, + 0xea, + 0x3a, + 0xaf, + 0x38, + 0x85, + 0xb8, + 0x4d, + 0x12, + 0xbc, + 0xa6, + 0x31, + 0xe9, + 0xd4, + 0xfb, + 0x3a, + 0x4d, + 0x1a, + 0x22, + 0x0a, + 0x20, + 0x1e, + 0x30, + 0x1a, + 0x03, + 0x53, + 0xdc, + 0xe3, + 0xdb, + 0xe7, + 0x68, + 0x4c, + 0xb8, + 0x33, + 0x6e, + 0x85, + 0x13, + 0x6c, + 0xdc, + 0x0e, + 0xe9, + 0x62, + 0x19, + 0x49, + 0x4a, + 0xda, + 0x30, + 0x5d, + 0x62, + 0xa7, + 0xbd, + 0x61, + 0xdf +]); + +int version2 = 2; +String displayableFingerprintV2 = displayableFingerprintV1; +Uint8List aliceScannableFingerprintV2 = Uint8List.fromList([ + 0x08, + 0x02, + 0x12, + 0x22, + 0x0a, + 0x20, + 0x1e, + 0x30, + 0x1a, + 0x03, + 0x53, + 0xdc, + 0xe3, + 0xdb, + 0xe7, + 0x68, + 0x4c, + 0xb8, + 0x33, + 0x6e, + 0x85, + 0x13, + 0x6c, + 0xdc, + 0x0e, + 0xe9, + 0x62, + 0x19, + 0x49, + 0x4a, + 0xda, + 0x30, + 0x5d, + 0x62, + 0xa7, + 0xbd, + 0x61, + 0xdf, + 0x1a, + 0x22, + 0x0a, + 0x20, + 0xd6, + 0x2c, + 0xbf, + 0x73, + 0xa1, + 0x15, + 0x92, + 0x01, + 0x5b, + 0x6b, + 0x9f, + 0x16, + 0x82, + 0xac, + 0x30, + 0x6f, + 0xea, + 0x3a, + 0xaf, + 0x38, + 0x85, + 0xb8, + 0x4d, + 0x12, + 0xbc, + 0xa6, + 0x31, + 0xe9, + 0xd4, + 0xfb, + 0x3a, + 0x4d +]); +Uint8List bobScannableFingerprintV2 = Uint8List.fromList([ + 0x08, + 0x02, + 0x12, + 0x22, + 0x0a, + 0x20, + 0xd6, + 0x2c, + 0xbf, + 0x73, + 0xa1, + 0x15, + 0x92, + 0x01, + 0x5b, + 0x6b, + 0x9f, + 0x16, + 0x82, + 0xac, + 0x30, + 0x6f, + 0xea, + 0x3a, + 0xaf, + 0x38, + 0x85, + 0xb8, + 0x4d, + 0x12, + 0xbc, + 0xa6, + 0x31, + 0xe9, + 0xd4, + 0xfb, + 0x3a, + 0x4d, + 0x1a, + 0x22, + 0x0a, + 0x20, + 0x1e, + 0x30, + 0x1a, + 0x03, + 0x53, + 0xdc, + 0xe3, + 0xdb, + 0xe7, + 0x68, + 0x4c, + 0xb8, + 0x33, + 0x6e, + 0x85, + 0x13, + 0x6c, + 0xdc, + 0x0e, + 0xe9, + 0x62, + 0x19, + 0x49, + 0x4a, + 0xda, + 0x30, + 0x5d, + 0x62, + 0xa7, + 0xbd, + 0x61, + 0xdf +]); + +void main() { + test('testVectorsVersion1', () { + final aliceIdentityKey = IdentityKey.fromBytes(aliceIdentity, 0); + final bobIdentityKey = IdentityKey.fromBytes(bobIdentity, 0); + final aliceStableId = Uint8List.fromList(utf8.encode('+14152222222')); + final bobStableId = Uint8List.fromList(utf8.encode('+14153333333')); + + final generator = NumericFingerprintGenerator(5200); + + final aliceFingerprint = generator.createFor( + version1, aliceStableId, aliceIdentityKey, bobStableId, bobIdentityKey); + + final bobFingerprint = generator.createFor( + version1, bobStableId, bobIdentityKey, aliceStableId, aliceIdentityKey); + + expect(aliceFingerprint.displayableFingerprint.getDisplayText(), + displayableFingerprintV1); + expect(bobFingerprint.displayableFingerprint.getDisplayText(), + displayableFingerprintV1); + + expect(aliceFingerprint.scannableFingerprint.fingerprints, + aliceScannableFingerprintV1); + expect(bobFingerprint.scannableFingerprint.fingerprints, + bobScannableFingerprintV1); + }); + + test('testMatchingFingerprints', () { + final aliceKeyPair = Curve.generateKeyPair(); + final bobKeyPair = Curve.generateKeyPair(); + + final aliceIdentityKey = IdentityKey(aliceKeyPair.publicKey); + final bobIdentityKey = IdentityKey(bobKeyPair.publicKey); + + final generator = NumericFingerprintGenerator(1024); + final aliceFingerprint = generator.createFor( + version1, + Uint8List.fromList(utf8.encode('+14152222222')), + aliceIdentityKey, + Uint8List.fromList(utf8.encode('+14153333333')), + bobIdentityKey); + + final bobFingerprint = generator.createFor( + version1, + Uint8List.fromList(utf8.encode('+14153333333')), + bobIdentityKey, + Uint8List.fromList(utf8.encode('+14152222222')), + aliceIdentityKey); + + expect(aliceFingerprint.displayableFingerprint.getDisplayText(), + bobFingerprint.displayableFingerprint.getDisplayText()); + + expect( + aliceFingerprint.scannableFingerprint + .compareTo(bobFingerprint.scannableFingerprint.fingerprints), + true); + expect( + bobFingerprint.scannableFingerprint + .compareTo(aliceFingerprint.scannableFingerprint.fingerprints), + true); + + expect(aliceFingerprint.displayableFingerprint.getDisplayText().length, 60); + }); + + test('testMismatchingFingerprints', () { + final aliceKeyPair = Curve.generateKeyPair(); + final bobKeyPair = Curve.generateKeyPair(); + final mitmKeyPair = Curve.generateKeyPair(); + + final aliceIdentityKey = IdentityKey(aliceKeyPair.publicKey); + final bobIdentityKey = IdentityKey(bobKeyPair.publicKey); + final mitmIdentityKey = IdentityKey(mitmKeyPair.publicKey); + + final generator = NumericFingerprintGenerator(1024); + final aliceFingerprint = generator.createFor( + version1, + Uint8List.fromList(utf8.encode('+14152222222')), + aliceIdentityKey, + Uint8List.fromList(utf8.encode('+14153333333')), + mitmIdentityKey); + + final bobFingerprint = generator.createFor( + version1, + Uint8List.fromList(utf8.encode('+14153333333')), + bobIdentityKey, + Uint8List.fromList(utf8.encode('+14152222222')), + aliceIdentityKey); + + expect( + aliceFingerprint.displayableFingerprint.getDisplayText() == + bobFingerprint.displayableFingerprint.getDisplayText(), + false); + + expect( + aliceFingerprint.scannableFingerprint + .compareTo(bobFingerprint.scannableFingerprint.fingerprints), + false); + expect( + bobFingerprint.scannableFingerprint + .compareTo(aliceFingerprint.scannableFingerprint.fingerprints), + false); + }); + + test('testMismatchingIdentifiers', () { + final aliceKeyPair = Curve.generateKeyPair(); + final bobKeyPair = Curve.generateKeyPair(); + + final aliceIdentityKey = IdentityKey(aliceKeyPair.publicKey); + final bobIdentityKey = IdentityKey(bobKeyPair.publicKey); + + final generator = NumericFingerprintGenerator(1024); + final aliceFingerprint = generator.createFor( + version1, + Uint8List.fromList(utf8.encode('+141512222222')), + aliceIdentityKey, + Uint8List.fromList(utf8.encode('+14153333333')), + bobIdentityKey); + final bobFingerprint = generator.createFor( + version1, + Uint8List.fromList(utf8.encode('+14153333333')), + bobIdentityKey, + Uint8List.fromList(utf8.encode('+14152222222')), + aliceIdentityKey); + + expect( + aliceFingerprint.displayableFingerprint.getDisplayText() == + bobFingerprint.displayableFingerprint.getDisplayText(), + false); + + expect( + aliceFingerprint.scannableFingerprint + .compareTo(bobFingerprint.scannableFingerprint.fingerprints), + false); + expect( + bobFingerprint.scannableFingerprint + .compareTo(aliceFingerprint.scannableFingerprint.fingerprints), + false); + }); + + test('testDifferentVersionsMakeSameFingerPrintsButDifferentScannable', () { + final aliceIdentityKey = IdentityKey.fromBytes(aliceIdentity, 0); + final bobIdentityKey = IdentityKey.fromBytes(bobIdentity, 0); + final aliceStableId = Uint8List.fromList(utf8.encode('+14152222222')); + final bobStableId = Uint8List.fromList(utf8.encode('+14153333333')); + + final generator = NumericFingerprintGenerator(5200); + + final aliceFingerprintV1 = generator.createFor( + version1, aliceStableId, aliceIdentityKey, bobStableId, bobIdentityKey); + + final aliceFingerprintV2 = generator.createFor( + version2, aliceStableId, aliceIdentityKey, bobStableId, bobIdentityKey); + + expect( + aliceFingerprintV1.displayableFingerprint.getDisplayText() == + aliceFingerprintV2.displayableFingerprint.getDisplayText(), + true); + + expect( + aliceFingerprintV1.scannableFingerprint.fingerprints == + aliceFingerprintV2.scannableFingerprint.fingerprints, + false); + }); +} diff --git a/libsignal_protocol_dart/test/groups/group_cipher_test.dart b/libsignal_protocol_dart/test/groups/group_cipher_test.dart new file mode 100644 index 0000000..6dbc299 --- /dev/null +++ b/libsignal_protocol_dart/test/groups/group_cipher_test.dart @@ -0,0 +1,322 @@ +import 'dart:convert'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/duplicate_message_exception.dart'; +import 'package:libsignal_protocol_dart/src/eq.dart'; +import 'package:libsignal_protocol_dart/src/groups/group_cipher.dart'; +import 'package:libsignal_protocol_dart/src/groups/group_session_builder.dart'; +import 'package:libsignal_protocol_dart/src/groups/sender_key_name.dart'; +import 'package:libsignal_protocol_dart/src/groups/state/in_memory_sender_key_store.dart'; +import 'package:libsignal_protocol_dart/src/invalid_message_exception.dart'; +import 'package:libsignal_protocol_dart/src/no_session_exception.dart'; +import 'package:libsignal_protocol_dart/src/protocol/sender_key_distribution_message_wrapper.dart'; +import 'package:libsignal_protocol_dart/src/signal_protocol_address.dart'; +import 'package:libsignal_protocol_dart/src/util/key_helper.dart'; +import 'package:test/test.dart'; + +void main() { + const senderAddress = SignalProtocolAddress('+14150001111', 1); + const groupSender = + SenderKeyName('nihilist history reading group', senderAddress); + + const integerMax = 0x7fffffff; + + int randomInt() { + final secureRandom = Random.secure(); + return secureRandom.nextInt(integerMax); + } + + test('testNoSession', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + // ignore: unused_local_variable + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + final aliceGroupCipher = GroupCipher(aliceStore, groupSender); + final bobGroupCipher = GroupCipher(bobStore, groupSender); + + final sentAliceDistributionMessage = + await aliceSessionBuilder.create(groupSender); + // ignore: unused_local_variable + final receivedAliceDistributionMessage = + SenderKeyDistributionMessageWrapper.fromSerialized( + sentAliceDistributionMessage.serialize()); + +// bobSessionBuilder.process(groupSender, receivedAliceDistributionMessage); + + final ciphertextFromAlice = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('smert ze smert'))); + try { + // ignore: unused_local_variable + final plaintextFromAlice = + await bobGroupCipher.decrypt(ciphertextFromAlice); + throw AssertionError('Should be no session!'); + } on NoSessionException { + // good + } + }); + + test('testBasicEncryptDecrypt', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + final aliceGroupCipher = GroupCipher(aliceStore, groupSender); + final bobGroupCipher = GroupCipher(bobStore, groupSender); + + final sentAliceDistributionMessage = + await aliceSessionBuilder.create(groupSender); + final receivedAliceDistributionMessage = + SenderKeyDistributionMessageWrapper.fromSerialized( + sentAliceDistributionMessage.serialize()); + await bobSessionBuilder.process( + groupSender, receivedAliceDistributionMessage); + + final ciphertextFromAlice = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('smert ze smert'))); + final plaintextFromAlice = + await bobGroupCipher.decrypt(ciphertextFromAlice); + + assert(utf8.decode(plaintextFromAlice) == 'smert ze smert'); + }); + + test('testLargeMessages', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + final aliceGroupCipher = GroupCipher(aliceStore, groupSender); + final bobGroupCipher = GroupCipher(bobStore, groupSender); + + final sentAliceDistributionMessage = + await aliceSessionBuilder.create(groupSender); + final receivedAliceDistributionMessage = + SenderKeyDistributionMessageWrapper.fromSerialized( + sentAliceDistributionMessage.serialize()); + await bobSessionBuilder.process( + groupSender, receivedAliceDistributionMessage); + + final plaintext = generateRandomBytes(1024 * 1024); + + final ciphertextFromAlice = await aliceGroupCipher.encrypt(plaintext); + final plaintextFromAlice = + await bobGroupCipher.decrypt(ciphertextFromAlice); + + assert(eq(plaintextFromAlice, plaintext)); + }); + + test('testBasicRatchet', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + const aliceName = groupSender; + + final aliceGroupCipher = GroupCipher(aliceStore, aliceName); + final bobGroupCipher = GroupCipher(bobStore, aliceName); + + final sentAliceDistributionMessage = + await aliceSessionBuilder.create(aliceName); + final receivedAliceDistributionMessage = + SenderKeyDistributionMessageWrapper.fromSerialized( + sentAliceDistributionMessage.serialize()); + + await bobSessionBuilder.process( + aliceName, receivedAliceDistributionMessage); + + final ciphertextFromAlice = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('smert ze smert'))); + final ciphertextFromAlice2 = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('smert ze smert2'))); + final ciphertextFromAlice3 = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('smert ze smert3'))); + + final plaintextFromAlice = + await bobGroupCipher.decrypt(ciphertextFromAlice); + + try { + await bobGroupCipher.decrypt(ciphertextFromAlice); + throw AssertionError('Should have ratcheted forward!'); + } on DuplicateMessageException { + // good + } + + final plaintextFromAlice2 = + await bobGroupCipher.decrypt(ciphertextFromAlice2); + final plaintextFromAlice3 = + await bobGroupCipher.decrypt(ciphertextFromAlice3); + + assert(utf8.decode(plaintextFromAlice) == 'smert ze smert'); + assert(utf8.decode(plaintextFromAlice2) == 'smert ze smert2'); + assert(utf8.decode(plaintextFromAlice3) == 'smert ze smert3'); + }); + + test('testLateJoin', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + + const aliceName = groupSender; + + final aliceGroupCipher = GroupCipher(aliceStore, aliceName); + + // ignore: unused_local_variable + final aliceDistributionMessage = + await aliceSessionBuilder.create(aliceName); + // Send off to some people. + + for (var i = 0; i < 100; i++) { + await aliceGroupCipher.encrypt(Uint8List.fromList( + utf8.encode('up the punks up the punks up the punks'))); + } + + // Now Bob Joins. + final bobSessionBuilder = GroupSessionBuilder(bobStore); + final bobGroupCipher = GroupCipher(bobStore, aliceName); + + final distributionMessageToBob = + await aliceSessionBuilder.create(aliceName); + await bobSessionBuilder.process( + aliceName, + SenderKeyDistributionMessageWrapper.fromSerialized( + distributionMessageToBob.serialize())); + + final ciphertext = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('welcome to the group'))); + final plaintext = await bobGroupCipher.decrypt(ciphertext); + + assert(utf8.decode(plaintext) == 'welcome to the group'); + }); + + test('testOutOfOrder', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + const aliceName = groupSender; + + final aliceGroupCipher = GroupCipher(aliceStore, aliceName); + final bobGroupCipher = GroupCipher(bobStore, aliceName); + + final sentAliceDistributionMessage = + await aliceSessionBuilder.create(aliceName); + // ignore: unused_local_variable + final receivedAliceDistributionMessage = + SenderKeyDistributionMessageWrapper.fromSerialized( + sentAliceDistributionMessage.serialize()); + + final aliceDistributionMessage = + await aliceSessionBuilder.create(aliceName); + + await bobSessionBuilder.process(aliceName, aliceDistributionMessage); + + final ciphertexts = []; + + for (var i = 0; i < 100; i++) { + ciphertexts.add(await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('up the punks')))); + } + + while (ciphertexts.isNotEmpty) { + final index = randomInt() % ciphertexts.length; + final ciphertext = ciphertexts.removeAt(index); + final plaintext = await bobGroupCipher.decrypt(ciphertext); + + assert(utf8.decode(plaintext) == 'up the punks'); + } + }); + + test('testEncryptNoSession', () async { + final aliceStore = InMemorySenderKeyStore(); + final aliceGroupCipher = GroupCipher( + aliceStore, + const SenderKeyName( + 'coolio groupio', SignalProtocolAddress('+10002223333', 1))); + try { + await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('up the punks'))); + throw AssertionError('Should have failed!'); + } on NoSessionException { + // good + } + }); + + test('testTooFarInFuture', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + const aliceName = groupSender; + + final aliceGroupCipher = GroupCipher(aliceStore, aliceName); + final bobGroupCipher = GroupCipher(bobStore, aliceName); + + final aliceDistributionMessage = + await aliceSessionBuilder.create(aliceName); + + await bobSessionBuilder.process(aliceName, aliceDistributionMessage); + + for (var i = 0; i < 2001; i++) { + await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('up the punks'))); + } + + final tooFarCiphertext = await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('notta gonna worka'))); + try { + await bobGroupCipher.decrypt(tooFarCiphertext); + throw AssertionError('Should have failed!'); + } on InvalidMessageException { + // good + } + }); + + test('testMessageKeyLimit', () async { + final aliceStore = InMemorySenderKeyStore(); + final bobStore = InMemorySenderKeyStore(); + + final aliceSessionBuilder = GroupSessionBuilder(aliceStore); + final bobSessionBuilder = GroupSessionBuilder(bobStore); + + const aliceName = groupSender; + + final aliceGroupCipher = GroupCipher(aliceStore, aliceName); + final bobGroupCipher = GroupCipher(bobStore, aliceName); + + final aliceDistributionMessage = + await aliceSessionBuilder.create(aliceName); + + await bobSessionBuilder.process(aliceName, aliceDistributionMessage); + + final inflight = []; + + for (var i = 0; i < 2010; i++) { + inflight.add(await aliceGroupCipher + .encrypt(Uint8List.fromList(utf8.encode('up the punks')))); + } + + await bobGroupCipher.decrypt(inflight[1000]); + await bobGroupCipher.decrypt(inflight[inflight.length - 1]); + + try { + await bobGroupCipher.decrypt(inflight[0]); + throw AssertionError('Should have failed!'); + } on DuplicateMessageException { + // good + } + }); +} diff --git a/libsignal_protocol_dart/test/kdf/hkdf_test.dart b/libsignal_protocol_dart/test/kdf/hkdf_test.dart new file mode 100644 index 0000000..fd85d6c --- /dev/null +++ b/libsignal_protocol_dart/test/kdf/hkdf_test.dart @@ -0,0 +1,555 @@ +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/kdf/hkdf.dart'; +import 'package:test/test.dart'; + +void main() { + test('testVectorV3', () { + final ikm = Uint8List.fromList([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b + ]); + + final salt = Uint8List.fromList([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c + ]); + + final info = Uint8List.fromList( + [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9]); + + final okm = Uint8List.fromList([ + 0x3c, + 0xb2, + 0x5f, + 0x25, + 0xfa, + 0xac, + 0xd5, + 0x7a, + 0x90, + 0x43, + 0x4f, + 0x64, + 0xd0, + 0x36, + 0x2f, + 0x2a, + 0x2d, + 0x2d, + 0x0a, + 0x90, + 0xcf, + 0x1a, + 0x5a, + 0x4c, + 0x5d, + 0xb0, + 0x2d, + 0x56, + 0xec, + 0xc4, + 0xc5, + 0xbf, + 0x34, + 0x00, + 0x72, + 0x08, + 0xd5, + 0xb8, + 0x87, + 0x18, + 0x58, + 0x65 + ]); + + final actualOutput = HKDF.createFor(3).deriveSecrets4(ikm, salt, info, 42); + expect(okm, actualOutput); + }); + + test('testVectorLong3', () { + final ikm = Uint8List.fromList([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3a, + 0x3b, + 0x3c, + 0x3d, + 0x3e, + 0x3f, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f + ]); + + final salt = Uint8List.fromList([ + 0x60, + 0x61, + 0x62, + 0x63, + 0x64, + 0x65, + 0x66, + 0x67, + 0x68, + 0x69, + 0x6a, + 0x6b, + 0x6c, + 0x6d, + 0x6e, + 0x6f, + 0x70, + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, + 0x76, + 0x77, + 0x78, + 0x79, + 0x7a, + 0x7b, + 0x7c, + 0x7d, + 0x7e, + 0x7f, + 0x80, + 0x81, + 0x82, + 0x83, + 0x84, + 0x85, + 0x86, + 0x87, + 0x88, + 0x89, + 0x8a, + 0x8b, + 0x8c, + 0x8d, + 0x8e, + 0x8f, + 0x90, + 0x91, + 0x92, + 0x93, + 0x94, + 0x95, + 0x96, + 0x97, + 0x98, + 0x99, + 0x9a, + 0x9b, + 0x9c, + 0x9d, + 0x9e, + 0x9f, + 0xa0, + 0xa1, + 0xa2, + 0xa3, + 0xa4, + 0xa5, + 0xa6, + 0xa7, + 0xa8, + 0xa9, + 0xaa, + 0xab, + 0xac, + 0xad, + 0xae, + 0xaf + ]); + + final info = Uint8List.fromList([ + 0xb0, + 0xb1, + 0xb2, + 0xb3, + 0xb4, + 0xb5, + 0xb6, + 0xb7, + 0xb8, + 0xb9, + 0xba, + 0xbb, + 0xbc, + 0xbd, + 0xbe, + 0xbf, + 0xc0, + 0xc1, + 0xc2, + 0xc3, + 0xc4, + 0xc5, + 0xc6, + 0xc7, + 0xc8, + 0xc9, + 0xca, + 0xcb, + 0xcc, + 0xcd, + 0xce, + 0xcf, + 0xd0, + 0xd1, + 0xd2, + 0xd3, + 0xd4, + 0xd5, + 0xd6, + 0xd7, + 0xd8, + 0xd9, + 0xda, + 0xdb, + 0xdc, + 0xdd, + 0xde, + 0xdf, + 0xe0, + 0xe1, + 0xe2, + 0xe3, + 0xe4, + 0xe5, + 0xe6, + 0xe7, + 0xe8, + 0xe9, + 0xea, + 0xeb, + 0xec, + 0xed, + 0xee, + 0xef, + 0xf0, + 0xf1, + 0xf2, + 0xf3, + 0xf4, + 0xf5, + 0xf6, + 0xf7, + 0xf8, + 0xf9, + 0xfa, + 0xfb, + 0xfc, + 0xfd, + 0xfe, + 0xff + ]); + + final okm = Uint8List.fromList([ + 0xb1, + 0x1e, + 0x39, + 0x8d, + 0xc8, + 0x03, + 0x27, + 0xa1, + 0xc8, + 0xe7, + 0xf7, + 0x8c, + 0x59, + 0x6a, + 0x49, + 0x34, + 0x4f, + 0x01, + 0x2e, + 0xda, + 0x2d, + 0x4e, + 0xfa, + 0xd8, + 0xa0, + 0x50, + 0xcc, + 0x4c, + 0x19, + 0xaf, + 0xa9, + 0x7c, + 0x59, + 0x04, + 0x5a, + 0x99, + 0xca, + 0xc7, + 0x82, + 0x72, + 0x71, + 0xcb, + 0x41, + 0xc6, + 0x5e, + 0x59, + 0x0e, + 0x09, + 0xda, + 0x32, + 0x75, + 0x60, + 0x0c, + 0x2f, + 0x09, + 0xb8, + 0x36, + 0x77, + 0x93, + 0xa9, + 0xac, + 0xa3, + 0xdb, + 0x71, + 0xcc, + 0x30, + 0xc5, + 0x81, + 0x79, + 0xec, + 0x3e, + 0x87, + 0xc1, + 0x4c, + 0x01, + 0xd5, + 0xc1, + 0xf3, + 0x43, + 0x4f, + 0x1d, + 0x87 + ]); + + final actualOutput = HKDF.createFor(3).deriveSecrets4(ikm, salt, info, 82); + expect(okm, actualOutput); + }); + + test('testVectorV2', () { + final ikm = Uint8List.fromList([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b + ]); + + final salt = Uint8List.fromList([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c + ]); + + final info = Uint8List.fromList( + [0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9]); + + final okm = Uint8List.fromList([ + 0x6e, + 0xc2, + 0x55, + 0x6d, + 0x5d, + 0x7b, + 0x1d, + 0x81, + 0xde, + 0xe4, + 0x22, + 0x2a, + 0xd7, + 0x48, + 0x36, + 0x95, + 0xdd, + 0xc9, + 0x8f, + 0x4f, + 0x5f, + 0xab, + 0xc0, + 0xe0, + 0x20, + 0x5d, + 0xc2, + 0xef, + 0x87, + 0x52, + 0xd4, + 0x1e, + 0x04, + 0xe2, + 0xe2, + 0x11, + 0x01, + 0xc6, + 0x8f, + 0xf0, + 0x93, + 0x94, + 0xb8, + 0xad, + 0x0b, + 0xdc, + 0xb9, + 0x60, + 0x9c, + 0xd4, + 0xee, + 0x82, + 0xac, + 0x13, + 0x19, + 0x9b, + 0x4a, + 0xa9, + 0xfd, + 0xa8, + 0x99, + 0xda, + 0xeb, + 0xec + ]); + + final actualOutput = HKDF.createFor(2).deriveSecrets4(ikm, salt, info, 64); + expect(okm, actualOutput); + }); +} diff --git a/libsignal_protocol_dart/test/provisioning_cipher_test.dart b/libsignal_protocol_dart/test/provisioning_cipher_test.dart new file mode 100644 index 0000000..aa5c40a --- /dev/null +++ b/libsignal_protocol_dart/test/provisioning_cipher_test.dart @@ -0,0 +1,29 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:libsignal_protocol_dart/src/cbc.dart'; +import 'package:test/test.dart'; + +void main() { + test('testDecrypt', () { + const privateKey = 'GHtZBYTNqbCofFo0keD3jTGoHF6bUAeiW9iV5ad/HHA='; + const content = + 'eyJwdWJsaWNfa2V5IjoiQmZFOWJFa3EzZ2FsUTFHTnVEMWlJaHBrSkE0RHRTVUxkYXhkS3JiZndMcDgiLCJib2R5IjoiQVd6YWZJSDEyZ2tTQmRjdVplSXRMM3lXVmhZdW1lemppZk9rbFdsV3lnQzVKSXpzMHVxYXFZNnhsdFJzVWJya2N0NGFLazVKSmxwYlBKSXNqTU5qYXZKR1hNSFpOSnQ2SXZ1S1pkUVwvN1RzbjRUUjhmWjNSUXo2aGM3RlpYZENLTUJMVzJHTjAzSDd3aUt1elArZVV4WktCQjFPb2pWaVlSU0Vyc3dUWGwxeWR5cnhcLzM1NVY5MzFCR0N1VlBLVXFuOUJFWCtidVFhYms3YWZYdEVCOUI2YTZGSnFCZXVGcHdcLzlDdWpwYVpXNzNIMmswTmxkNjdPMzB5QkZEM3RuNmtiaXZ3MzNjN0l2Uk9EYlwvQnFTS1NGSlJoMUE2eU1leTAyeHZkNkJpRkxja1FRQk9LXC9ROW5ZOExoM2VlS2FNNTQ3cVV3XC9qUEE0ZGE5TzI0RkJUXC9ON2NvR2dBOVkrN1pvZ0syQ3YzbDZCNG9CN0xyTCtrVlRWTHJ2MFA1aDF3YklrUm10YWRLQmxiTjVvK3RnVUZ5VnVNcWFXQVJ6QnBJNlVDajVaZ0JJVWJWM3N0enVwUXpYU0E5OVBWV3hXOTE2dz09In0='; + final plaintext = decrypt(privateKey, content); + final result = utf8.decode(plaintext, allowMalformed: true); + const r = + '{"session_id":"304745a1-45af-4045-bd16-ba4d42a03a4e","platform":"iOS","user_id":"f59b9309-70c2-4b69-8fd8-5773dbd10018","identity_key_public":"BTEcMFj5uvP+32z+avKFOjDOrMvmnoDmwMfPZcuxBT08","identity_key_private":"iG5ilNnI8dkqtslK84NWWmPUhzADyUm6odlwA96isEk=","provisioning_code":"7972"}'; + assert(result == r); + }); + + test('testEncrypt', () { + final privateKey = + base64.decode('v9FTNn2tg40ENCEaoCHstCo5J0wb9wKwgZQ6PYJjf0U='); + final iv = base64.decode('tNp4sPQGKjwzqN0L8tDLDg=='); + const encode = 'l0JO9zrPWzrPg2r53Sjf6g=='; + final ciphertext = aesCbcEncrypt( + privateKey, iv, Uint8List.fromList(utf8.encode('Hello Mixin'))); + assert(encode == base64.encode(ciphertext)); + }); +} diff --git a/libsignal_protocol_dart/test/ratchet/chain_key_test.dart b/libsignal_protocol_dart/test/ratchet/chain_key_test.dart new file mode 100644 index 0000000..75e2a21 --- /dev/null +++ b/libsignal_protocol_dart/test/ratchet/chain_key_test.dart @@ -0,0 +1,314 @@ +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/kdf/hkdf.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/chain_key.dart'; +import 'package:test/test.dart'; + +void main() { + test('testChainKeyDerivationV2', () { + final seed = Uint8List.fromList([ + 0x8a, + 0xb7, + 0x2d, + 0x6f, + 0x4c, + 0xc5, + 0xac, + 0x0d, + 0x38, + 0x7e, + 0xaf, + 0x46, + 0x33, + 0x78, + 0xdd, + 0xb2, + 0x8e, + 0xdd, + 0x07, + 0x38, + 0x5b, + 0x1c, + 0xb0, + 0x12, + 0x50, + 0xc7, + 0x15, + 0x98, + 0x2e, + 0x7a, + 0xd4, + 0x8f + ]); + + final messageKey = Uint8List.fromList([ + 0x02, + 0xa9, + 0xaa, + 0x6c, + 0x7d, + 0xbd, + 0x64, + 0xf9, + 0xd3, + 0xaa, + 0x92, + 0xf9, + 0x2a, + 0x27, + 0x7b, + 0xf5, + 0x46, + 0x09, + 0xda, + 0xdf, + 0x0b, + 0x00, + 0x82, + 0x8a, + 0xcf, + 0xc6, + 0x1e, + 0x3c, + 0x72, + 0x4b, + 0x84, + 0xa7 + ]); + + final macKey = Uint8List.fromList([ + 0xbf, + 0xbe, + 0x5e, + 0xfb, + 0x60, + 0x30, + 0x30, + 0x52, + 0x67, + 0x42, + 0xe3, + 0xee, + 0x89, + 0xc7, + 0x02, + 0x4e, + 0x88, + 0x4e, + 0x44, + 0x0f, + 0x1f, + 0xf3, + 0x76, + 0xbb, + 0x23, + 0x17, + 0xb2, + 0xd6, + 0x4d, + 0xeb, + 0x7c, + 0x83 + ]); + + final nextChainKey = Uint8List.fromList([ + 0x28, + 0xe8, + 0xf8, + 0xfe, + 0xe5, + 0x4b, + 0x80, + 0x1e, + 0xef, + 0x7c, + 0x5c, + 0xfb, + 0x2f, + 0x17, + 0xf3, + 0x2c, + 0x7b, + 0x33, + 0x44, + 0x85, + 0xbb, + 0xb7, + 0x0f, + 0xac, + 0x6e, + 0xc1, + 0x03, + 0x42, + 0xa2, + 0x46, + 0xd1, + 0x5d + ]); + + final chainKey = ChainKey(HKDF.createFor(2), seed, 0); + + expect(chainKey.key, seed); + expect(chainKey.getMessageKeys().getCipherKey(), messageKey); + expect(chainKey.getMessageKeys().getMacKey(), macKey); + expect(chainKey.getNextChainKey().key, nextChainKey); + expect(chainKey.index, 0); + expect(chainKey.getMessageKeys().getCounter(), 0); + expect(chainKey.getNextChainKey().index, 1); + expect(chainKey.getNextChainKey().getMessageKeys().getCounter(), 1); + }); + + test('testChainKeyDerivationV3()', () { + final seed = Uint8List.fromList([ + 0x8a, + 0xb7, + 0x2d, + 0x6f, + 0x4c, + 0xc5, + 0xac, + 0x0d, + 0x38, + 0x7e, + 0xaf, + 0x46, + 0x33, + 0x78, + 0xdd, + 0xb2, + 0x8e, + 0xdd, + 0x07, + 0x38, + 0x5b, + 0x1c, + 0xb0, + 0x12, + 0x50, + 0xc7, + 0x15, + 0x98, + 0x2e, + 0x7a, + 0xd4, + 0x8f + ]); + + final messageKey = Uint8List.fromList([ + /* 0x02*/ + 0xbf, + 0x51, + 0xe9, + 0xd7, + 0x5e, + 0x0e, + 0x31, + 0x03, + 0x10, + 0x51, + 0xf8, + 0x2a, + 0x24, + 0x91, + 0xff, + 0xc0, + 0x84, + 0xfa, + 0x29, + 0x8b, + 0x77, + 0x93, + 0xbd, + 0x9d, + 0xb6, + 0x20, + 0x05, + 0x6f, + 0xeb, + 0xf4, + 0x52, + 0x17 + ]); + + final macKey = Uint8List.fromList([ + 0xc6, + 0xc7, + 0x7d, + 0x6a, + 0x73, + 0xa3, + 0x54, + 0x33, + 0x7a, + 0x56, + 0x43, + 0x5e, + 0x34, + 0x60, + 0x7d, + 0xfe, + 0x48, + 0xe3, + 0xac, + 0xe1, + 0x4e, + 0x77, + 0x31, + 0x4d, + 0xc6, + 0xab, + 0xc1, + 0x72, + 0xe7, + 0xa7, + 0x03, + 0x0b + ]); + + final nextChainKey = Uint8List.fromList([ + 0x28, + 0xe8, + 0xf8, + 0xfe, + 0xe5, + 0x4b, + 0x80, + 0x1e, + 0xef, + 0x7c, + 0x5c, + 0xfb, + 0x2f, + 0x17, + 0xf3, + 0x2c, + 0x7b, + 0x33, + 0x44, + 0x85, + 0xbb, + 0xb7, + 0x0f, + 0xac, + 0x6e, + 0xc1, + 0x03, + 0x42, + 0xa2, + 0x46, + 0xd1, + 0x5d + ]); + + final chainKey = ChainKey(HKDF.createFor(3), seed, 0); + + expect(chainKey.key, seed); + expect(chainKey.getMessageKeys().getCipherKey(), messageKey); + expect(chainKey.getMessageKeys().getMacKey(), macKey); + expect(chainKey.getNextChainKey().key, nextChainKey); + expect(chainKey.index, 0); + expect(chainKey.getMessageKeys().getCounter(), 0); + expect(chainKey.getNextChainKey().index, 1); + expect(chainKey.getNextChainKey().getMessageKeys().getCounter(), 1); + }); +} diff --git a/libsignal_protocol_dart/test/ratchet/ratcheting_session_test.dart b/libsignal_protocol_dart/test/ratchet/ratcheting_session_test.dart new file mode 100644 index 0000000..edf031e --- /dev/null +++ b/libsignal_protocol_dart/test/ratchet/ratcheting_session_test.dart @@ -0,0 +1,418 @@ +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/ecc/ec_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:libsignal_protocol_dart/src/identity_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/bob_signal_protocol_parameters.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/ratcheting_session.dart'; +import 'package:libsignal_protocol_dart/src/state/session_state.dart'; +import 'package:optional/optional.dart'; +import 'package:test/test.dart'; + +void main() { + test('testRatchetingSessionAsBob', () { + final bobPublic = Uint8List.fromList([ + 0x05, + 0x2c, + 0xb4, + 0x97, + 0x76, + 0xb8, + 0x77, + 0x02, + 0x05, + 0x74, + 0x5a, + 0x3a, + 0x6e, + 0x24, + 0xf5, + 0x79, + 0xcd, + 0xb4, + 0xba, + 0x7a, + 0x89, + 0x04, + 0x10, + 0x05, + 0x92, + 0x8e, + 0xbb, + 0xad, + 0xc9, + 0xc0, + 0x5a, + 0xd4, + 0x58 + ]); + + final bobPrivate = Uint8List.fromList([ + 0xa1, + 0xca, + 0xb4, + 0x8f, + 0x7c, + 0x89, + 0x3f, + 0xaf, + 0xa9, + 0x88, + 0x0a, + 0x28, + 0xc3, + 0xb4, + 0x99, + 0x9d, + 0x28, + 0xd6, + 0x32, + 0x95, + 0x62, + 0xd2, + 0x7a, + 0x4e, + 0xa4, + 0xe2, + 0x2e, + 0x9f, + 0xf1, + 0xbd, + 0xd6, + 0x5a + ]); + + final bobIdentityPublic = Uint8List.fromList([ + 0x05, + 0xf1, + 0xf4, + 0x38, + 0x74, + 0xf6, + 0x96, + 0x69, + 0x56, + 0xc2, + 0xdd, + 0x47, + 0x3f, + 0x8f, + 0xa1, + 0x5a, + 0xde, + 0xb7, + 0x1d, + 0x1c, + 0xb9, + 0x91, + 0xb2, + 0x34, + 0x16, + 0x92, + 0x32, + 0x4c, + 0xef, + 0xb1, + 0xc5, + 0xe6, + 0x26 + ]); + + final bobIdentityPrivate = Uint8List.fromList([ + 0x48, + 0x75, + 0xcc, + 0x69, + 0xdd, + 0xf8, + 0xea, + 0x07, + 0x19, + 0xec, + 0x94, + 0x7d, + 0x61, + 0x08, + 0x11, + 0x35, + 0x86, + 0x8d, + 0x5f, + 0xd8, + 0x01, + 0xf0, + 0x2c, + 0x02, + 0x25, + 0xe5, + 0x16, + 0xdf, + 0x21, + 0x56, + 0x60, + 0x5e + ]); + + final aliceBasePublic = Uint8List.fromList([ + 0x05, + 0x47, + 0x2d, + 0x1f, + 0xb1, + 0xa9, + 0x86, + 0x2c, + 0x3a, + 0xf6, + 0xbe, + 0xac, + 0xa8, + 0x92, + 0x02, + 0x77, + 0xe2, + 0xb2, + 0x6f, + 0x4a, + 0x79, + 0x21, + 0x3e, + 0xc7, + 0xc9, + 0x06, + 0xae, + 0xb3, + 0x5e, + 0x03, + 0xcf, + 0x89, + 0x50 + ]); + + final aliceEphemeralPublic = Uint8List.fromList([ + 0x05, + 0x6c, + 0x3e, + 0x0d, + 0x1f, + 0x52, + 0x02, + 0x83, + 0xef, + 0xcc, + 0x55, + 0xfc, + 0xa5, + 0xe6, + 0x70, + 0x75, + 0xb9, + 0x04, + 0x00, + 0x7f, + 0x18, + 0x81, + 0xd1, + 0x51, + 0xaf, + 0x76, + 0xdf, + 0x18, + 0xc5, + 0x1d, + 0x29, + 0xd3, + 0x4b + ]); + + final aliceIdentityPublic = Uint8List.fromList([ + 0x05, + 0xb4, + 0xa8, + 0x45, + 0x56, + 0x60, + 0xad, + 0xa6, + 0x5b, + 0x40, + 0x10, + 0x07, + 0xf6, + 0x15, + 0xe6, + 0x54, + 0x04, + 0x17, + 0x46, + 0x43, + 0x2e, + 0x33, + 0x39, + 0xc6, + 0x87, + 0x51, + 0x49, + 0xbc, + 0xee, + 0xfc, + 0xb4, + 0x2b, + 0x4a + ]); + + final bobSignedPreKeyPublic = Uint8List.fromList([ + 0x05, + 0xac, + 0x24, + 0x8a, + 0x8f, + 0x26, + 0x3b, + 0xe6, + 0x86, + 0x35, + 0x76, + 0xeb, + 0x03, + 0x62, + 0xe2, + 0x8c, + 0x82, + 0x8f, + 0x01, + 0x07, + 0xa3, + 0x37, + 0x9d, + 0x34, + 0xba, + 0xb1, + 0x58, + 0x6b, + 0xf8, + 0xc7, + 0x70, + 0xcd, + 0x67 + ]); + + final bobSignedPreKeyPrivate = Uint8List.fromList([ + 0x58, + 0x39, + 0x00, + 0x13, + 0x1f, + 0xb7, + 0x27, + 0x99, + 0x8b, + 0x78, + 0x03, + 0xfe, + 0x6a, + 0xc2, + 0x2c, + 0xc5, + 0x91, + 0xf3, + 0x42, + 0xe4, + 0xe4, + 0x2a, + 0x8c, + 0x8d, + 0x5d, + 0x78, + 0x19, + 0x42, + 0x09, + 0xb8, + 0xd2, + 0x53 + ]); + + final senderChain = Uint8List.fromList([ + 0x97, + 0x97, + 0xca, + 0xca, + 0x53, + 0xc9, + 0x89, + 0xbb, + 0xe2, + 0x29, + 0xa4, + 0x0c, + 0xa7, + 0x72, + 0x70, + 0x10, + 0xeb, + 0x26, + 0x04, + 0xfc, + 0x14, + 0x94, + 0x5d, + 0x77, + 0x95, + 0x8a, + 0x0a, + 0xed, + 0xa0, + 0x88, + 0xb4, + 0x4d + ]); + + final bobIdentityKeyPublic = IdentityKey.fromBytes(bobIdentityPublic, 0); + final bobIdentityKeyPrivate = Curve.decodePrivatePoint(bobIdentityPrivate); + final bobIdentityKey = + IdentityKeyPair(bobIdentityKeyPublic, bobIdentityKeyPrivate); + final bobEphemeralPublicKey = Curve.decodePoint(bobPublic, 0); + final bobEphemeralPrivateKey = Curve.decodePrivatePoint(bobPrivate); + final bobEphemeralKey = + ECKeyPair(bobEphemeralPublicKey, bobEphemeralPrivateKey); + // ignore: unused_local_variable + final bobBaseKey = bobEphemeralKey; + final bobSignedPreKey = ECKeyPair( + Curve.decodePoint(bobSignedPreKeyPublic, 0), + Curve.decodePrivatePoint(bobSignedPreKeyPrivate)); + + final aliceBasePublicKey = Curve.decodePoint(aliceBasePublic, 0); + // ignore: unused_local_variable + final aliceEphemeralPublicKey = Curve.decodePoint(aliceEphemeralPublic, 0); + final aliceIdentityPublicKey = + IdentityKey.fromBytes(aliceIdentityPublic, 0); + + final parameters = BobSignalProtocolParameters( + ourIdentityKey: bobIdentityKey, + ourSignedPreKey: bobSignedPreKey, + ourRatchetKey: bobEphemeralKey, + ourOneTimePreKey: const Optional.empty(), + theirIdentityKey: aliceIdentityPublicKey, + theirBaseKey: aliceBasePublicKey, + ); + + final session = SessionState(); + + RatchetingSession.initializeSessionBob(session, parameters); + + expect( + 0, + session + .getLocalIdentityKey() + .publicKey + .compareTo(bobIdentityKey.getPublicKey().publicKey)); + expect( + 0, + session + .getRemoteIdentityKey() + ?.publicKey + .compareTo(aliceIdentityPublicKey.publicKey)); + expect(session.getSenderChainKey().key, senderChain); + }); +} diff --git a/libsignal_protocol_dart/test/ratchet/root_key_test.dart b/libsignal_protocol_dart/test/ratchet/root_key_test.dart new file mode 100644 index 0000000..f2e0279 --- /dev/null +++ b/libsignal_protocol_dart/test/ratchet/root_key_test.dart @@ -0,0 +1,243 @@ +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/ecc/ec_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/kdf/hkdf.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/root_key.dart'; +import 'package:test/test.dart'; + +void main() { + test('testRootKeyDerivationV2', () { + final rootKeySeed = Uint8List.fromList([ + 0x7b, + 0xa6, + 0xde, + 0xbc, + 0x2b, + 0xc1, + 0xbb, + 0xf9, + 0x1a, + 0xbb, + 0xc1, + 0x36, + 0x74, + 0x04, + 0x17, + 0x6c, + 0xa6, + 0x23, + 0x09, + 0x5b, + 0x7e, + 0xc6, + 0x6b, + 0x45, + 0xf6, + 0x02, + 0xd9, + 0x35, + 0x38, + 0x94, + 0x2d, + 0xcc + ]); + + final alicePublic = Uint8List.fromList([ + 0x05, + 0xee, + 0x4f, + 0xa6, + 0xcd, + 0xc0, + 0x30, + 0xdf, + 0x49, + 0xec, + 0xd0, + 0xba, + 0x6c, + 0xfc, + 0xff, + 0xb2, + 0x33, + 0xd3, + 0x65, + 0xa2, + 0x7f, + 0xad, + 0xbe, + 0xff, + 0x77, + 0xe9, + 0x63, + 0xfc, + 0xb1, + 0x62, + 0x22, + 0xe1, + 0x3a + ]); + + final alicePrivate = Uint8List.fromList([ + 0x21, + 0x68, + 0x22, + 0xec, + 0x67, + 0xeb, + 0x38, + 0x04, + 0x9e, + 0xba, + 0xe7, + 0xb9, + 0x39, + 0xba, + 0xea, + 0xeb, + 0xb1, + 0x51, + 0xbb, + 0xb3, + 0x2d, + 0xb8, + 0x0f, + 0xd3, + 0x89, + 0x24, + 0x5a, + 0xc3, + 0x7a, + 0x94, + 0x8e, + 0x50 + ]); + + final bobPublic = Uint8List.fromList([ + 0x05, + 0xab, + 0xb8, + 0xeb, + 0x29, + 0xcc, + 0x80, + 0xb4, + 0x71, + 0x09, + 0xa2, + 0x26, + 0x5a, + 0xbe, + 0x97, + 0x98, + 0x48, + 0x54, + 0x06, + 0xe3, + 0x2d, + 0xa2, + 0x68, + 0x93, + 0x4a, + 0x95, + 0x55, + 0xe8, + 0x47, + 0x57, + 0x70, + 0x8a, + 0x30 + ]); + + // ignore: unused_local_variable + final nextRoot = Uint8List.fromList([ + 0xb1, + 0x14, + 0xf5, + 0xde, + 0x28, + 0x01, + 0x19, + 0x85, + 0xe6, + 0xeb, + 0xa2, + 0x5d, + 0x50, + 0xe7, + 0xec, + 0x41, + 0xa9, + 0xb0, + 0x2f, + 0x56, + 0x93, + 0xc5, + 0xc7, + 0x88, + 0xa6, + 0x3a, + 0x06, + 0xd2, + 0x12, + 0xa2, + 0xf7, + 0x31 + ]); + + // ignore: unused_local_variable + final nextChain = Uint8List.fromList([ + 0x9d, + 0x7d, + 0x24, + 0x69, + 0xbc, + 0x9a, + 0xe5, + 0x3e, + 0xe9, + 0x80, + 0x5a, + 0xa3, + 0x26, + 0x4d, + 0x24, + 0x99, + 0xa3, + 0xac, + 0xe8, + 0x0f, + 0x4c, + 0xca, + 0xe2, + 0xda, + 0x13, + 0x43, + 0x0c, + 0x5c, + 0x55, + 0xb5, + 0xca, + 0x5f + ]); + + final alicePublicKey = Curve.decodePoint(alicePublic, 0); + final alicePrivateKey = Curve.decodePrivatePoint(alicePrivate); + final aliceKeyPair = ECKeyPair(alicePublicKey, alicePrivateKey); + + final bobPublicKey = Curve.decodePoint(bobPublic, 0); + final rootKey = RootKey(HKDF.createFor(2), rootKeySeed); + + final rootKeyChainKeyPair = rootKey.createChain(bobPublicKey, aliceKeyPair); + // ignore: unused_local_variable + final nextRootKey = rootKeyChainKeyPair.$1; + // ignore: unused_local_variable + final nextChainKey = rootKeyChainKeyPair.$2; + + expect(rootKey.getKeyBytes(), rootKeySeed); + // TODO +// expect(nextRootKey.getKeyBytes(), nextRoot); +// expect(nextChainKey.getKey(), nextChain); + }); +} diff --git a/libsignal_protocol_dart/test/session_builder_test.dart b/libsignal_protocol_dart/test/session_builder_test.dart new file mode 100644 index 0000000..b095dd1 --- /dev/null +++ b/libsignal_protocol_dart/test/session_builder_test.dart @@ -0,0 +1,347 @@ +import 'dart:collection'; +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:fixnum/fixnum.dart'; +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/invalid_key_exception.dart'; +import 'package:libsignal_protocol_dart/src/protocol/ciphertext_message.dart'; +import 'package:libsignal_protocol_dart/src/protocol/pre_key_signal_message.dart'; +import 'package:libsignal_protocol_dart/src/protocol/signal_message.dart'; +import 'package:libsignal_protocol_dart/src/session_builder.dart'; +import 'package:libsignal_protocol_dart/src/session_cipher.dart'; +import 'package:libsignal_protocol_dart/src/signal_protocol_address.dart'; +import 'package:libsignal_protocol_dart/src/state/pre_key_bundle.dart'; +import 'package:libsignal_protocol_dart/src/state/pre_key_record.dart'; +import 'package:libsignal_protocol_dart/src/state/signal_protocol_store.dart'; +import 'package:libsignal_protocol_dart/src/state/signed_pre_key_record.dart'; +import 'package:libsignal_protocol_dart/src/untrusted_identity_exception.dart'; +import 'package:test/test.dart'; + +import 'test_in_memory_identity_key_store.dart'; +import 'test_in_memory_signal_protocol_store.dart'; + +void main() { + const aliceAddress = SignalProtocolAddress('+14151111111', 1); + const bobAddress = SignalProtocolAddress('+14152222222', 1); + + test('testBasicPreKeyV2', () async { + final aliceStore = TestInMemorySignalProtocolStore(); + final aliceSessionBuilder = + SessionBuilder.fromSignalStore(aliceStore, bobAddress); + + final bobStore = TestInMemorySignalProtocolStore(); + final bobPreKeyPair = Curve.generateKeyPair(); + final bobPreKey = PreKeyBundle( + await bobStore.getLocalRegistrationId(), + 1, + 31337, + bobPreKeyPair.publicKey, + 0, + null, + null, + await bobStore + .getIdentityKeyPair() + .then((value) => value.getPublicKey())); + try { + await aliceSessionBuilder.processPreKeyBundle(bobPreKey); + throw AssertionError('Should fail with missing unsigned prekey!'); + } on InvalidKeyException { + // Good! + return; + } + }); + + Future runInteraction( + SignalProtocolStore aliceStore, SignalProtocolStore bobStore) async { + final aliceSessionCipher = SessionCipher.fromStore(aliceStore, bobAddress); + final bobSessionCipher = SessionCipher.fromStore(bobStore, aliceAddress); + + const originalMessage = 'smert ze smert'; + final aliceMessage = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(originalMessage))); + + assert(aliceMessage.getType() == CiphertextMessage.whisperType); + + var plaintext = await bobSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(aliceMessage.serialize())); + assert(String.fromCharCodes(plaintext) == originalMessage); + + final bobMessage = await bobSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(originalMessage))); + + assert(bobMessage.getType() == CiphertextMessage.whisperType); + + plaintext = await aliceSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(bobMessage.serialize())); + assert(String.fromCharCodes(plaintext) == originalMessage); + + for (var i = 0; i < 10; i++) { + final loopingMessage = + '''What do we mean by saying that existence precedes essence? + We mean that man first of all exists, encounters himself, + surges up in the world--and defines himself aftward. $i'''; + final aliceLoopingMessage = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(loopingMessage))); + + final loopingPlaintext = await bobSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(aliceLoopingMessage.serialize())); + assert(String.fromCharCodes(loopingPlaintext) == loopingMessage); + } + + for (var i = 0; i < 10; i++) { + final loopingMessage = + '''What do we mean by saying that existence precedes essence? + We mean that man first of all exists, encounters himself, + surges up in the world--and defines himself aftward. $i'''; + final bobLoopingMessage = await bobSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(loopingMessage))); + + final loopingPlaintext = await aliceSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(bobLoopingMessage.serialize())); + assert(String.fromCharCodes(loopingPlaintext) == loopingMessage); + } + + final Set<(String, CiphertextMessage)> aliceOutOfOrderMessages = + HashSet<(String, CiphertextMessage)>(); + + for (var i = 0; i < 10; i++) { + final loopingMessage = + '''What do we mean by saying that existence precedes essence? + We mean that man first of all exists, encounters himself, + surges up in the world--and defines himself aftward. $i'''; + final aliceLoopingMessage = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(loopingMessage))); + + aliceOutOfOrderMessages.add((loopingMessage, aliceLoopingMessage)); + } + + for (var i = 0; i < 10; i++) { + final loopingMessage = + '''What do we mean by saying that existence precedes essence? + We mean that man first of all exists, encounters himself, + surges up in the world--and defines himself aftward. $i'''; + final aliceLoopingMessage = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(loopingMessage))); + + final loopingPlaintext = await bobSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(aliceLoopingMessage.serialize())); + assert(String.fromCharCodes(loopingPlaintext) == loopingMessage); + } + + for (var i = 0; i < 10; i++) { + final loopingMessage = 'You can only desire based on what you know: $i'; + final bobLoopingMessage = await bobSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(loopingMessage))); + + final loopingPlaintext = await aliceSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(bobLoopingMessage.serialize())); + assert(String.fromCharCodes(loopingPlaintext) == loopingMessage); + } + + for (final aliceOutOfOrderMessage in aliceOutOfOrderMessages) { + final outOfOrderPlaintext = await bobSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(aliceOutOfOrderMessage.$2.serialize())); + assert(String.fromCharCodes(outOfOrderPlaintext) == + (aliceOutOfOrderMessage.$1)); + } + } + + test('testBasicPreKeyV3', () async { + var aliceStore = TestInMemorySignalProtocolStore(); + var aliceSessionBuilder = + SessionBuilder.fromSignalStore(aliceStore, bobAddress); + + final bobStore = TestInMemorySignalProtocolStore(); + var bobPreKeyPair = Curve.generateKeyPair(); + var bobSignedPreKeyPair = Curve.generateKeyPair(); + var bobSignedPreKeySignature = Curve.calculateSignature( + await bobStore + .getIdentityKeyPair() + .then((value) => value.getPrivateKey()), + bobSignedPreKeyPair.publicKey.serialize()); + + var bobPreKey = PreKeyBundle( + await bobStore.getLocalRegistrationId(), + 1, + 31337, + bobPreKeyPair.publicKey, + 22, + bobSignedPreKeyPair.publicKey, + bobSignedPreKeySignature, + await bobStore + .getIdentityKeyPair() + .then((value) => value.getPublicKey())); + await aliceSessionBuilder.processPreKeyBundle(bobPreKey); + + assert(await aliceStore.containsSession(bobAddress)); + assert(await aliceStore + .loadSession(bobAddress) + .then((value) => value.sessionState.getSessionVersion()) == + 3); + + const originalMessage = "L'homme est condamné à être libre"; + var aliceSessionCipher = SessionCipher.fromStore(aliceStore, bobAddress); + var outgoingMessage = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(originalMessage))); + assert(outgoingMessage.getType() == CiphertextMessage.prekeyType); + + final incomingMessage = PreKeySignalMessage(outgoingMessage.serialize()); + await bobStore.storePreKey( + 31337, PreKeyRecord(bobPreKey.getPreKeyId()!, bobPreKeyPair)); + await bobStore.storeSignedPreKey( + 22, + SignedPreKeyRecord(22, Int64(DateTime.now().millisecondsSinceEpoch), + bobSignedPreKeyPair, bobSignedPreKeySignature)); + + final bobSessionCipher = SessionCipher.fromStore(bobStore, aliceAddress); + var plaintext = await bobSessionCipher.decryptWithCallback(incomingMessage, + (plaintext) async { + final result = utf8.decode(plaintext, allowMalformed: true); + assert(originalMessage == result); + assert(!await bobStore.containsSession(aliceAddress)); + }); + + assert(await bobStore.containsSession(aliceAddress)); + assert(await bobStore + .loadSession(aliceAddress) + .then((value) => value.sessionState.getSessionVersion()) == + 3); + assert(originalMessage == utf8.decode(plaintext, allowMalformed: true)); + + final bobOutgoingMessage = await bobSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(originalMessage))); + assert(bobOutgoingMessage.getType() == CiphertextMessage.whisperType); + + final alicePlaintext = await aliceSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(bobOutgoingMessage.serialize())); + assert( + utf8.decode(alicePlaintext, allowMalformed: true) == originalMessage); + + await runInteraction(aliceStore, bobStore); + + aliceStore = TestInMemorySignalProtocolStore(); + aliceSessionBuilder = + SessionBuilder.fromSignalStore(aliceStore, bobAddress); + aliceSessionCipher = SessionCipher.fromStore(aliceStore, bobAddress); + + bobPreKeyPair = Curve.generateKeyPair(); + bobSignedPreKeyPair = Curve.generateKeyPair(); + bobSignedPreKeySignature = Curve.calculateSignature( + await bobStore + .getIdentityKeyPair() + .then((value) => value.getPrivateKey()), + bobSignedPreKeyPair.publicKey.serialize()); + bobPreKey = PreKeyBundle( + await bobStore.getLocalRegistrationId(), + 1, + 31338, + bobPreKeyPair.publicKey, + 23, + bobSignedPreKeyPair.publicKey, + bobSignedPreKeySignature, + await bobStore + .getIdentityKeyPair() + .then((value) => value.getPublicKey())); + + await bobStore.storePreKey( + 31338, PreKeyRecord(bobPreKey.getPreKeyId()!, bobPreKeyPair)); + await bobStore.storeSignedPreKey( + 23, + SignedPreKeyRecord(23, Int64(DateTime.now().millisecondsSinceEpoch), + bobSignedPreKeyPair, bobSignedPreKeySignature)); + await aliceSessionBuilder.processPreKeyBundle(bobPreKey); + + outgoingMessage = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(originalMessage))); + + try { + plaintext = await bobSessionCipher + .decrypt(PreKeySignalMessage(outgoingMessage.serialize())); + throw AssertionError("shouldn't be trusted!"); + } on UntrustedIdentityException { + await bobStore.saveIdentity(aliceAddress, + PreKeySignalMessage(outgoingMessage.serialize()).getIdentityKey()); + } + + plaintext = await bobSessionCipher + .decrypt(PreKeySignalMessage(outgoingMessage.serialize())); + assert(utf8.decode(plaintext, allowMalformed: true) == originalMessage); + + bobPreKey = PreKeyBundle( + await bobStore.getLocalRegistrationId(), + 1, + 31337, + Curve.generateKeyPair().publicKey, + 23, + bobSignedPreKeyPair.publicKey, + bobSignedPreKeySignature, + await aliceStore + .getIdentityKeyPair() + .then((value) => value.getPublicKey())); + + try { + await aliceSessionBuilder.processPreKeyBundle(bobPreKey); + throw AssertionError("shoulnd't be trusted!"); + } on UntrustedIdentityException { + // good + } + }); + + test('testBadSignedPreKeySignature', () async { + final aliceStore = TestInMemorySignalProtocolStore(); + final aliceSessionBuilder = + SessionBuilder.fromSignalStore(aliceStore, bobAddress); + + final bobIdentityKeyStore = TestInMemoryIdentityKeyStore(); + + final bobPreKeyPair = Curve.generateKeyPair(); + final bobSignedPreKeyPair = Curve.generateKeyPair(); + final bobSignedPreKeySignature = Curve.calculateSignature( + await bobIdentityKeyStore + .getIdentityKeyPair() + .then((value) => value.getPrivateKey()), + bobSignedPreKeyPair.publicKey.serialize()); + + for (var i = 0; i < bobSignedPreKeySignature.length * 8; i++) { + final modifiedSignature = Uint8List(bobSignedPreKeySignature.length); + Curve.arraycopy(bobSignedPreKeySignature, 0, modifiedSignature, 0, + modifiedSignature.length); + + modifiedSignature[i ~/ 8] ^= 0x01 << (i % 8); + + final bobPreKey = PreKeyBundle( + await bobIdentityKeyStore.getLocalRegistrationId(), + 1, + 31337, + bobPreKeyPair.publicKey, + 22, + bobSignedPreKeyPair.publicKey, + modifiedSignature, + await bobIdentityKeyStore + .getIdentityKeyPair() + .then((value) => value.getPublicKey())); + + try { + await aliceSessionBuilder.processPreKeyBundle(bobPreKey); + throw AssertionError('Accepted modified device key signature!'); + } on InvalidKeyException { + // good + } + } + + final bobPreKey = PreKeyBundle( + await bobIdentityKeyStore.getLocalRegistrationId(), + 1, + 31337, + bobPreKeyPair.publicKey, + 22, + bobSignedPreKeyPair.publicKey, + bobSignedPreKeySignature, + await bobIdentityKeyStore + .getIdentityKeyPair() + .then((value) => value.getPublicKey())); + + await aliceSessionBuilder.processPreKeyBundle(bobPreKey); + }); +} diff --git a/libsignal_protocol_dart/test/session_cipher_test.dart b/libsignal_protocol_dart/test/session_cipher_test.dart new file mode 100644 index 0000000..2ba7083 --- /dev/null +++ b/libsignal_protocol_dart/test/session_cipher_test.dart @@ -0,0 +1,256 @@ +import 'dart:convert'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/duplicate_message_exception.dart'; +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/ecc/ec_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/ecc/ec_public_key.dart'; +import 'package:libsignal_protocol_dart/src/eq.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:libsignal_protocol_dart/src/identity_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/protocol/ciphertext_message.dart'; +import 'package:libsignal_protocol_dart/src/protocol/signal_message.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/alice_signal_protocol_parameters.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/bob_signal_protocol_parameters.dart'; +import 'package:libsignal_protocol_dart/src/ratchet/ratcheting_session.dart'; +import 'package:libsignal_protocol_dart/src/session_cipher.dart'; +import 'package:libsignal_protocol_dart/src/signal_protocol_address.dart'; +import 'package:libsignal_protocol_dart/src/state/session_record.dart'; +import 'package:libsignal_protocol_dart/src/state/session_state.dart'; +import 'package:optional/optional.dart'; +import 'package:test/test.dart'; + +import 'test_in_memory_signal_protocol_store.dart'; + +Future main() async { + const integerMax = 0x7fffffff; + + int randomInt() { + final secureRandom = Random.secure(); + return secureRandom.nextInt(integerMax); + } + + Future runInteraction( + SessionRecord aliceSessionRecord, SessionRecord bobSessionRecord) async { + final aliceStore = TestInMemorySignalProtocolStore(); + final bobStore = TestInMemorySignalProtocolStore(); + + await aliceStore.storeSession( + const SignalProtocolAddress('+14159999999', 1), aliceSessionRecord); + await bobStore.storeSession( + const SignalProtocolAddress('+14158888888', 1), bobSessionRecord); + + final aliceCipher = SessionCipher.fromStore( + aliceStore, const SignalProtocolAddress('+14159999999', 1)); + final bobCipher = SessionCipher.fromStore( + bobStore, const SignalProtocolAddress('+14158888888', 1)); + + final alicePlaintext = + Uint8List.fromList(utf8.encode('This is a plaintext message.')); + final message = await aliceCipher.encrypt(alicePlaintext); + final bobPlaintext = await bobCipher + .decryptFromSignal(SignalMessage.fromSerialized(message.serialize())); + + assert(eq(alicePlaintext, bobPlaintext)); + + final bobReply = + Uint8List.fromList(utf8.encode('This is a message from Bob.')); + final reply = await bobCipher.encrypt(bobReply); + final receivedReply = await aliceCipher + .decryptFromSignal(SignalMessage.fromSerialized(reply.serialize())); + + assert(eq(bobReply, receivedReply)); + + final aliceCiphertextMessages = []; + final alicePlaintextMessages = []; + + for (var i = 0; i < 50; i++) { + alicePlaintextMessages + .add(Uint8List.fromList(utf8.encode('смерть за смерть $i'))); + aliceCiphertextMessages.add(await aliceCipher + .encrypt(Uint8List.fromList(utf8.encode('смерть за смерть $i')))); + } + + var seed = DateTime.now().microsecondsSinceEpoch; + + aliceCiphertextMessages.shuffle(Random(seed)); + alicePlaintextMessages.shuffle(Random(seed)); + + for (var i = 0; i < aliceCiphertextMessages.length / 2; i++) { + final receivedPlaintext = await bobCipher.decryptFromSignal( + SignalMessage.fromSerialized(aliceCiphertextMessages[i].serialize())); + assert(eq(receivedPlaintext, alicePlaintextMessages[i])); + } + + final bobCiphertextMessages = []; + final bobPlaintextMessages = []; + + for (var i = 0; i < 20; i++) { + bobPlaintextMessages + .add(Uint8List.fromList(utf8.encode('смерть за смерть $i'))); + bobCiphertextMessages.add(await bobCipher + .encrypt(Uint8List.fromList(utf8.encode('смерть за смерть $i')))); + } + + seed = DateTime.now().millisecondsSinceEpoch; + + bobCiphertextMessages.shuffle(Random(seed)); + bobPlaintextMessages.shuffle(Random(seed)); + + for (var i = 0; i < bobCiphertextMessages.length / 2; i++) { + final receivedPlaintext = await aliceCipher.decryptFromSignal( + SignalMessage.fromSerialized(bobCiphertextMessages[i].serialize())); + assert(eq(receivedPlaintext, bobPlaintextMessages[i])); + } + + for (var i = aliceCiphertextMessages.length ~/ 2; + i < aliceCiphertextMessages.length; + i++) { + final receivedPlaintext = await bobCipher.decryptFromSignal( + SignalMessage.fromSerialized(aliceCiphertextMessages[i].serialize())); + assert(eq(receivedPlaintext, alicePlaintextMessages[i])); + } + + for (var i = bobCiphertextMessages.length ~/ 2; + i < bobCiphertextMessages.length; + i++) { + final receivedPlaintext = await aliceCipher.decryptFromSignal( + SignalMessage.fromSerialized(bobCiphertextMessages[i].serialize())); + assert(eq(receivedPlaintext, bobPlaintextMessages[i])); + } + } + + Future initializeSessionsV3( + SessionState aliceSessionState, SessionState bobSessionState) async { + final aliceIdentityKeyPair = Curve.generateKeyPair(); + final aliceIdentityKey = IdentityKeyPair( + IdentityKey(aliceIdentityKeyPair.publicKey), + aliceIdentityKeyPair.privateKey); + final aliceBaseKey = Curve.generateKeyPair(); + // ignore: unused_local_variable + final aliceEphemeralKey = Curve.generateKeyPair(); + + // ignore: unused_local_variable + final alicePreKey = aliceBaseKey; + + final bobIdentityKeyPair = Curve.generateKeyPair(); + final bobIdentityKey = IdentityKeyPair( + IdentityKey(bobIdentityKeyPair.publicKey), + bobIdentityKeyPair.privateKey); + final bobBaseKey = Curve.generateKeyPair(); + final bobEphemeralKey = bobBaseKey; + + // ignore: unused_local_variable + final bobPreKey = Curve.generateKeyPair(); + + final aliceParameters = AliceSignalProtocolParameters( + ourBaseKey: aliceBaseKey, + ourIdentityKey: aliceIdentityKey, + theirOneTimePreKey: const Optional.empty(), + theirRatchetKey: bobEphemeralKey.publicKey, + theirSignedPreKey: bobBaseKey.publicKey, + theirIdentityKey: bobIdentityKey.getPublicKey(), + ); + + final bobParameters = BobSignalProtocolParameters( + ourRatchetKey: bobEphemeralKey, + ourSignedPreKey: bobBaseKey, + ourOneTimePreKey: const Optional.empty(), + ourIdentityKey: bobIdentityKey, + theirIdentityKey: aliceIdentityKey.getPublicKey(), + theirBaseKey: aliceBaseKey.publicKey, + ); + + RatchetingSession.initializeSessionAlice( + aliceSessionState, aliceParameters); + RatchetingSession.initializeSessionBob(bobSessionState, bobParameters); + } + + test('testBasicSessionV3', () async { + final aliceSessionRecord = SessionRecord(); + final bobSessionRecord = SessionRecord(); + + await initializeSessionsV3( + aliceSessionRecord.sessionState, bobSessionRecord.sessionState); + await runInteraction(aliceSessionRecord, bobSessionRecord); + }); + + test('testMessageKeyLimits', () async { + final aliceSessionRecord = SessionRecord(); + final bobSessionRecord = SessionRecord(); + + await initializeSessionsV3( + aliceSessionRecord.sessionState, bobSessionRecord.sessionState); + + final aliceStore = TestInMemorySignalProtocolStore(); + final bobStore = TestInMemorySignalProtocolStore(); + + await aliceStore.storeSession( + const SignalProtocolAddress('+14159999999', 1), aliceSessionRecord); + await bobStore.storeSession( + const SignalProtocolAddress('+14158888888', 1), bobSessionRecord); + + final aliceCipher = SessionCipher.fromStore( + aliceStore, const SignalProtocolAddress('+14159999999', 1)); + final bobCipher = SessionCipher.fromStore( + bobStore, const SignalProtocolAddress('+14158888888', 1)); + + final inflight = []; + + for (var i = 0; i < 2010; i++) { + inflight.add(await aliceCipher.encrypt(Uint8List.fromList(utf8 + .encode("you've never been so hungry, you've never been so cold")))); + } + + await bobCipher.decryptFromSignal( + SignalMessage.fromSerialized(inflight[1000].serialize())); + await bobCipher.decryptFromSignal(SignalMessage.fromSerialized( + inflight[inflight.length - 1].serialize())); + + try { + await bobCipher.decryptFromSignal( + SignalMessage.fromSerialized(inflight[0].serialize())); + throw AssertionError('Should have failed!'); + } on DuplicateMessageException { + // good + } + }); + + test('testOutOfOrder', () async { + final aliceSessionRecord = SessionRecord(); + final bobSessionRecord = SessionRecord(); + + await initializeSessionsV3( + aliceSessionRecord.sessionState, bobSessionRecord.sessionState); + + final aliceStore = TestInMemorySignalProtocolStore(); + final bobStore = TestInMemorySignalProtocolStore(); + + await aliceStore.storeSession( + const SignalProtocolAddress('+14159999999', 1), aliceSessionRecord); + await bobStore.storeSession( + const SignalProtocolAddress('+14158888888', 1), bobSessionRecord); + + final aliceCipher = SessionCipher.fromStore( + aliceStore, const SignalProtocolAddress('+14159999999', 1)); + final bobCipher = SessionCipher.fromStore( + bobStore, const SignalProtocolAddress('+14158888888', 1)); + + final inflight = []; + + for (var i = 0; i < 2000; i++) { + inflight.add(await aliceCipher + .encrypt(Uint8List.fromList(utf8.encode('up the punks')))); + } + + while (inflight.isNotEmpty) { + final index = randomInt() % inflight.length; + final ciphertext = inflight.removeAt(index); + final plaintext = await bobCipher.decryptFromSignal( + SignalMessage.fromSerialized(ciphertext.serialize())); + + assert(utf8.decode(plaintext) == 'up the punks'); + } + }); +} diff --git a/libsignal_protocol_dart/test/state/impl/in_memory_identity_key_store_test.dart b/libsignal_protocol_dart/test/state/impl/in_memory_identity_key_store_test.dart new file mode 100644 index 0000000..f2faa1e --- /dev/null +++ b/libsignal_protocol_dart/test/state/impl/in_memory_identity_key_store_test.dart @@ -0,0 +1,42 @@ +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:libsignal_protocol_dart/src/identity_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/signal_protocol_address.dart'; +import 'package:libsignal_protocol_dart/src/state/impl/in_memory_identity_key_store.dart'; +import 'package:libsignal_protocol_dart/src/util/key_helper.dart'; +import 'package:test/test.dart'; + +void main() { + test('should implement interface successfully', () async { + final keyPair = Curve.generateKeyPair(); + final identityKey = IdentityKey(keyPair.publicKey); + final identityKeyPair = IdentityKeyPair(identityKey, keyPair.privateKey); + final registrationId = generateRegistrationId(false); + final store = InMemoryIdentityKeyStore(identityKeyPair, registrationId); + const address = SignalProtocolAddress('address-1', 123); + + // getIdentityKeyPair + expect(await store.getIdentityKeyPair(), identityKeyPair); + + // getLocalRegistrationId + expect(await store.getLocalRegistrationId(), registrationId); + + // getIdentity + // TODO + // expect(store.getIdentity(address), null); + + // saveIdentity & getIdentity + expect(await store.saveIdentity(address, identityKey), true); + expect( + await store.getIdentity(address).then((value) => value?.getFingerprint()), + identityKey.getFingerprint(), + ); + expect(await store.saveIdentity(address, identityKey), false); + + // isTrustedIdentity + expect(await store.isTrustedIdentity(address, identityKey, null), true); + // expect(store.isTrustedIdentity(null, identityKey, null), true); + final newIdentityKey = IdentityKey(Curve.generateKeyPair().publicKey); + expect(await store.isTrustedIdentity(address, newIdentityKey, null), false); + }); +} diff --git a/libsignal_protocol_dart/test/state/impl/in_memory_pre_key_store_test.dart b/libsignal_protocol_dart/test/state/impl/in_memory_pre_key_store_test.dart new file mode 100644 index 0000000..6640ae7 --- /dev/null +++ b/libsignal_protocol_dart/test/state/impl/in_memory_pre_key_store_test.dart @@ -0,0 +1,26 @@ +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:test/test.dart'; + +void main() { + test('should implement interface successfully', () async { + final store = InMemoryPreKeyStore(); + final preKeys = generatePreKeys(1, 2); + + // storePreKey + await store.storePreKey(1, preKeys[0]); + await store.storePreKey(2, preKeys[1]); + + // containsPreKey + expect(await store.containsPreKey(1), true); + expect(await store.containsPreKey(2), true); + expect(await store.containsPreKey(3), false); + + // loadPreKey + expect(await store.loadPreKey(2).then((value) => value.serialize()), + preKeys[1].serialize()); + + // removePreKey & loadPreKey + await store.removePreKey(2); + expect(() => store.loadPreKey(2), throwsA(isA())); + }); +} diff --git a/libsignal_protocol_dart/test/state/impl/in_memory_session_store_test.dart b/libsignal_protocol_dart/test/state/impl/in_memory_session_store_test.dart new file mode 100644 index 0000000..07cc867 --- /dev/null +++ b/libsignal_protocol_dart/test/state/impl/in_memory_session_store_test.dart @@ -0,0 +1,48 @@ +import 'package:collection/collection.dart'; +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:test/test.dart'; + +void main() { + test('should implement interface successfully', () async { + const address1 = SignalProtocolAddress('address-1', 123); + const address2a = SignalProtocolAddress('address-2', 123); + const address2b = SignalProtocolAddress('address-2', 456); + final store = InMemorySessionStore(); + + // containsSession & loadSession + expect(await store.containsSession(address1), false); + final sessionRecord1 = await store.loadSession(address1); + await store.storeSession(address1, sessionRecord1); + expect(await store.containsSession(address1), true); + + // loadSession & storeSession + final sessionRecord2 = await store.loadSession(address1); + await store.storeSession(address2a, sessionRecord2); + await store.storeSession(address2b, sessionRecord2); + + // getSubDeviceSessions + final subDeviceSessions1 = + await store.getSubDeviceSessions(address1.getName()); + expect(subDeviceSessions1.length, 1); + expect(subDeviceSessions1, [123]); + final subDeviceSessions2 = + await store.getSubDeviceSessions(address2a.getName()); + expect(subDeviceSessions2.length, 2); + expect( + const SetEquality().equals( + subDeviceSessions2.toSet(), + {123, 456}.toSet(), + ), + true); + + // deleteSession & containsSession + expect(await store.containsSession(address2a), true); + await store.deleteSession(address2a); + expect(await store.containsSession(address2a), false); + + // deleteAllSessions & containsSession + expect(await store.containsSession(address2b), true); + await store.deleteAllSessions(address2b.getName()); + expect(await store.containsSession(address2b), false); + }); +} diff --git a/libsignal_protocol_dart/test/state/impl/in_memory_signal_protocol_store_test.dart b/libsignal_protocol_dart/test/state/impl/in_memory_signal_protocol_store_test.dart new file mode 100644 index 0000000..70a7301 --- /dev/null +++ b/libsignal_protocol_dart/test/state/impl/in_memory_signal_protocol_store_test.dart @@ -0,0 +1,104 @@ +import 'dart:convert'; +import 'dart:typed_data'; +import 'package:fixnum/fixnum.dart'; +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:test/test.dart'; + +import '../../test_in_memory_signal_protocol_store.dart'; + +void main() { + test('should encrypt/decrypt message from Alice, to Bob and back again', + () async { + final aliceStore = TestInMemorySignalProtocolStore(); + final bobStore = TestInMemorySignalProtocolStore(); + const msgOrig = "L'homme est condamné à être libre"; + + const aliceAddress = SignalProtocolAddress('alice', 1); + const bobAddress = SignalProtocolAddress('bob', 1); + + // Bob creates his keys to store locally and to publish public to cloud + final bobPreKeyPair = Curve.generateKeyPair(); + final bobSignedPreKeyPair = Curve.generateKeyPair(); + final bobSignedPreKeySignature = Curve.calculateSignature( + await bobStore + .getIdentityKeyPair() + .then((value) => value.getPrivateKey()), + bobSignedPreKeyPair.publicKey.serialize(), + ); + + // + // Alice to encrypt and send to Bob... + // + + // Pretend that Alice has downloaded Bob's pre key bundle from the cloud + final bobPreKey = PreKeyBundle( + await bobStore.getLocalRegistrationId(), + 1, + 31337, + bobPreKeyPair.publicKey, + 22, + bobSignedPreKeyPair.publicKey, + bobSignedPreKeySignature, + await bobStore.getIdentityKeyPair().then((value) => value.getPublicKey()), + ); + + await SessionBuilder.fromSignalStore(aliceStore, bobAddress) + .processPreKeyBundle(bobPreKey); + + final aliceSessionCipher = SessionCipher.fromStore(aliceStore, bobAddress); + final msgAliceToBob = await aliceSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(msgOrig))); + + // Pretend that Alice has now sent the message to Bob + + // + // Bob to decrypt... + // + + await bobStore.storePreKey( + 31337, + PreKeyRecord(bobPreKey.getPreKeyId()!, bobPreKeyPair), + ); + await bobStore.storeSignedPreKey( + 22, + SignedPreKeyRecord( + 22, + Int64(DateTime.now().millisecondsSinceEpoch), + bobSignedPreKeyPair, + bobSignedPreKeySignature, + ), + ); + + final msgIn = PreKeySignalMessage(msgAliceToBob.serialize()); + expect( + msgIn.getType(), + CiphertextMessage.prekeyType, + ); + + final bobSessionCipher = SessionCipher.fromStore(bobStore, aliceAddress); + var msgDecrypted = await bobSessionCipher.decrypt(msgIn); + var msgDecoded = utf8.decode(msgDecrypted, allowMalformed: true); + expect(msgDecoded, msgOrig); + + // + // Bob to encrypt and send to Alice... + // + + final msgBobToAlice = await bobSessionCipher + .encrypt(Uint8List.fromList(utf8.encode(msgDecoded))); + expect( + msgBobToAlice.getType(), + CiphertextMessage.whisperType, + ); + + // + // Alice to decrypt... + // + + msgDecrypted = await aliceSessionCipher.decryptFromSignal( + SignalMessage.fromSerialized(msgBobToAlice.serialize()), + ); + msgDecoded = utf8.decode(msgDecrypted, allowMalformed: true); + expect(msgDecoded, msgOrig); + }); +} diff --git a/libsignal_protocol_dart/test/state/impl/in_memory_signed_pre_key_store_test.dart b/libsignal_protocol_dart/test/state/impl/in_memory_signed_pre_key_store_test.dart new file mode 100644 index 0000000..01e6594 --- /dev/null +++ b/libsignal_protocol_dart/test/state/impl/in_memory_signed_pre_key_store_test.dart @@ -0,0 +1,41 @@ +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:test/test.dart'; + +void main() { + test('should implement interface successfully', () async { + final store = InMemorySignedPreKeyStore(); + final signedPreKeyRecord1 = _generateSignedPreKey(1); + final signedPreKeyRecord2 = _generateSignedPreKey(2); + + // storeSignedPreKey + await store.storeSignedPreKey(1, signedPreKeyRecord1); + await store.storeSignedPreKey(2, signedPreKeyRecord2); + + // containsSignedPreKey + expect(await store.containsSignedPreKey(1), true); + expect(await store.containsSignedPreKey(2), true); + expect(await store.containsSignedPreKey(3), false); + + // loadSignedPreKey + expect(await store.loadSignedPreKey(1).then((value) => value.id), 1); + expect(await store.loadSignedPreKey(2).then((value) => value.id), 2); + + // loadSignedPreKey + expect(() => store.loadSignedPreKey(10), + throwsA(isA())); + + // loadSignedPreKeys + final signedPreKeys = await store.loadSignedPreKeys(); + expect(signedPreKeys.length, 2); + expect(signedPreKeys[0].id, 1); + expect(signedPreKeys[1].id, 2); + + // removeSignedPreKey & containsSignedPreKey + await store.removeSignedPreKey(1); + expect(await store.containsSignedPreKey(1), false); + expect(await store.containsSignedPreKey(2), true); + }); +} + +SignedPreKeyRecord _generateSignedPreKey(int signedPreKeyId) => + generateSignedPreKey(generateIdentityKeyPair(), signedPreKeyId); diff --git a/libsignal_protocol_dart/test/test_in_memory_identity_key_store.dart b/libsignal_protocol_dart/test/test_in_memory_identity_key_store.dart new file mode 100644 index 0000000..f03062d --- /dev/null +++ b/libsignal_protocol_dart/test/test_in_memory_identity_key_store.dart @@ -0,0 +1,19 @@ +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:libsignal_protocol_dart/src/identity_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/state/impl/in_memory_identity_key_store.dart'; +import 'package:libsignal_protocol_dart/src/util/key_helper.dart'; + +class TestInMemoryIdentityKeyStore extends InMemoryIdentityKeyStore { + TestInMemoryIdentityKeyStore() + : super(_generateIdentityKeyPair(), _generateRegistrationId()); + + static IdentityKeyPair _generateIdentityKeyPair() { + final identityKeyPairKeys = Curve.generateKeyPair(); + + return IdentityKeyPair(IdentityKey(identityKeyPairKeys.publicKey), + identityKeyPairKeys.privateKey); + } + + static int _generateRegistrationId() => generateRegistrationId(false); +} diff --git a/libsignal_protocol_dart/test/test_in_memory_signal_protocol_store.dart b/libsignal_protocol_dart/test/test_in_memory_signal_protocol_store.dart new file mode 100644 index 0000000..f5c3cce --- /dev/null +++ b/libsignal_protocol_dart/test/test_in_memory_signal_protocol_store.dart @@ -0,0 +1,19 @@ +import 'package:libsignal_protocol_dart/src/ecc/curve.dart'; +import 'package:libsignal_protocol_dart/src/identity_key.dart'; +import 'package:libsignal_protocol_dart/src/identity_key_pair.dart'; +import 'package:libsignal_protocol_dart/src/state/impl/in_memory_signal_protocol_store.dart'; +import 'package:libsignal_protocol_dart/src/util/key_helper.dart'; + +class TestInMemorySignalProtocolStore extends InMemorySignalProtocolStore { + TestInMemorySignalProtocolStore() + : super(_generateIdentityKeyPair(), _generateRegistrationId()); + + static IdentityKeyPair _generateIdentityKeyPair() { + final identityKeyPairKeys = Curve.generateKeyPair(); + + return IdentityKeyPair(IdentityKey(identityKeyPairKeys.publicKey), + identityKeyPairKeys.privateKey); + } + + static int _generateRegistrationId() => generateRegistrationId(false); +} diff --git a/libsignal_protocol_dart/test/util/byte_util_test.dart b/libsignal_protocol_dart/test/util/byte_util_test.dart new file mode 100644 index 0000000..69f3a22 --- /dev/null +++ b/libsignal_protocol_dart/test/util/byte_util_test.dart @@ -0,0 +1,113 @@ +import 'dart:typed_data'; + +import 'package:libsignal_protocol_dart/src/util/byte_util.dart'; +import 'package:test/test.dart'; + +void main() { + test('ByteUtil.combime() combile multi Uintlist8 into 1', () { + final first = Uint8List.fromList([1]); + final second = Uint8List.fromList([2, 3]); + final third = Uint8List.fromList([4, 5]); + final other = Uint8List.fromList([1, 2, 3, 4, 5]); + expect(ByteUtil.combine([first, second, third]), other); + }); + + test('ByteUtil.shortToByteArray() convert short to UintList8', () { + const value1 = 100; + expect(ByteUtil.shortToByteArray(value1), Uint8List.fromList([0, 100])); + const value2 = 1024; + expect(ByteUtil.shortToByteArray(value2), Uint8List.fromList([4, 1024])); + }); + + test('ByteUtil.intToByteArray() convert int to UintList8', () { + const value1 = 100; + expect(ByteUtil.intToByteArray(value1), Uint8List.fromList([0, 0, 0, 100])); + const value2 = 1024; + expect(ByteUtil.intToByteArray(value2), Uint8List.fromList([0, 0, 4, 0])); + }); + + test('ByteUtil.trim() sublist Uint8List from 0 to specification length', () { + final input = Uint8List.fromList([1, 2, 3, 4, 5]); + expect(ByteUtil.trim(input, 3), Uint8List.fromList([1, 2, 3])); + expect(ByteUtil.trim(input, 0), Uint8List.fromList([])); + }); + + test('ByteUtil.split() splits the string to three length', () { + final input = Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + final first = Uint8List.fromList([1]); + final second = Uint8List.fromList([2, 3]); + final third = Uint8List.fromList([4, 5, 6, 7, 8, 9]); + expect(ByteUtil.split(input, 1, 2, 6), [first, second, third]); + }); + + test('ByteUtil.splitTwo() splits the string to two length', () { + final input = Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + final first = Uint8List.fromList([1]); + final second = Uint8List.fromList([2, 3, 4, 5, 6, 7]); + expect(ByteUtil.splitTwo(input, 1, 6), [first, second]); + }); + + test('String.trim() removes surrounding whitespace', () { + const string = ' foo '; + expect(string.trim(), equals('foo')); + }); + + test('ByteUtil.intsToByteHighAndLow()', () { + const highValue1 = 4; + const lowValue1 = 2; + expect(ByteUtil.intsToByteHighAndLow(highValue1, lowValue1), 66); + const highValue2 = 2; + const lowValue2 = 4; + expect(ByteUtil.intsToByteHighAndLow(highValue2, lowValue2), 36); + const highValue3 = 3; + const lowValue3 = 3; + expect(ByteUtil.intsToByteHighAndLow(highValue3, lowValue3), 51); + }); + + test('ByteUtil.highBitsToInt', () { + const int1 = 16; + expect(ByteUtil.highBitsToInt(int1), 1); + const int2 = 35; + expect(ByteUtil.highBitsToInt(int2), 2); + const int3 = 100; + expect(ByteUtil.highBitsToInt(int3), 6); + }); + + test('ByteUtil.lowBitsToInt', () { + const int1 = 16; + expect(ByteUtil.lowBitsToInt(int1), 0); + const int2 = 35; + expect(ByteUtil.lowBitsToInt(int2), 3); + const int3 = 100; + expect(ByteUtil.lowBitsToInt(int3), 4); + }); + + test('ByteUtil.highBitsToMedium', () { + const int1 = 16; + expect(ByteUtil.highBitsToMedium(int1), 0); + const int2 = 35; + expect(ByteUtil.highBitsToMedium(int2), 0); + const int3 = 100; + expect(ByteUtil.highBitsToMedium(int3), 0); + const int4 = 10000; + expect(ByteUtil.highBitsToMedium(int4), 2); + }); + + test('ByteUtil.lowBitsToMedium', () { + const int1 = 16; + expect(ByteUtil.lowBitsToMedium(int1), 16); + const int2 = 35; + expect(ByteUtil.lowBitsToMedium(int2), 35); + const int3 = 100; + expect(ByteUtil.lowBitsToMedium(int3), 100); + const int4 = 10000; + expect(ByteUtil.lowBitsToMedium(int4), 1808); + }); + + test('ByteUtil.byteArray5ToLong', () { + // ignore: unused_local_variable + final input = Uint8List.fromList( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + // TODO + }); +} diff --git a/lottie/LICENSE b/lottie/LICENSE new file mode 100644 index 0000000..8aa2645 --- /dev/null +++ b/lottie/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lottie/lib/lottie.dart b/lottie/lib/lottie.dart new file mode 100644 index 0000000..728031e --- /dev/null +++ b/lottie/lib/lottie.dart @@ -0,0 +1,19 @@ +export 'src/composition.dart' show LottieComposition, LottieDecoder; +export 'src/frame_rate.dart' show FrameRate; +export 'src/lottie.dart' show Lottie; +export 'src/lottie_builder.dart' show LottieBuilder; +export 'src/lottie_delegates.dart' show LottieDelegates; +export 'src/lottie_drawable.dart' show LottieDrawable, LottieFontStyle; +export 'src/lottie_image_asset.dart' show LottieImageAsset; +export 'src/model/marker.dart' show Marker; +export 'src/options.dart' show LottieOptions; +export 'src/providers/asset_provider.dart' show AssetLottie; +export 'src/providers/file_provider.dart' show FileLottie; +export 'src/providers/load_image.dart' show LottieImageProviderFactory; +export 'src/providers/lottie_provider.dart' show LottieCache, LottieProvider; +export 'src/providers/memory_provider.dart' show MemoryLottie; +export 'src/providers/network_provider.dart' show NetworkLottie; +export 'src/raw_lottie.dart' show RawLottie; +export 'src/render_cache.dart' show RenderCache; +export 'src/value/drop_shadow.dart' show DropShadow; +export 'src/value_delegate.dart' show ValueDelegate; diff --git a/lottie/lib/src/animation/content/base_stroke_content.dart b/lottie/lib/src/animation/content/base_stroke_content.dart new file mode 100644 index 0000000..789657d --- /dev/null +++ b/lottie/lib/src/animation/content/base_stroke_content.dart @@ -0,0 +1,424 @@ +import 'dart:math'; +import 'dart:ui'; +import 'package:flutter/foundation.dart'; +import 'package:vector_math/vector_math_64.dart'; +import '../../l.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/animatable/animatable_double_value.dart'; +import '../../model/animatable/animatable_integer_value.dart'; +import '../../model/content/drop_shadow_effect.dart'; +import '../../model/content/shape_trim_path.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../utils/dash_path.dart'; +import '../../utils/misc.dart'; +import '../../utils/utils.dart'; +import '../../value/drop_shadow.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import '../keyframe/drop_shadow_keyframe_animation.dart'; +import '../keyframe/value_callback_keyframe_animation.dart'; +import 'content.dart'; +import 'drawing_content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; +import 'trim_path_content.dart'; + +abstract class BaseStrokeContent + implements KeyPathElementContent, DrawingContent { + final Path _path = Path(); + final Path _trimPathPath = Path(); + final LottieDrawable lottieDrawable; + final BaseLayer layer; + final List<_PathGroup> _pathGroups = <_PathGroup>[]; + final List _dashPatternValues; + final Paint paint = Paint()..style = PaintingStyle.stroke; + + final BaseKeyframeAnimation _widthAnimation; + final BaseKeyframeAnimation _opacityAnimation; + final List> _dashPatternAnimations; + final BaseKeyframeAnimation? _dashPatternOffsetAnimation; + BaseKeyframeAnimation? _colorFilterAnimation; + BaseKeyframeAnimation? _blurAnimation; + double _blurMaskFilterRadius = 0; + DropShadowKeyframeAnimation? dropShadowAnimation; + + BaseStrokeContent( + this.lottieDrawable, + this.layer, { + required StrokeCap cap, + required StrokeJoin join, + required double miterLimit, + required AnimatableIntegerValue opacity, + required AnimatableDoubleValue width, + required List dashPattern, + AnimatableDoubleValue? dashOffset, + }) : _widthAnimation = width.createAnimation(), + _opacityAnimation = opacity.createAnimation(), + _dashPatternOffsetAnimation = dashOffset?.createAnimation(), + _dashPatternAnimations = dashPattern + .map((d) => d.createAnimation()) + .toList(), + _dashPatternValues = List.filled(dashPattern.length, 0.0) { + paint + ..strokeCap = cap + ..strokeJoin = join + ..strokeMiterLimit = miterLimit; + + layer.addAnimation(_opacityAnimation); + layer.addAnimation(_widthAnimation); + for (var i = 0; i < _dashPatternAnimations.length; i++) { + layer.addAnimation(_dashPatternAnimations[i]); + } + if (_dashPatternOffsetAnimation != null) { + layer.addAnimation(_dashPatternOffsetAnimation); + } + + _opacityAnimation.addUpdateListener(onUpdateListener); + _widthAnimation.addUpdateListener(onUpdateListener); + + for (var i = 0; i < dashPattern.length; i++) { + _dashPatternAnimations[i].addUpdateListener(onUpdateListener); + } + if (_dashPatternOffsetAnimation != null) { + _dashPatternOffsetAnimation.addUpdateListener(onUpdateListener); + } + var blurEffect = layer.blurEffect; + if (blurEffect != null) { + _blurAnimation = blurEffect.blurriness.createAnimation() + ..addUpdateListener(onUpdateListener); + layer.addAnimation(_blurAnimation); + } + var dropShadowEffect = layer.dropShadowEffect; + if (dropShadowEffect != null) { + dropShadowAnimation = DropShadowKeyframeAnimation( + onUpdateListener, + layer, + dropShadowEffect, + ); + } + } + + void onUpdateListener() { + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + TrimPathContent? trimPathContentBefore; + for (var i = contentsBefore.length - 1; i >= 0; i--) { + var content = contentsBefore[i]; + if (content is TrimPathContent && + content.type == ShapeTrimPathType.individually) { + trimPathContentBefore = content; + } + } + if (trimPathContentBefore != null) { + trimPathContentBefore.addListener(onUpdateListener); + } + + _PathGroup? currentPathGroup; + for (var i = contentsAfter.length - 1; i >= 0; i--) { + var content = contentsAfter[i]; + if (content is TrimPathContent && + content.type == ShapeTrimPathType.individually) { + if (currentPathGroup != null) { + _pathGroups.add(currentPathGroup); + } + currentPathGroup = _PathGroup(content); + content.addListener(onUpdateListener); + } else if (content is PathContent) { + currentPathGroup ??= _PathGroup(trimPathContentBefore); + currentPathGroup.paths.add(content); + } + } + if (currentPathGroup != null) { + _pathGroups.add(currentPathGroup); + } + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + L.beginSection('StrokeContent#draw'); + if (parentMatrix.hasZeroScaleAxis) { + L.endSection('StrokeContent#draw'); + return; + } + var alpha = ((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255) + .round(); + paint.setAlpha(alpha.clamp(0, 255)); + paint.strokeWidth = _widthAnimation.value * parentMatrix.getScale(); + if (paint.strokeWidth <= 0) { + // Android draws a hairline stroke for 0, After Effects doesn't. + L.endSection('StrokeContent#draw'); + return; + } + + if (_colorFilterAnimation != null) { + paint.colorFilter = _colorFilterAnimation!.value; + } + + var blurAnimation = _blurAnimation; + if (blurAnimation != null) { + var blurRadius = blurAnimation.value; + if (blurRadius == 0) { + paint.maskFilter = null; + } else if (blurRadius != _blurMaskFilterRadius) { + var blur = layer.getBlurMaskFilter(blurRadius); + paint.maskFilter = blur; + } + _blurMaskFilterRadius = blurRadius; + } + + for (var i = 0; i < _pathGroups.length; i++) { + var pathGroup = _pathGroups[i]; + + if (pathGroup.trimPath != null) { + _applyTrimPath(canvas, pathGroup, parentMatrix); + } else { + L.beginSection('StrokeContent#buildPath'); + _path.reset(); + for (var j = pathGroup.paths.length - 1; j >= 0; j--) { + _path.addPath( + pathGroup.paths[j].getPath(), + Offset.zero, + matrix4: parentMatrix.storage, + ); + } + L.endSection('StrokeContent#buildPath'); + L.beginSection('StrokeContent#drawPath'); + var dropShadow = dropShadowAnimation; + if (dropShadow != null) { + dropShadow.draw(canvas, _path); + } + canvas.drawPath(_withDashPattern(_path, parentMatrix), paint); + L.endSection('StrokeContent#drawPath'); + } + } + L.endSection('StrokeContent#draw'); + } + + void _applyTrimPath( + Canvas canvas, + _PathGroup pathGroup, + Matrix4 parentMatrix, + ) { + L.beginSection('StrokeContent#applyTrimPath'); + var trimPath = pathGroup.trimPath; + if (trimPath == null) { + L.endSection('StrokeContent#applyTrimPath'); + return; + } + _path.reset(); + for (var j = pathGroup.paths.length - 1; j >= 0; j--) { + _path.addPath( + pathGroup.paths[j].getPath(), + Offset.zero, + matrix4: parentMatrix.storage, + ); + } + var animStartValue = trimPath.start.value / 100; + var animEndValue = trimPath.end.value / 100; + var animOffsetValue = trimPath.offset.value / 360; + + // If the start-end is ~100, consider it to be the full path. + if (animStartValue < 0.01 && animEndValue > 0.99) { + canvas.drawPath(_path, paint); + L.endSection('StrokeContent#applyTrimPath'); + return; + } + + var pathMetrics = _path.computeMetrics().toList(); + var totalLength = pathMetrics.fold(0.0, (a, b) => a + b.length); + + var offsetLength = totalLength * animOffsetValue; + var startLength = totalLength * animStartValue + offsetLength; + var endLength = min( + totalLength * animEndValue + offsetLength, + startLength + totalLength - 1, + ); + + var currentLength = 0.0; + for (var j = pathGroup.paths.length - 1; j >= 0; j--) { + _trimPathPath.set( + pathGroup.paths[j].getPath().transform(parentMatrix.storage), + ); + var pathMetrics = _trimPathPath.computeMetrics().toList(); + var length = pathMetrics.isNotEmpty ? pathMetrics.first.length : 0; + if (endLength > totalLength && + endLength - totalLength < currentLength + length && + currentLength < endLength - totalLength) { + // Draw the segment when the end is greater than the length which wraps around to the + // beginning. + double startValue; + if (startLength > totalLength) { + startValue = (startLength - totalLength) / length; + } else { + startValue = 0; + } + var endValue = min((endLength - totalLength) / length, 1).toDouble(); + Utils.applyTrimPathIfNeeded(_trimPathPath, startValue, endValue, 0.0); + canvas.drawPath(_withDashPattern(_trimPathPath, parentMatrix), paint); + } else if (currentLength + length < startLength || + currentLength > endLength) { + // Do nothing + } else if (currentLength + length <= endLength && + startLength < currentLength) { + canvas.drawPath(_withDashPattern(_trimPathPath, parentMatrix), paint); + } else { + double startValue; + if (startLength < currentLength) { + startValue = 0; + } else { + startValue = (startLength - currentLength) / length; + } + double endValue; + if (endLength > currentLength + length) { + endValue = 1.0; + } else { + endValue = (endLength - currentLength) / length; + } + Utils.applyTrimPathIfNeeded(_trimPathPath, startValue, endValue, 0); + canvas.drawPath(_withDashPattern(_trimPathPath, parentMatrix), paint); + } + currentLength += length; + } + L.endSection('StrokeContent#applyTrimPath'); + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + L.beginSection('StrokeContent#getBounds'); + _path.reset(); + for (var i = 0; i < _pathGroups.length; i++) { + var pathGroup = _pathGroups[i]; + for (var j = 0; j < pathGroup.paths.length; j++) { + _path.addPath( + pathGroup.paths[j].getPath(), + Offset.zero, + matrix4: parentMatrix.storage, + ); + } + } + var bounds = _path.getBounds(); + + var width = _widthAnimation.value; + bounds = bounds.inflate(width / 2.0); + // Add padding to account for rounding errors. + bounds = bounds.inflate(1); + L.endSection('StrokeContent#getBounds'); + return bounds; + } + + Path _withDashPattern(Path path, Matrix4 parentMatrix) { + L.beginSection('StrokeContent#applyDashPattern'); + if (_dashPatternAnimations.isEmpty) { + L.endSection('StrokeContent#applyDashPattern'); + return path; + } + + var scale = parentMatrix.getScale(); + for (var i = 0; i < _dashPatternAnimations.length; i++) { + _dashPatternValues[i] = _dashPatternAnimations[i].value; + // If the value of the dash pattern or gap is too small, the number of individual sections + // approaches infinity as the value approaches 0. + // To mitigate this, we essentially put a minimum value on the dash pattern size of 1px + // and a minimum gap size of 0.01. + if (i % 2 == 0) { + if (_dashPatternValues[i] < 1.0) { + _dashPatternValues[i] = 1.0; + } + } else { + if (_dashPatternValues[i] < 0.1) { + _dashPatternValues[i] = 0.1; + } + } + _dashPatternValues[i] *= scale; + } + + var offset = _dashPatternOffsetAnimation == null + ? 0.0 + : _dashPatternOffsetAnimation.value * scale; + var newPath = dashPath(path, intervals: _dashPatternValues, phase: offset); + L.endSection('StrokeContent#applyDashPattern'); + + return newPath; + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + @mustCallSuper + void addValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.opacity) { + _opacityAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.strokeWidth) { + _widthAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.colorFilter) { + if (_colorFilterAnimation != null) { + layer.removeAnimation(_colorFilterAnimation); + } + + if (callback == null) { + _colorFilterAnimation = null; + } else { + _colorFilterAnimation = + ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + )..addUpdateListener(onUpdateListener); + layer.addAnimation(_colorFilterAnimation); + } + } else if (property == LottieProperty.blurRadius) { + var blurAnimation = _blurAnimation; + if (blurAnimation != null) { + blurAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else { + _blurAnimation = blurAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + 0, + )..addUpdateListener(onUpdateListener); + layer.addAnimation(blurAnimation); + } + } else if (property == LottieProperty.dropShadow) { + var dropShadowAnimation = this.dropShadowAnimation; + if (dropShadowAnimation == null) { + var effect = DropShadowEffect.createEmpty(); + this.dropShadowAnimation = dropShadowAnimation = dropShadowAnimation = + DropShadowKeyframeAnimation(onUpdateListener, layer, effect); + } + + dropShadowAnimation.setCallback( + callback as LottieValueCallback?, + ); + } + } +} + +/// Data class to help drawing trim paths individually. +class _PathGroup { + final List paths = []; + final TrimPathContent? trimPath; + + _PathGroup(this.trimPath); +} diff --git a/lottie/lib/src/animation/content/compound_trim_path_content.dart b/lottie/lib/src/animation/content/compound_trim_path_content.dart new file mode 100644 index 0000000..4437084 --- /dev/null +++ b/lottie/lib/src/animation/content/compound_trim_path_content.dart @@ -0,0 +1,17 @@ +import 'dart:ui'; +import '../../utils/utils.dart'; +import 'trim_path_content.dart'; + +class CompoundTrimPathContent { + final List _contents = []; + + void addTrimPath(TrimPathContent trimPath) { + _contents.add(trimPath); + } + + void apply(Path path) { + for (var i = _contents.length - 1; i >= 0; i--) { + Utils.applyTrimPathContentIfNeeded(path, _contents[i]); + } + } +} diff --git a/lottie/lib/src/animation/content/content.dart b/lottie/lib/src/animation/content/content.dart new file mode 100644 index 0000000..8efbacf --- /dev/null +++ b/lottie/lib/src/animation/content/content.dart @@ -0,0 +1,5 @@ +abstract class Content { + String? get name; + + void setContents(List contentsBefore, List contentsAfter); +} diff --git a/lottie/lib/src/animation/content/content_group.dart b/lottie/lib/src/animation/content/content_group.dart new file mode 100644 index 0000000..53cd36a --- /dev/null +++ b/lottie/lib/src/animation/content/content_group.dart @@ -0,0 +1,271 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_drawable.dart'; +import '../../model/animatable/animatable_transform.dart'; +import '../../model/content/content_model.dart'; +import '../../model/content/shape_group.dart'; +import '../../model/key_path.dart'; +import '../../model/key_path_element.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/transform_keyframe_animation.dart'; +import 'content.dart'; +import 'drawing_content.dart'; +import 'greedy_content.dart'; +import 'path_content.dart'; + +class ContentGroup implements DrawingContent, PathContent, KeyPathElement { + final Paint _offScreenPaint = Paint(); + + static List contentsFromModels( + LottieDrawable drawable, + BaseLayer layer, + List contentModels, + ) { + var contents = []; + for (var i = 0; i < contentModels.length; i++) { + var content = contentModels[i].toContent(drawable, layer); + if (content != null) { + contents.add(content); + } + } + return contents; + } + + static AnimatableTransform? findTransform(List contentModels) { + for (var i = 0; i < contentModels.length; i++) { + var contentModel = contentModels[i]; + if (contentModel is AnimatableTransform) { + return contentModel; + } + } + return null; + } + + final Matrix4 _matrix = Matrix4.identity(); + final Path _path = Path(); + + @override + final String? name; + final bool _hidden; + final List _contents; + final LottieDrawable _lottieDrawable; + List? _pathContents; + TransformKeyframeAnimation? _transformAnimation; + + ContentGroup( + LottieDrawable lottieDrawable, + BaseLayer layer, + ShapeGroup shapeGroup, + ) : this.copy( + lottieDrawable, + layer, + shapeGroup.name, + contentsFromModels(lottieDrawable, layer, shapeGroup.items), + findTransform(shapeGroup.items), + hidden: shapeGroup.hidden, + ); + + ContentGroup.copy( + this._lottieDrawable, + BaseLayer layer, + this.name, + this._contents, + AnimatableTransform? transform, { + required bool hidden, + }) : _hidden = hidden { + if (transform != null) { + _transformAnimation = transform.createAnimation() + ..addAnimationsToLayer(layer) + ..addListener(onValueChanged); + } + + var greedyContents = []; + for (var i = _contents.length - 1; i >= 0; i--) { + var content = _contents[i]; + if (content is GreedyContent) { + greedyContents.add(content as GreedyContent); + } + } + + for (var i = greedyContents.length - 1; i >= 0; i--) { + greedyContents[i].absorbContent(_contents); + } + } + + void onValueChanged() { + _lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + // Do nothing with contents after. + var myContentsBefore = []; + myContentsBefore.addAll(contentsBefore); + + for (var i = _contents.length - 1; i >= 0; i--) { + var content = _contents[i]; + content.setContents(myContentsBefore, _contents.sublist(0, i)); + myContentsBefore.add(content); + } + } + + List getPathList() { + if (_pathContents == null) { + var pathContents = _pathContents = []; + for (var i = 0; i < _contents.length; i++) { + var content = _contents[i]; + if (content is PathContent) { + pathContents.add(content); + } + } + } + return _pathContents!; + } + + Matrix4 getTransformationMatrix() { + if (_transformAnimation != null) { + return _transformAnimation!.getMatrix(); + } + _matrix.reset(); + return _matrix; + } + + @override + Path getPath() { + // TODO: cache this somehow. + _matrix.reset(); + if (_transformAnimation != null) { + _matrix.set(_transformAnimation!.getMatrix()); + } + _path.reset(); + if (_hidden) { + return _path; + } + for (var i = _contents.length - 1; i >= 0; i--) { + var content = _contents[i]; + if (content is PathContent) { + _path.addPath(content.getPath(), Offset.zero, matrix4: _matrix.storage); + } + } + return _path; + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + if (_hidden) { + return; + } + _matrix.set(parentMatrix); + int layerAlpha; + if (_transformAnimation != null) { + _matrix.preConcat(_transformAnimation!.getMatrix()); + var opacity = _transformAnimation?.opacity == null + ? 100 + : _transformAnimation!.opacity!.value; + layerAlpha = ((opacity / 100.0 * parentAlpha / 255.0) * 255).round(); + } else { + layerAlpha = parentAlpha; + } + + // Apply off-screen rendering only when needed in order to improve rendering performance. + var isRenderingWithOffScreen = + _lottieDrawable.isApplyingOpacityToLayersEnabled && + hasTwoOrMoreDrawableContent() && + layerAlpha != 255; + if (isRenderingWithOffScreen) { + var offScreenRect = getBounds(_matrix, applyParents: true); + _offScreenPaint.setAlpha(layerAlpha); + canvas.saveLayer(offScreenRect, _offScreenPaint); + } + + var childAlpha = isRenderingWithOffScreen ? 255 : layerAlpha; + for (var i = _contents.length - 1; i >= 0; i--) { + Object content = _contents[i]; + if (content is DrawingContent) { + content.draw(canvas, _matrix, parentAlpha: childAlpha); + } + } + + if (isRenderingWithOffScreen) { + canvas.restore(); + } + } + + bool hasTwoOrMoreDrawableContent() { + var drawableContentCount = 0; + for (var i = 0; i < _contents.length; i++) { + if (_contents[i] is DrawingContent) { + drawableContentCount += 1; + if (drawableContentCount >= 2) { + return true; + } + } + } + return false; + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + _matrix.set(parentMatrix); + if (_transformAnimation != null) { + _matrix.preConcat(_transformAnimation!.getMatrix()); + } + var bounds = Rect.zero; + for (var i = _contents.length - 1; i >= 0; i--) { + var content = _contents[i]; + if (content is DrawingContent) { + var contentBounds = content.getBounds( + _matrix, + applyParents: applyParents, + ); + bounds = bounds.expandToInclude(contentBounds); + } + } + return bounds; + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + if (!keyPath.matches(name, depth) && name != '__container') { + return; + } + + if ('__container' != name && name != null) { + currentPartialKeyPath = currentPartialKeyPath.addKey(name!); + + if (keyPath.fullyResolvesTo(name, depth)) { + accumulator.add(currentPartialKeyPath.resolve(this)); + } + } + + if (keyPath.propagateToChildren(name, depth)) { + var newDepth = depth + keyPath.incrementDepthBy(name, depth); + for (var i = 0; i < _contents.length; i++) { + var content = _contents[i]; + if (content is KeyPathElement) { + var element = content as KeyPathElement; + element.resolveKeyPath( + keyPath, + newDepth, + accumulator, + currentPartialKeyPath, + ); + } + } + } + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (_transformAnimation != null) { + _transformAnimation!.applyValueCallback(property, callback); + } + } +} diff --git a/lottie/lib/src/animation/content/drawing_content.dart b/lottie/lib/src/animation/content/drawing_content.dart new file mode 100644 index 0000000..411ff6b --- /dev/null +++ b/lottie/lib/src/animation/content/drawing_content.dart @@ -0,0 +1,8 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import 'content.dart'; + +abstract class DrawingContent extends Content { + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}); + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}); +} diff --git a/lottie/lib/src/animation/content/ellipse_content.dart b/lottie/lib/src/animation/content/ellipse_content.dart new file mode 100644 index 0000000..5f784bb --- /dev/null +++ b/lottie/lib/src/animation/content/ellipse_content.dart @@ -0,0 +1,135 @@ +import 'dart:ui'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/circle_shape.dart'; +import '../../model/content/shape_trim_path.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../utils/misc.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import 'compound_trim_path_content.dart'; +import 'content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; +import 'trim_path_content.dart'; + +class EllipseContent implements PathContent, KeyPathElementContent { + static const _ellipseControlPointPercentage = 0.55228; + + final Path _path = Path(); + + @override + final String? name; + final LottieDrawable lottieDrawable; + final BaseKeyframeAnimation _sizeAnimation; + final BaseKeyframeAnimation _positionAnimation; + final CircleShape _circleShape; + + final CompoundTrimPathContent _trimPaths = CompoundTrimPathContent(); + bool _isPathValid = false; + + EllipseContent(this.lottieDrawable, BaseLayer layer, this._circleShape) + : name = _circleShape.name, + _sizeAnimation = _circleShape.size.createAnimation(), + _positionAnimation = _circleShape.position.createAnimation() { + layer.addAnimation(_sizeAnimation); + layer.addAnimation(_positionAnimation); + + _sizeAnimation.addUpdateListener(invalidate); + _positionAnimation.addUpdateListener(invalidate); + } + + void invalidate() { + _isPathValid = false; + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + for (var i = 0; i < contentsBefore.length; i++) { + var content = contentsBefore[i]; + if (content is TrimPathContent && + content.type == ShapeTrimPathType.simultaneously) { + var trimPath = content; + _trimPaths.addTrimPath(trimPath); + trimPath.addListener(invalidate); + } + } + } + + @override + Path getPath() { + if (_isPathValid) { + return _path; + } + + _path.reset(); + + if (_circleShape.hidden) { + _isPathValid = true; + return _path; + } + + var size = _sizeAnimation.value; + var halfWidth = size.dx / 2.0; + var halfHeight = size.dy / 2.0; + // TODO: handle bounds + + var cpW = halfWidth * _ellipseControlPointPercentage; + var cpH = halfHeight * _ellipseControlPointPercentage; + + _path.reset(); + if (_circleShape.isReversed) { + _path.moveTo(0, -halfHeight); + _path.cubicTo(0 - cpW, -halfHeight, -halfWidth, 0 - cpH, -halfWidth, 0); + _path.cubicTo(-halfWidth, 0 + cpH, 0 - cpW, halfHeight, 0, halfHeight); + _path.cubicTo(0 + cpW, halfHeight, halfWidth, 0 + cpH, halfWidth, 0); + _path.cubicTo(halfWidth, 0 - cpH, 0 + cpW, -halfHeight, 0, -halfHeight); + } else { + _path.moveTo(0, -halfHeight); + _path.cubicTo(0 + cpW, -halfHeight, halfWidth, 0 - cpH, halfWidth, 0); + _path.cubicTo(halfWidth, 0 + cpH, 0 + cpW, halfHeight, 0, halfHeight); + _path.cubicTo(0 - cpW, halfHeight, -halfWidth, 0 + cpH, -halfWidth, 0); + _path.cubicTo(-halfWidth, 0 - cpH, 0 - cpW, -halfHeight, 0, -halfHeight); + } + + var position = _positionAnimation.value; + _path.offset(position); + + _path.close(); + + _trimPaths.apply(_path); + + _isPathValid = true; + return _path; + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.ellipseSize) { + _sizeAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.position) { + _positionAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } + } +} diff --git a/lottie/lib/src/animation/content/fill_content.dart b/lottie/lib/src/animation/content/fill_content.dart new file mode 100644 index 0000000..27bd9c0 --- /dev/null +++ b/lottie/lib/src/animation/content/fill_content.dart @@ -0,0 +1,210 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../l.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/drop_shadow_effect.dart'; +import '../../model/content/shape_fill.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../utils/misc.dart'; +import '../../value/drop_shadow.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import '../keyframe/drop_shadow_keyframe_animation.dart'; +import '../keyframe/value_callback_keyframe_animation.dart'; +import 'content.dart'; +import 'drawing_content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; + +class FillContent implements DrawingContent, KeyPathElementContent { + final Path _path = Path(); + final BaseLayer layer; + @override + final String? name; + final bool _hidden; + final List _paths = []; + late final BaseKeyframeAnimation _colorAnimation; + late final BaseKeyframeAnimation _opacityAnimation; + BaseKeyframeAnimation? _colorFilterAnimation; + final LottieDrawable lottieDrawable; + BaseKeyframeAnimation? _blurAnimation; + double _blurMaskFilterRadius = 0; + DropShadowKeyframeAnimation? dropShadowAnimation; + + FillContent(this.lottieDrawable, this.layer, ShapeFill fill) + : name = fill.name, + _hidden = fill.hidden { + var blurEffect = layer.blurEffect; + if (blurEffect != null) { + _blurAnimation = blurEffect.blurriness.createAnimation() + ..addUpdateListener(onValueChanged); + layer.addAnimation(_blurAnimation); + } + var dropShadowEffect = layer.dropShadowEffect; + if (dropShadowEffect != null) { + dropShadowAnimation = DropShadowKeyframeAnimation( + onValueChanged, + layer, + dropShadowEffect, + ); + } + + if (fill.color == null || fill.opacity == null) { + return; + } + + _path.fillType = fill.fillType; + + _colorAnimation = fill.color!.createAnimation(); + _colorAnimation.addUpdateListener(onValueChanged); + layer.addAnimation(_colorAnimation); + _opacityAnimation = fill.opacity!.createAnimation(); + _opacityAnimation.addUpdateListener(onValueChanged); + layer.addAnimation(_opacityAnimation); + } + + void onValueChanged() { + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + for (var i = 0; i < contentsAfter.length; i++) { + var content = contentsAfter[i]; + if (content is PathContent) { + _paths.add(content); + } + } + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + if (_hidden) { + return; + } + L.beginSection('FillContent#draw'); + + var paint = Paint()..color = _colorAnimation.value; + var alpha = ((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255) + .round(); + paint.setAlpha(alpha.clamp(0, 255)); + if (lottieDrawable.antiAliasingSuggested) { + paint.isAntiAlias = true; + } + + if (_colorFilterAnimation != null) { + paint.colorFilter = _colorFilterAnimation!.value; + } + + var blurAnimation = _blurAnimation; + if (blurAnimation != null) { + var blurRadius = blurAnimation.value; + if (blurRadius == 0) { + paint.maskFilter = null; + } else if (blurRadius != _blurMaskFilterRadius) { + var blur = layer.getBlurMaskFilter(blurRadius); + paint.maskFilter = blur; + } + _blurMaskFilterRadius = blurRadius; + } + + _path.reset(); + for (var i = 0; i < _paths.length; i++) { + _path.addPath(_paths[i].getPath(), Offset.zero); + } + + canvas.save(); + canvas.transform(parentMatrix.storage); + var dropShadow = dropShadowAnimation; + if (dropShadow != null) { + dropShadow.draw(canvas, _path); + } + canvas.drawPath(_path, paint); + canvas.restore(); + + L.endSection('FillContent#draw'); + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + _path.reset(); + for (var i = 0; i < _paths.length; i++) { + _path.addPath( + _paths[i].getPath(), + Offset.zero, + matrix4: parentMatrix.storage, + ); + } + var outBounds = _path.getBounds(); + // Add padding to account for rounding errors. + outBounds = outBounds.inflate(1); + return outBounds; + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.color) { + _colorAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.opacity) { + _opacityAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.colorFilter) { + if (_colorFilterAnimation != null) { + layer.removeAnimation(_colorFilterAnimation); + } + + if (callback == null) { + _colorFilterAnimation = null; + } else { + _colorFilterAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + )..addUpdateListener(onValueChanged); + layer.addAnimation(_colorFilterAnimation); + } + } else if (property == LottieProperty.blurRadius) { + var blurAnimation = _blurAnimation; + if (blurAnimation != null) { + blurAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else { + var callbackBlur = callback as LottieValueCallback?; + _blurAnimation = blurAnimation = ValueCallbackKeyframeAnimation( + callbackBlur, + callbackBlur?.value ?? 0, + )..addUpdateListener(onValueChanged); + layer.addAnimation(blurAnimation); + } + } else if (property == LottieProperty.dropShadow) { + var dropShadowAnimation = this.dropShadowAnimation; + if (dropShadowAnimation == null) { + var effect = DropShadowEffect.createEmpty(); + this.dropShadowAnimation = dropShadowAnimation = dropShadowAnimation = + DropShadowKeyframeAnimation(onValueChanged, layer, effect); + } + + dropShadowAnimation.setCallback( + callback as LottieValueCallback?, + ); + } + } +} diff --git a/lottie/lib/src/animation/content/gradient_fill_content.dart b/lottie/lib/src/animation/content/gradient_fill_content.dart new file mode 100644 index 0000000..3d591ff --- /dev/null +++ b/lottie/lib/src/animation/content/gradient_fill_content.dart @@ -0,0 +1,329 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../l.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/drop_shadow_effect.dart'; +import '../../model/content/gradient_color.dart'; +import '../../model/content/gradient_fill.dart'; +import '../../model/content/gradient_type.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../utils/misc.dart'; +import '../../value/drop_shadow.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import '../keyframe/drop_shadow_keyframe_animation.dart'; +import '../keyframe/value_callback_keyframe_animation.dart'; +import 'content.dart'; +import 'drawing_content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; + +class GradientFillContent implements DrawingContent, KeyPathElementContent { + /// Cache the gradients such that it runs at 30fps. + static const _cacheStepsMs = 32; + final BaseLayer layer; + final GradientFill _fill; + final _linearGradientCache = {}; + final _radialGradientCache = {}; + final _path = Path(); + final _paint = Paint(); + final _paths = []; + final BaseKeyframeAnimation _colorAnimation; + final BaseKeyframeAnimation _opacityAnimation; + final BaseKeyframeAnimation _startPointAnimation; + final BaseKeyframeAnimation _endPointAnimation; + BaseKeyframeAnimation? _colorFilterAnimation; + ValueCallbackKeyframeAnimation, List>? + _colorCallbackAnimation; + final LottieDrawable lottieDrawable; + final int _cacheSteps; + BaseKeyframeAnimation? _blurAnimation; + double _blurMaskFilterRadius = 0; + DropShadowKeyframeAnimation? dropShadowAnimation; + + GradientFillContent(this.lottieDrawable, this.layer, this._fill) + : _cacheSteps = + (lottieDrawable.composition.duration.inMilliseconds / _cacheStepsMs) + .round(), + _colorAnimation = _fill.gradientColor.createAnimation(), + _opacityAnimation = _fill.opacity.createAnimation(), + _startPointAnimation = _fill.startPoint.createAnimation(), + _endPointAnimation = _fill.endPoint.createAnimation() { + _path.fillType = _fill.fillType; + _colorAnimation.addUpdateListener(invalidate); + layer.addAnimation(_colorAnimation); + + _opacityAnimation.addUpdateListener(invalidate); + layer.addAnimation(_opacityAnimation); + + _startPointAnimation.addUpdateListener(invalidate); + layer.addAnimation(_startPointAnimation); + + _endPointAnimation.addUpdateListener(invalidate); + layer.addAnimation(_endPointAnimation); + + var blurEffect = layer.blurEffect; + if (blurEffect != null) { + _blurAnimation = blurEffect.blurriness.createAnimation() + ..addUpdateListener(invalidate); + layer.addAnimation(_blurAnimation); + } + var dropShadowEffect = layer.dropShadowEffect; + if (dropShadowEffect != null) { + dropShadowAnimation = DropShadowKeyframeAnimation( + invalidate, + layer, + dropShadowEffect, + ); + } + } + + @override + String? get name => _fill.name; + + void invalidate() { + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + for (var i = 0; i < contentsAfter.length; i++) { + var content = contentsAfter[i]; + if (content is PathContent) { + _paths.add(content); + } + } + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + if (_fill.hidden) { + return; + } + L.beginSection('GradientFillContent#draw'); + _path.reset(); + for (var i = 0; i < _paths.length; i++) { + _path.addPath(_paths[i].getPath(), Offset.zero); + } + + Gradient gradient; + if (_fill.gradientType == GradientType.linear) { + gradient = _getLinearGradient(); + } else { + gradient = _getRadialGradient(); + } + + _paint.shader = gradient; + + if (_colorFilterAnimation != null) { + _paint.colorFilter = _colorFilterAnimation!.value; + } + + var blurAnimation = _blurAnimation; + if (blurAnimation != null) { + var blurRadius = blurAnimation.value; + if (blurRadius == 0) { + _paint.maskFilter = null; + } else if (blurRadius != _blurMaskFilterRadius) { + var blur = layer.getBlurMaskFilter(blurRadius); + _paint.maskFilter = blur; + } + _blurMaskFilterRadius = blurRadius; + } + + var alpha = ((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255) + .round(); + _paint.setAlpha(alpha.clamp(0, 255)); + if (lottieDrawable.antiAliasingSuggested) { + _paint.isAntiAlias = true; + } + + canvas.save(); + canvas.transform(parentMatrix.storage); + var dropShadow = dropShadowAnimation; + if (dropShadow != null) { + dropShadow.draw(canvas, _path); + } + canvas.drawPath(_path, _paint); + canvas.restore(); + L.endSection('GradientFillContent#draw'); + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + _path.reset(); + for (var i = 0; i < _paths.length; i++) { + _path.addPath( + _paths[i].getPath(), + Offset.zero, + matrix4: parentMatrix.storage, + ); + } + + var outBounds = _path.getBounds(); + // Add padding to account for rounding errors. + return outBounds.inflate(1); + } + + Gradient _getLinearGradient() { + var gradientHash = _getGradientHash(); + var gradient = _linearGradientCache[gradientHash]; + if (gradient != null && _colorCallbackAnimation == null) { + return gradient; + } + var startPoint = _startPointAnimation.value; + var endPoint = _endPointAnimation.value; + var gradientColor = _colorAnimation.value; + var colors = _applyDynamicColorsIfNeeded(gradientColor.colors); + var positions = gradientColor.positions; + gradient = Gradient.linear(startPoint, endPoint, colors, positions); + if (gradientHash != null) { + _linearGradientCache[gradientHash] = gradient; + } + return gradient; + } + + Gradient _getRadialGradient() { + var gradientHash = _getGradientHash(); + var gradient = _radialGradientCache[gradientHash]; + if (gradient != null) { + return gradient; + } + var startPoint = _startPointAnimation.value; + var endPoint = _endPointAnimation.value; + var gradientColor = _colorAnimation.value; + var colors = _applyDynamicColorsIfNeeded(gradientColor.colors); + var positions = gradientColor.positions; + var x0 = startPoint.dx; + var y0 = startPoint.dy; + var x1 = endPoint.dx; + var y1 = endPoint.dy; + var radius = hypot(x1 - x0, y1 - y0).toDouble(); + if (radius <= 0) { + radius = 0.001; + } + gradient = Gradient.radial(startPoint, radius, colors, positions); + if (gradientHash != null) { + _radialGradientCache[gradientHash] = gradient; + } + return gradient; + } + + int? _getGradientHash() { + // Don't cache gradient if ValueDelegate.gradient is used + if (_colorCallbackAnimation != null) return null; + + var startPointProgress = (_startPointAnimation.progress * _cacheSteps) + .round(); + var endPointProgress = (_endPointAnimation.progress * _cacheSteps).round(); + var colorProgress = (_colorAnimation.progress * _cacheSteps).round(); + var hash = 17; + if (startPointProgress != 0) { + hash = hash * 31 * startPointProgress; + } + if (endPointProgress != 0) { + hash = hash * 31 * endPointProgress; + } + if (colorProgress != 0) { + hash = hash * 31 * colorProgress; + } + return hash; + } + + List _applyDynamicColorsIfNeeded(List colors) { + if (_colorCallbackAnimation != null) { + var dynamicColors = _colorCallbackAnimation!.value; + if (colors.length == dynamicColors.length) { + for (var i = 0; i < colors.length; i++) { + colors[i] = dynamicColors[i]; + } + } else { + colors = List.filled(dynamicColors.length, const Color(0x00000000)); + for (var i = 0; i < dynamicColors.length; i++) { + colors[i] = dynamicColors[i]; + } + } + } + return colors; + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.opacity) { + _opacityAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.colorFilter) { + if (_colorFilterAnimation != null) { + layer.removeAnimation(_colorFilterAnimation); + } + + if (callback == null) { + _colorFilterAnimation = null; + } else { + _colorFilterAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + )..addUpdateListener(invalidate); + layer.addAnimation(_colorFilterAnimation); + } + } else if (property == LottieProperty.gradientColor) { + if (_colorCallbackAnimation != null) { + layer.removeAnimation(_colorCallbackAnimation); + } + + if (callback == null) { + _colorCallbackAnimation = null; + } else { + _linearGradientCache.clear(); + _radialGradientCache.clear(); + _colorCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback>, + [], + )..addUpdateListener(invalidate); + layer.addAnimation(_colorCallbackAnimation); + } + } else if (property == LottieProperty.blurRadius) { + var blurAnimation = _blurAnimation; + if (blurAnimation != null) { + blurAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else { + _blurAnimation = blurAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + 0, + )..addUpdateListener(invalidate); + layer.addAnimation(blurAnimation); + } + } else if (property == LottieProperty.dropShadow) { + var dropShadowAnimation = this.dropShadowAnimation; + if (dropShadowAnimation == null) { + var effect = DropShadowEffect.createEmpty(); + this.dropShadowAnimation = dropShadowAnimation = dropShadowAnimation = + DropShadowKeyframeAnimation(invalidate, layer, effect); + } + + dropShadowAnimation.setCallback( + callback as LottieValueCallback?, + ); + } + } +} diff --git a/lottie/lib/src/animation/content/gradient_stroke_content.dart b/lottie/lib/src/animation/content/gradient_stroke_content.dart new file mode 100644 index 0000000..3549421 --- /dev/null +++ b/lottie/lib/src/animation/content/gradient_stroke_content.dart @@ -0,0 +1,206 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/gradient_color.dart'; +import '../../model/content/gradient_stroke.dart'; +import '../../model/content/gradient_type.dart'; +import '../../model/content/shape_stroke.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import '../keyframe/value_callback_keyframe_animation.dart'; +import 'base_stroke_content.dart'; + +class GradientStrokeContent extends BaseStrokeContent { + /// Cache the gradients such that it runs at 30fps. + static const _cacheStepsMs = 32; + + @override + final String? name; + final bool _hidden; + final _linearGradientCache = {}; + final _radialGradientCache = {}; + + final GradientType _type; + final int _cacheSteps; + final BaseKeyframeAnimation _colorAnimation; + final BaseKeyframeAnimation _startPointAnimation; + final BaseKeyframeAnimation _endPointAnimation; + ValueCallbackKeyframeAnimation, List>? + _colorCallbackAnimation; + + GradientStrokeContent( + LottieDrawable lottieDrawable, + BaseLayer layer, + GradientStroke stroke, + ) : name = stroke.name, + _type = stroke.gradientType, + _hidden = stroke.hidden, + _cacheSteps = + (lottieDrawable.composition.duration.inMilliseconds / _cacheStepsMs) + .round(), + _colorAnimation = stroke.gradientColor.createAnimation(), + _startPointAnimation = stroke.startPoint.createAnimation(), + _endPointAnimation = stroke.endPoint.createAnimation(), + super( + lottieDrawable, + layer, + cap: lineCapTypeToPaintCap(stroke.capType), + join: lineJoinTypeToPaintJoin(stroke.joinType), + miterLimit: stroke.miterLimit, + opacity: stroke.opacity, + width: stroke.width, + dashPattern: stroke.lineDashPattern, + dashOffset: stroke.dashOffset, + ) { + _colorAnimation.addUpdateListener(onUpdateListener); + layer.addAnimation(_colorAnimation); + + _startPointAnimation.addUpdateListener(onUpdateListener); + layer.addAnimation(_startPointAnimation); + + _endPointAnimation.addUpdateListener(onUpdateListener); + layer.addAnimation(_endPointAnimation); + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + if (_hidden) { + return; + } + + Gradient gradient; + if (_type == GradientType.linear) { + gradient = _getLinearGradient(parentMatrix); + } else { + gradient = _getRadialGradient(parentMatrix); + } + + paint.shader = gradient; + + super.draw(canvas, parentMatrix, parentAlpha: parentAlpha); + } + + Gradient _getLinearGradient(Matrix4 parentMatrix) { + var gradientHash = _getGradientHash(parentMatrix); + var gradient = _linearGradientCache[gradientHash]; + if (gradient != null) { + return gradient; + } + var startPoint = _startPointAnimation.value; + var endPoint = _endPointAnimation.value; + var gradientColor = _colorAnimation.value; + var colors = _applyDynamicColorsIfNeeded(gradientColor.colors); + var positions = gradientColor.positions; + + gradient = Gradient.linear( + startPoint, + endPoint, + colors, + positions, + TileMode.clamp, + parentMatrix.storage, + ); + if (gradientHash != null) { + _linearGradientCache[gradientHash] = gradient; + } + return gradient; + } + + Gradient _getRadialGradient(Matrix4 parentMatrix) { + var gradientHash = _getGradientHash(parentMatrix); + var gradient = _radialGradientCache[gradientHash]; + if (gradient != null) { + return gradient; + } + var startPoint = _startPointAnimation.value; + var endPoint = _endPointAnimation.value; + var gradientColor = _colorAnimation.value; + var colors = _applyDynamicColorsIfNeeded(gradientColor.colors); + var positions = gradientColor.positions; + var x0 = startPoint.dx; + var y0 = startPoint.dy; + var x1 = endPoint.dx; + var y1 = endPoint.dy; + var radius = hypot(x1 - x0, y1 - y0).toDouble(); + gradient = Gradient.radial( + startPoint, + radius, + colors, + positions, + TileMode.clamp, + parentMatrix.storage, + ); + if (gradientHash != null) { + _radialGradientCache[gradientHash] = gradient; + } + return gradient; + } + + //TODO(xha): cache the shader based on the input parameters and not the animation + // progress. + // At first, log when there is too many cache miss. + int? _getGradientHash(Matrix4 parentMatrix) { + // Don't cache gradient if ValueDelegate.gradient is used + if (_colorCallbackAnimation != null) return null; + + var startPointProgress = (_startPointAnimation.progress * _cacheSteps) + .round(); + var endPointProgress = (_endPointAnimation.progress * _cacheSteps).round(); + var colorProgress = (_colorAnimation.progress * _cacheSteps).round(); + var hash = 17; + if (startPointProgress != 0) { + hash = hash * 31 * startPointProgress; + } + if (endPointProgress != 0) { + hash = hash * 31 * endPointProgress; + } + if (colorProgress != 0) { + hash = hash * 31 * colorProgress; + } + hash *= 31 * parentMatrix.hashCode; + return hash; + } + + List _applyDynamicColorsIfNeeded(List colors) { + if (_colorCallbackAnimation != null) { + var dynamicColors = _colorCallbackAnimation!.value; + if (colors.length == dynamicColors.length) { + for (var i = 0; i < colors.length; i++) { + colors[i] = dynamicColors[i]; + } + } else { + colors = List.filled( + dynamicColors.length, + const Color(0x00000000), + ); + for (var i = 0; i < dynamicColors.length; i++) { + colors[i] = dynamicColors[i]; + } + } + } + return colors; + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + super.addValueCallback(property, callback); + if (property == LottieProperty.gradientColor) { + if (_colorCallbackAnimation != null) { + layer.removeAnimation(_colorCallbackAnimation); + } + + if (callback == null) { + _colorCallbackAnimation = null; + } else { + _colorCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback>, + [], + )..addUpdateListener(onUpdateListener); + layer.addAnimation(_colorCallbackAnimation); + } + } + } +} diff --git a/lottie/lib/src/animation/content/greedy_content.dart b/lottie/lib/src/animation/content/greedy_content.dart new file mode 100644 index 0000000..4c4f229 --- /dev/null +++ b/lottie/lib/src/animation/content/greedy_content.dart @@ -0,0 +1,13 @@ +import 'content.dart'; + +/// Content that may want to absorb and take ownership of the content around it. +/// For example, merge paths will absorb the shapes above it and repeaters will absorb the content +/// above it. +abstract class GreedyContent { + /// An iterator of contents that can be used to take ownership of contents. If ownership is taken, + /// the content should be removed from the iterator. + /// + /// The contents should be iterated by calling hasPrevious() and previous() so that the list of + /// contents is traversed from bottom to top which is the correct order for handling AE logic. + void absorbContent(List contents); +} diff --git a/lottie/lib/src/animation/content/key_path_element_content.dart b/lottie/lib/src/animation/content/key_path_element_content.dart new file mode 100644 index 0000000..8a0c039 --- /dev/null +++ b/lottie/lib/src/animation/content/key_path_element_content.dart @@ -0,0 +1,4 @@ +import '../../model/key_path_element.dart'; +import 'content.dart'; + +abstract class KeyPathElementContent implements KeyPathElement, Content {} diff --git a/lottie/lib/src/animation/content/merge_paths_content.dart b/lottie/lib/src/animation/content/merge_paths_content.dart new file mode 100644 index 0000000..b73347f --- /dev/null +++ b/lottie/lib/src/animation/content/merge_paths_content.dart @@ -0,0 +1,107 @@ +import 'dart:ui'; +import '../../model/content/merge_paths.dart'; +import '../../utils.dart'; +import 'content.dart'; +import 'content_group.dart'; +import 'greedy_content.dart'; +import 'path_content.dart'; + +class MergePathsContent implements PathContent, GreedyContent { + final Path _firstPath = Path(); + final Path _remainderPath = Path(); + final Path _path = Path(); + + final List _pathContents = []; + final MergePaths _mergePaths; + + MergePathsContent(this._mergePaths); + + @override + void absorbContent(List contents) { + // Fast forward the iterator until after this content. + var index = contents.lastIndexOf(this) - 1; + + while (index >= 0) { + var content = contents[index]; + if (content is PathContent) { + _pathContents.add(content); + contents.removeAt(index); + } + --index; + } + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + for (var i = 0; i < _pathContents.length; i++) { + _pathContents[i].setContents(contentsBefore, contentsAfter); + } + } + + @override + Path getPath() { + _path.reset(); + + if (_mergePaths.hidden) { + return _path; + } + + switch (_mergePaths.mode) { + case MergePathsMode.merge: + _addPaths(); + case MergePathsMode.add: + _opFirstPathWithRest(PathOperation.union); + case MergePathsMode.substract: + _opFirstPathWithRest(PathOperation.reverseDifference); + case MergePathsMode.intersect: + _opFirstPathWithRest(PathOperation.intersect); + case MergePathsMode.excludeIntersections: + _opFirstPathWithRest(PathOperation.xor); + } + + return _path; + } + + @override + String get name => _mergePaths.name; + + void _addPaths() { + for (var i = 0; i < _pathContents.length; i++) { + _path.addPath(_pathContents[i].getPath(), Offset.zero); + } + } + + void _opFirstPathWithRest(PathOperation op) { + _remainderPath.reset(); + _firstPath.reset(); + + for (var i = _pathContents.length - 1; i >= 1; i--) { + var content = _pathContents[i]; + + if (content is ContentGroup) { + var pathList = content.getPathList(); + for (var j = pathList.length - 1; j >= 0; j--) { + var path = pathList[j].getPath(); + path = path.transform(content.getTransformationMatrix().storage); + _remainderPath.addPath(path, Offset.zero); + } + } else { + _remainderPath.addPath(content.getPath(), Offset.zero); + } + } + + var lastContent = _pathContents[0]; + if (lastContent is ContentGroup) { + var pathList = lastContent.getPathList(); + for (var j = 0; j < pathList.length; j++) { + var path = pathList[j].getPath(); + path = path.transform(lastContent.getTransformationMatrix().storage); + _firstPath.addPath(path, Offset.zero); + } + } else { + _firstPath.set(lastContent.getPath()); + } + + _path.set(Path.combine(op, _firstPath, _remainderPath)); + } +} diff --git a/lottie/lib/src/animation/content/modifier_content.dart b/lottie/lib/src/animation/content/modifier_content.dart new file mode 100644 index 0000000..78a7569 --- /dev/null +++ b/lottie/lib/src/animation/content/modifier_content.dart @@ -0,0 +1 @@ +abstract class ModifierContent {} diff --git a/lottie/lib/src/animation/content/path_content.dart b/lottie/lib/src/animation/content/path_content.dart new file mode 100644 index 0000000..5cd62a1 --- /dev/null +++ b/lottie/lib/src/animation/content/path_content.dart @@ -0,0 +1,6 @@ +import 'dart:ui'; +import 'content.dart'; + +abstract class PathContent extends Content { + Path getPath(); +} diff --git a/lottie/lib/src/animation/content/polystar_content.dart b/lottie/lib/src/animation/content/polystar_content.dart new file mode 100644 index 0000000..00338fa --- /dev/null +++ b/lottie/lib/src/animation/content/polystar_content.dart @@ -0,0 +1,348 @@ +import 'dart:math'; +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/polystar_shape.dart'; +import '../../model/content/shape_trim_path.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils/misc.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import 'compound_trim_path_content.dart'; +import 'content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; +import 'trim_path_content.dart'; + +class PolystarContent implements PathContent, KeyPathElementContent { + /// This was empirically derived by creating polystars, converting them to + /// curves, and calculating a scale factor. + /// It works best for polygons and stars with 3 points and needs more + /// work otherwise. + static const _polystarMagicNumber = .47829; + static const _polygonMagicNumber = .25; + final _path = Path(); + + final LottieDrawable lottieDrawable; + final PolystarShape _polystarShape; + final BaseKeyframeAnimation _pointsAnimation; + final BaseKeyframeAnimation _positionAnimation; + final BaseKeyframeAnimation _rotationAnimation; + final BaseKeyframeAnimation? _innerRadiusAnimation; + final BaseKeyframeAnimation _outerRadiusAnimation; + final BaseKeyframeAnimation? _innerRoundednessAnimation; + final BaseKeyframeAnimation _outerRoundednessAnimation; + + final _trimPaths = CompoundTrimPathContent(); + bool _isPathValid = false; + + PolystarContent(this.lottieDrawable, BaseLayer layer, this._polystarShape) + : _pointsAnimation = _polystarShape.points.createAnimation(), + _positionAnimation = _polystarShape.position.createAnimation(), + _rotationAnimation = _polystarShape.rotation.createAnimation(), + _outerRadiusAnimation = _polystarShape.outerRadius.createAnimation(), + _outerRoundednessAnimation = _polystarShape.outerRoundedness + .createAnimation(), + _innerRadiusAnimation = _polystarShape.type == PolystarShapeType.star + ? _polystarShape.innerRadius!.createAnimation() + : null, + _innerRoundednessAnimation = _polystarShape.type == PolystarShapeType.star + ? _polystarShape.innerRoundedness!.createAnimation() + : null { + layer.addAnimation(_pointsAnimation); + layer.addAnimation(_positionAnimation); + layer.addAnimation(_rotationAnimation); + layer.addAnimation(_outerRadiusAnimation); + layer.addAnimation(_outerRoundednessAnimation); + if (_polystarShape.type == PolystarShapeType.star) { + layer.addAnimation(_innerRadiusAnimation); + layer.addAnimation(_innerRoundednessAnimation); + } + + _pointsAnimation.addUpdateListener(invalidate); + _positionAnimation.addUpdateListener(invalidate); + _rotationAnimation.addUpdateListener(invalidate); + _outerRadiusAnimation.addUpdateListener(invalidate); + _outerRoundednessAnimation.addUpdateListener(invalidate); + if (_polystarShape.type == PolystarShapeType.star) { + _innerRadiusAnimation!.addUpdateListener(invalidate); + _innerRoundednessAnimation!.addUpdateListener(invalidate); + } + } + + void invalidate() { + _isPathValid = false; + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + for (var i = 0; i < contentsBefore.length; i++) { + var content = contentsBefore[i]; + if (content is TrimPathContent && + content.type == ShapeTrimPathType.simultaneously) { + var trimPath = content; + _trimPaths.addTrimPath(trimPath); + trimPath.addListener(invalidate); + } + } + } + + @override + Path getPath() { + if (_isPathValid) { + return _path; + } + + _path.reset(); + + if (_polystarShape.hidden) { + _isPathValid = true; + return _path; + } + + switch (_polystarShape.type) { + case PolystarShapeType.star: + _createStarPath(); + case PolystarShapeType.polygon: + _createPolygonPath(); + } + + _path.close(); + + _trimPaths.apply(_path); + + _isPathValid = true; + return _path; + } + + @override + String? get name => _polystarShape.name; + + void _createStarPath() { + var points = _pointsAnimation.value; + var currentAngle = _rotationAnimation.value; + // Start at +y instead of +x + currentAngle -= 90; + // convert to radians + currentAngle = radians(currentAngle); + // adjust current angle for partial points + var anglePerPoint = 2 * pi / points; + if (_polystarShape.isReversed) { + anglePerPoint *= -1; + } + var halfAnglePerPoint = anglePerPoint / 2.0; + var partialPointAmount = points - points.toInt(); + if (partialPointAmount != 0) { + currentAngle += halfAnglePerPoint * (1.0 - partialPointAmount); + } + + var outerRadius = _outerRadiusAnimation.value; + //noinspection ConstantConditions + var innerRadius = _innerRadiusAnimation!.value; + + var innerRoundedness = 0.0; + if (_innerRoundednessAnimation != null) { + innerRoundedness = _innerRoundednessAnimation.value / 100.0; + } + var outerRoundedness = _outerRoundednessAnimation.value / 100.0; + + double x; + double y; + double previousX; + double previousY; + var partialPointRadius = 0.0; + if (partialPointAmount != 0) { + partialPointRadius = + innerRadius + partialPointAmount * (outerRadius - innerRadius); + x = partialPointRadius * cos(currentAngle); + y = partialPointRadius * sin(currentAngle); + _path.moveTo(x, y); + currentAngle += anglePerPoint * partialPointAmount / 2.0; + } else { + x = outerRadius * cos(currentAngle); + y = outerRadius * sin(currentAngle); + _path.moveTo(x, y); + currentAngle += halfAnglePerPoint; + } + + // True means the line will go to outer radius. False means inner radius. + var longSegment = false; + var numPoints = (points.ceil() * 2).toDouble(); + for (var i = 0; i < numPoints; i++) { + var radius = longSegment ? outerRadius : innerRadius; + var dTheta = halfAnglePerPoint; + if (partialPointRadius != 0 && i == numPoints - 2) { + dTheta = anglePerPoint * partialPointAmount / 2.0; + } + if (partialPointRadius != 0 && i == numPoints - 1) { + radius = partialPointRadius; + } + previousX = x; + previousY = y; + x = radius * cos(currentAngle); + y = radius * sin(currentAngle); + + if (innerRoundedness == 0 && outerRoundedness == 0) { + _path.lineTo(x, y); + } else { + var cp1Theta = atan2(previousY, previousX) - pi / 2.0; + var cp1Dx = cos(cp1Theta); + var cp1Dy = sin(cp1Theta); + + var cp2Theta = atan2(y, x) - pi / 2.0; + var cp2Dx = cos(cp2Theta); + var cp2Dy = sin(cp2Theta); + + var cp1Roundedness = longSegment ? innerRoundedness : outerRoundedness; + var cp2Roundedness = longSegment ? outerRoundedness : innerRoundedness; + var cp1Radius = longSegment ? innerRadius : outerRadius; + var cp2Radius = longSegment ? outerRadius : innerRadius; + + var cp1x = cp1Radius * cp1Roundedness * _polystarMagicNumber * cp1Dx; + var cp1y = cp1Radius * cp1Roundedness * _polystarMagicNumber * cp1Dy; + var cp2x = cp2Radius * cp2Roundedness * _polystarMagicNumber * cp2Dx; + var cp2y = cp2Radius * cp2Roundedness * _polystarMagicNumber * cp2Dy; + if (partialPointAmount != 0) { + if (i == 0) { + cp1x *= partialPointAmount; + cp1y *= partialPointAmount; + } else if (i == numPoints - 1) { + cp2x *= partialPointAmount; + cp2y *= partialPointAmount; + } + } + + _path.cubicTo( + previousX - cp1x, + previousY - cp1y, + x + cp2x, + y + cp2y, + x, + y, + ); + } + + currentAngle += dTheta; + longSegment = !longSegment; + } + + var position = _positionAnimation.value; + _path.shift(position); + _path.close(); + } + + void _createPolygonPath() { + var points = _pointsAnimation.value.floor(); + var currentAngle = _rotationAnimation.value; + // Start at +y instead of +x + currentAngle -= 90; + // convert to radians + currentAngle = radians(currentAngle); + // adjust current angle for partial points + var anglePerPoint = 2 * pi / points; + + var roundedness = _outerRoundednessAnimation.value / 100.0; + var radius = _outerRadiusAnimation.value; + double x; + double y; + double previousX; + double previousY; + x = radius * cos(currentAngle); + y = radius * sin(currentAngle); + _path.moveTo(x, y); + currentAngle += anglePerPoint; + + var numPoints = points.toDouble(); + for (var i = 0; i < numPoints; i++) { + previousX = x; + previousY = y; + x = radius * cos(currentAngle); + y = radius * sin(currentAngle); + + if (roundedness != 0) { + var cp1Theta = atan2(previousY, previousX) - pi / 2.0; + var cp1Dx = cos(cp1Theta); + var cp1Dy = sin(cp1Theta); + + var cp2Theta = atan2(y, x) - pi / 2.0; + var cp2Dx = cos(cp2Theta); + var cp2Dy = sin(cp2Theta); + + var cp1x = radius * roundedness * _polygonMagicNumber * cp1Dx; + var cp1y = radius * roundedness * _polygonMagicNumber * cp1Dy; + var cp2x = radius * roundedness * _polygonMagicNumber * cp2Dx; + var cp2y = radius * roundedness * _polygonMagicNumber * cp2Dy; + _path.cubicTo( + previousX - cp1x, + previousY - cp1y, + x + cp2x, + y + cp2y, + x, + y, + ); + } else { + _path.lineTo(x, y); + } + + currentAngle += anglePerPoint; + } + + var position = _positionAnimation.value; + _path.shift(position); + _path.close(); + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.polystarPoints) { + _pointsAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.polystarRotation) { + _rotationAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.position) { + _positionAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.polystarInnerRadius && + _innerRadiusAnimation != null) { + _innerRadiusAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.polystarOuterRadius) { + _outerRadiusAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.polystarInnerRoundedness && + _innerRoundednessAnimation != null) { + _innerRoundednessAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.polystarOuterRoundedness) { + _outerRoundednessAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } + } +} diff --git a/lottie/lib/src/animation/content/rectangle_content.dart b/lottie/lib/src/animation/content/rectangle_content.dart new file mode 100644 index 0000000..26ae774 --- /dev/null +++ b/lottie/lib/src/animation/content/rectangle_content.dart @@ -0,0 +1,207 @@ +import 'dart:math'; +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/rectangle_shape.dart'; +import '../../model/content/shape_trim_path.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils/misc.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import 'compound_trim_path_content.dart'; +import 'content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; +import 'rounded_corners_content.dart'; +import 'trim_path_content.dart'; + +class RectangleContent implements KeyPathElementContent, PathContent { + final _path = Path(); + + @override + final String? name; + final bool _hidden; + final LottieDrawable lottieDrawable; + final BaseKeyframeAnimation _positionAnimation; + final BaseKeyframeAnimation _sizeAnimation; + final BaseKeyframeAnimation _cornerRadiusAnimation; + + final CompoundTrimPathContent _trimPaths = CompoundTrimPathContent(); + + /// This corner radius is from a layer item. The first one is from the roundedness on this specific rect. + BaseKeyframeAnimation? _roundedCornersAnimation; + bool _isPathValid = false; + + RectangleContent( + this.lottieDrawable, + BaseLayer layer, + RectangleShape rectShape, + ) : name = rectShape.name, + _hidden = rectShape.hidden, + _positionAnimation = rectShape.position.createAnimation(), + _sizeAnimation = rectShape.size.createAnimation(), + _cornerRadiusAnimation = rectShape.cornerRadius.createAnimation() { + layer.addAnimation(_positionAnimation); + layer.addAnimation(_sizeAnimation); + layer.addAnimation(_cornerRadiusAnimation); + + _positionAnimation.addUpdateListener(invalidate); + _sizeAnimation.addUpdateListener(invalidate); + _cornerRadiusAnimation.addUpdateListener(invalidate); + } + + void invalidate() { + _isPathValid = false; + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + for (var i = 0; i < contentsBefore.length; i++) { + var content = contentsBefore[i]; + if (content is TrimPathContent && + content.type == ShapeTrimPathType.simultaneously) { + var trimPath = content; + _trimPaths.addTrimPath(trimPath); + trimPath.addListener(invalidate); + } else if (content is RoundedCornersContent) { + _roundedCornersAnimation = content.roundedCorners; + } + } + } + + @override + Path getPath() { + if (_isPathValid) { + return _path; + } + + _path.reset(); + + if (_hidden) { + _isPathValid = true; + return _path; + } + + var size = _sizeAnimation.value; + var halfWidth = size.dx / 2.0; + var halfHeight = size.dy / 2.0; + var radius = _cornerRadiusAnimation.value; + var roundedCornersAnimation = _roundedCornersAnimation; + if (radius == 0 && roundedCornersAnimation != null) { + radius = min(roundedCornersAnimation.value, min(halfWidth, halfHeight)); + } + var maxRadius = min(halfWidth, halfHeight); + if (radius > maxRadius) { + radius = maxRadius; + } + + // Draw the rectangle top right to bottom left. + var position = _positionAnimation.value; + + _path.moveTo(position.dx + halfWidth, position.dy - halfHeight + radius); + + _path.lineTo(position.dx + halfWidth, position.dy + halfHeight - radius); + + if (radius > 0) { + _path.arcTo( + Rect.fromLTRB( + position.dx + halfWidth - 2 * radius, + position.dy + halfHeight - 2 * radius, + position.dx + halfWidth, + position.dy + halfHeight, + ), + 0, + radians(90), + false, + ); + } + + _path.lineTo(position.dx - halfWidth + radius, position.dy + halfHeight); + + if (radius > 0) { + _path.arcTo( + Rect.fromLTRB( + position.dx - halfWidth, + position.dy + halfHeight - 2 * radius, + position.dx - halfWidth + 2 * radius, + position.dy + halfHeight, + ), + radians(90), + radians(90), + false, + ); + } + + _path.lineTo(position.dx - halfWidth, position.dy - halfHeight + radius); + + if (radius > 0) { + _path.arcTo( + Rect.fromLTRB( + position.dx - halfWidth, + position.dy - halfHeight, + position.dx - halfWidth + 2 * radius, + position.dy - halfHeight + 2 * radius, + ), + radians(180), + radians(90), + false, + ); + } + + _path.lineTo(position.dx + halfWidth - radius, position.dy - halfHeight); + + if (radius > 0) { + _path.arcTo( + Rect.fromLTRB( + position.dx + halfWidth - 2 * radius, + position.dy - halfHeight, + position.dx + halfWidth, + position.dy - halfHeight + 2 * radius, + ), + radians(270), + radians(90), + false, + ); + } + _path.close(); + + _trimPaths.apply(_path); + + _isPathValid = true; + return _path; + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.rectangleSize) { + _sizeAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.position) { + _positionAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } else if (property == LottieProperty.cornerRadius) { + _cornerRadiusAnimation.setValueCallback( + callback as LottieValueCallback?, + ); + } + } +} diff --git a/lottie/lib/src/animation/content/repeater_content.dart b/lottie/lib/src/animation/content/repeater_content.dart new file mode 100644 index 0000000..aeac934 --- /dev/null +++ b/lottie/lib/src/animation/content/repeater_content.dart @@ -0,0 +1,163 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/repeater.dart'; +import '../../model/key_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../utils/misc.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import '../keyframe/transform_keyframe_animation.dart'; +import 'content.dart'; +import 'content_group.dart'; +import 'drawing_content.dart'; +import 'greedy_content.dart'; +import 'key_path_element_content.dart'; +import 'path_content.dart'; + +class RepeaterContent + implements + DrawingContent, + PathContent, + GreedyContent, + KeyPathElementContent { + final Matrix4 _matrix = Matrix4.identity(); + final _path = Path(); + + final LottieDrawable lottieDrawable; + final BaseLayer layer; + final Repeater _repeater; + final BaseKeyframeAnimation _copies; + final BaseKeyframeAnimation _offset; + final TransformKeyframeAnimation _transform; + ContentGroup? _contentGroup; + + RepeaterContent(this.lottieDrawable, this.layer, this._repeater) + : _copies = _repeater.copies.createAnimation(), + _offset = _repeater.offset.createAnimation(), + _transform = _repeater.transform.createAnimation() { + layer.addAnimation(_copies); + _copies.addUpdateListener(_invalidate); + + layer.addAnimation(_offset); + _offset.addUpdateListener(_invalidate); + + _transform.addAnimationsToLayer(layer); + _transform.addListener(_invalidate); + } + + @override + void absorbContent(List contents) { + // This check prevents a repeater from getting added twice. + // This can happen in the following situation: + // RECTANGLE + // REPEATER 1 + // FILL + // REPEATER 2 + // In this case, the expected structure would be: + // REPEATER 2 + // REPEATER 1 + // RECTANGLE + // FILL + // Without this check, REPEATER 1 will try and absorb contents once it is already inside of + // REPEATER 2. + if (_contentGroup != null) { + return; + } + // Fast forward the iterator until after this content. + var index = contents.lastIndexOf(this) - 1; + var newContents = []; + while (index >= 0) { + var content = contents[index]; + newContents.add(content); + contents.removeAt(index); + --index; + } + newContents = newContents.reversed.toList(); + + _contentGroup = ContentGroup.copy( + lottieDrawable, + layer, + 'Repeater', + newContents, + null, + hidden: _repeater.hidden, + ); + } + + @override + String? get name => _repeater.name; + + @override + void setContents(List contentsBefore, List contentsAfter) { + _contentGroup!.setContents(contentsBefore, contentsAfter); + } + + @override + Path getPath() { + var contentPath = _contentGroup!.getPath(); + _path.reset(); + var copies = _copies.value; + var offset = _offset.value; + for (var i = copies.toInt() - 1; i >= 0; i--) { + _matrix.set(_transform.getMatrixForRepeater(i + offset)); + _path.addPath(contentPath, Offset.zero, matrix4: _matrix.storage); + } + return _path; + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + var copies = _copies.value; + var offset = _offset.value; + var startOpacity = _transform.startOpacity!.value / 100.0; + var endOpacity = _transform.endOpacity!.value / 100.0; + for (var i = copies.toInt() - 1; i >= 0; i--) { + _matrix.set(parentMatrix); + _matrix.preConcat(_transform.getMatrixForRepeater(i + offset)); + var newAlpha = + parentAlpha * lerpDouble(startOpacity, endOpacity, i / copies)!; + _contentGroup!.draw(canvas, _matrix, parentAlpha: newAlpha.round()); + } + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + return _contentGroup!.getBounds(parentMatrix, applyParents: applyParents); + } + + void _invalidate() { + lottieDrawable.invalidateSelf(); + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + MiscUtils.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + this, + ); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + if (_transform.applyValueCallback(property, callback)) { + return; + } + + if (property == LottieProperty.repeaterCopies) { + _copies.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.repeaterOffset) { + _offset.setValueCallback(callback as LottieValueCallback?); + } + } +} diff --git a/lottie/lib/src/animation/content/rounded_corners_content.dart b/lottie/lib/src/animation/content/rounded_corners_content.dart new file mode 100644 index 0000000..4a3c167 --- /dev/null +++ b/lottie/lib/src/animation/content/rounded_corners_content.dart @@ -0,0 +1,253 @@ +import 'dart:math' as math; +import 'dart:ui'; +import '../../lottie_drawable.dart'; +import '../../model/content/rounded_corners.dart'; +import '../../model/content/shape_data.dart'; +import '../../model/cubic_curve_data.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../utils/misc.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import 'content.dart'; +import 'shape_modifier_content.dart'; + +class RoundedCornersContent implements ShapeModifierContent { + /// Copied from: + /// https://github.com/airbnb/lottie-web/blob/bb71072a26e03f1ca993da60915860f39aae890b/player/js/utils/common.js#L47 + static const _roundedCornerMagicNumber = 0.5519; + + final LottieDrawable lottieDrawable; + + @override + final String name; + final BaseKeyframeAnimation roundedCorners; + ShapeData? shapeData; + + RoundedCornersContent( + this.lottieDrawable, + BaseLayer layer, + RoundedCorners roundedCorners, + ) : name = roundedCorners.name, + roundedCorners = roundedCorners.cornerRadius.createAnimation() { + layer.addAnimation(this.roundedCorners); + this.roundedCorners.addUpdateListener(_onValueChanged); + } + + void _onValueChanged() { + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + // Do nothing. + } + + /// Rounded corner algorithm: + /// Iterate through each vertex. + /// If a vertex is a sharp corner, it rounds it. + /// If a vertex has control points, it is already rounded, so it does nothing. + ///

+ /// To round a vertex: + /// Split the vertex into two. + /// Move vertex 1 directly towards the previous vertex. + /// Set vertex 1's in control point to itself so it is not rounded on that side. + /// Extend vertex 1's out control point towards the original vertex. + ///

+ /// Repeat for vertex 2: + /// Move vertex 2 directly towards the next vertex. + /// Set vertex 2's out point to itself so it is not rounded on that side. + /// Extend vertex 2's in control point towards the original vertex. + ///

+ /// The distance that the vertices and control points are moved are relative to the + /// shape's vertex distances and the roundedness set in the animation. + @override + ShapeData modifyShape(ShapeData startingShapeData) { + var startingCurves = startingShapeData.curves; + if (startingCurves.length <= 2) { + return startingShapeData; + } + var roundedness = roundedCorners.value; + if (roundedness == 0) { + return startingShapeData; + } + + var modifiedShapeData = _getShapeData(startingShapeData); + modifiedShapeData.setInitialPoint( + startingShapeData.initialPoint.dx, + startingShapeData.initialPoint.dy, + ); + var modifiedCurves = modifiedShapeData.curves; + var modifiedCurvesIndex = 0; + var isClosed = startingShapeData.isClosed; + + // i represents which vertex we are currently on. Refer to the docs of CubicCurveData prior to working with + // this code. + // When i == 0 + // vertex=ShapeData.initialPoint + // inCp=if closed vertex else curves[size - 1].cp2 + // outCp=curves[0].cp1 + // When i == 1 + // vertex=curves[0].vertex + // inCp=curves[0].cp2 + // outCp=curves[1].cp1. + // When i == size - 1 + // vertex=curves[size - 1].vertex + // inCp=curves[size - 1].cp2 + // outCp=if closed vertex else curves[0].cp1 + for (var i = 0; i < startingCurves.length; i++) { + var startingCurve = startingCurves[i]; + var previousCurve = + startingCurves[floorMod(i - 1, startingCurves.length)]; + var previousPreviousCurve = + startingCurves[floorMod(i - 2, startingCurves.length)]; + var vertex = (i == 0 && !isClosed) + ? startingShapeData.initialPoint + : previousCurve.vertex; + var inPoint = (i == 0 && !isClosed) + ? vertex + : previousCurve.controlPoint2; + var outPoint = startingCurve.controlPoint1; + var previousVertex = previousPreviousCurve.vertex; + var nextVertex = startingCurve.vertex; + + // We can't round the corner of the end of a non-closed curve. + var isEndOfCurve = + !startingShapeData.isClosed && + (i == 0 || i == startingCurves.length - 1); + if (inPoint == vertex && outPoint == vertex && !isEndOfCurve) { + // This vertex is a point. Round its corners + var dxToPreviousVertex = vertex.dx - previousVertex.dx; + var dyToPreviousVertex = vertex.dy - previousVertex.dy; + var dxToNextVertex = nextVertex.dx - vertex.dx; + var dyToNextVertex = nextVertex.dy - vertex.dy; + + var dToPreviousVertex = hypot(dxToPreviousVertex, dyToPreviousVertex); + var dToNextVertex = hypot(dxToNextVertex, dyToNextVertex); + + double previousVertexPercent = math.min( + roundedness / dToPreviousVertex, + 0.5, + ); + double nextVertexPercent = math.min(roundedness / dToNextVertex, 0.5); + + // Split the vertex into two and move each vertex towards the previous/next vertex. + var newVertex1X = + vertex.dx + (previousVertex.dx - vertex.dx) * previousVertexPercent; + var newVertex1Y = + vertex.dy + (previousVertex.dy - vertex.dy) * previousVertexPercent; + var newVertex2X = + vertex.dx + (nextVertex.dx - vertex.dx) * nextVertexPercent; + var newVertex2Y = + vertex.dy + (nextVertex.dy - vertex.dy) * nextVertexPercent; + + // Extend the new vertex control point towards the original vertex. + var newVertex1OutPointX = + newVertex1X - (newVertex1X - vertex.dx) * _roundedCornerMagicNumber; + var newVertex1OutPointY = + newVertex1Y - (newVertex1Y - vertex.dy) * _roundedCornerMagicNumber; + var newVertex2InPointX = + newVertex2X - (newVertex2X - vertex.dx) * _roundedCornerMagicNumber; + var newVertex2InPointY = + newVertex2Y - (newVertex2Y - vertex.dy) * _roundedCornerMagicNumber; + + // Remap vertex/in/out point to CubicCurveData. + // Refer to the docs for CubicCurveData for more info on the difference. + var previousCurveData = + modifiedCurves[floorMod( + modifiedCurvesIndex - 1, + modifiedCurves.length, + )]; + var currentCurveData = modifiedCurves[modifiedCurvesIndex]; + previousCurveData.controlPoint2 = Offset(newVertex1X, newVertex1Y); + previousCurveData.vertex = Offset(newVertex1X, newVertex1Y); + if (i == 0) { + modifiedShapeData.setInitialPoint(newVertex1X, newVertex1Y); + } + currentCurveData.controlPoint1 = Offset( + newVertex1OutPointX, + newVertex1OutPointY, + ); + modifiedCurvesIndex++; + + previousCurveData = currentCurveData; + currentCurveData = modifiedCurves[modifiedCurvesIndex]; + previousCurveData.controlPoint2 = Offset( + newVertex2InPointX, + newVertex2InPointY, + ); + previousCurveData.vertex = Offset(newVertex2X, newVertex2Y); + currentCurveData.controlPoint1 = Offset(newVertex2X, newVertex2Y); + modifiedCurvesIndex++; + } else { + // This vertex is not a point. Don't modify it. Refer to the documentation above and for CubicCurveData for mapping a vertex + // oriented point to CubicCurveData (path segments). + var previousCurveData = + modifiedCurves[floorMod( + modifiedCurvesIndex - 1, + modifiedCurves.length, + )]; + var currentCurveData = modifiedCurves[modifiedCurvesIndex]; + previousCurveData.controlPoint2 = Offset( + previousCurve.controlPoint2.dx, + previousCurve.controlPoint2.dy, + ); + previousCurveData.vertex = Offset( + previousCurve.vertex.dx, + previousCurve.vertex.dy, + ); + currentCurveData.controlPoint1 = Offset( + startingCurve.controlPoint1.dx, + startingCurve.controlPoint1.dy, + ); + modifiedCurvesIndex++; + } + } + return modifiedShapeData; + } + + /// Returns a shape data with the correct number of vertices for the rounded corners shape. + /// This just returns the object. It does not update any values within the shape. + + ShapeData _getShapeData(ShapeData startingShapeData) { + var startingCurves = startingShapeData.curves; + var isClosed = startingShapeData.isClosed; + var vertices = 0; + for (var i = startingCurves.length - 1; i >= 0; i--) { + var startingCurve = startingCurves[i]; + var previousCurve = + startingCurves[floorMod(i - 1, startingCurves.length)]; + var vertex = (i == 0 && !isClosed) + ? startingShapeData.initialPoint + : previousCurve.vertex; + var inPoint = (i == 0 && !isClosed) + ? vertex + : previousCurve.controlPoint2; + var outPoint = startingCurve.controlPoint1; + + var isEndOfCurve = + !startingShapeData.isClosed && + (i == 0 || i == startingCurves.length - 1); + if (inPoint == vertex && outPoint == vertex && !isEndOfCurve) { + vertices += 2; + } else { + vertices += 1; + } + } + var shapeData = this.shapeData; + if (shapeData == null || shapeData.curves.length != vertices) { + var newCurves = []; + for (var i = 0; i < vertices; i++) { + newCurves.add(CubicCurveData()); + } + this.shapeData = shapeData = ShapeData( + newCurves, + initialPoint: Offset.zero, + closed: false, + ); + } + shapeData.isClosed = isClosed; + return shapeData; + } + + static int floorMod(int x, int y) => MiscUtils.floorModInt(x, y); +} diff --git a/lottie/lib/src/animation/content/shape_content.dart b/lottie/lib/src/animation/content/shape_content.dart new file mode 100644 index 0000000..c7dc24b --- /dev/null +++ b/lottie/lib/src/animation/content/shape_content.dart @@ -0,0 +1,79 @@ +import 'dart:ui'; +import '../../lottie_drawable.dart'; +import '../../model/content/shape_path.dart'; +import '../../model/content/shape_trim_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../keyframe/shape_keyframe_animation.dart'; +import 'compound_trim_path_content.dart'; +import 'content.dart'; +import 'path_content.dart'; +import 'shape_modifier_content.dart'; +import 'trim_path_content.dart'; + +class ShapeContent implements PathContent { + final _path = Path(); + + final ShapePath _shape; + + final LottieDrawable lottieDrawable; + final ShapeKeyframeAnimation _shapeAnimation; + + bool _isPathValid = false; + final _trimPaths = CompoundTrimPathContent(); + + ShapeContent(this.lottieDrawable, BaseLayer layer, this._shape) + : _shapeAnimation = _shape.shapePath.createAnimation() { + layer.addAnimation(_shapeAnimation); + _shapeAnimation.addUpdateListener(_invalidate); + } + + void _invalidate() { + _isPathValid = false; + lottieDrawable.invalidateSelf(); + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + List? shapeModifierContents; + for (var i = 0; i < contentsBefore.length; i++) { + var content = contentsBefore[i]; + if (content is TrimPathContent && + content.type == ShapeTrimPathType.simultaneously) { + // Trim path individually will be handled by the stroke where paths are combined. + var trimPath = content; + _trimPaths.addTrimPath(trimPath); + trimPath.addListener(_invalidate); + } else if (content is ShapeModifierContent) { + shapeModifierContents ??= []; + shapeModifierContents.add(content); + } + } + _shapeAnimation.setShapeModifiers(shapeModifierContents); + } + + @override + String? get name => _shape.name; + + @override + Path getPath() { + if (_isPathValid) { + return _path; + } + + _path.reset(); + + if (_shape.hidden) { + _isPathValid = true; + return _path; + } + + _path.set(_shapeAnimation.value); + _path.fillType = PathFillType.evenOdd; + + _trimPaths.apply(_path); + + _isPathValid = true; + return _path; + } +} diff --git a/lottie/lib/src/animation/content/shape_modifier_content.dart b/lottie/lib/src/animation/content/shape_modifier_content.dart new file mode 100644 index 0000000..12daabe --- /dev/null +++ b/lottie/lib/src/animation/content/shape_modifier_content.dart @@ -0,0 +1,6 @@ +import '../../model/content/shape_data.dart'; +import 'content.dart'; + +abstract class ShapeModifierContent extends Content { + ShapeData modifyShape(ShapeData shapeData); +} diff --git a/lottie/lib/src/animation/content/stroke_content.dart b/lottie/lib/src/animation/content/stroke_content.dart new file mode 100644 index 0000000..fd02906 --- /dev/null +++ b/lottie/lib/src/animation/content/stroke_content.dart @@ -0,0 +1,76 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../model/content/shape_stroke.dart'; +import '../../model/layer/base_layer.dart'; +import '../../value/lottie_value_callback.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import '../keyframe/value_callback_keyframe_animation.dart'; +import 'base_stroke_content.dart'; + +class StrokeContent extends BaseStrokeContent { + @override + final String? name; + final bool _hidden; + final BaseKeyframeAnimation _colorAnimation; + BaseKeyframeAnimation? _colorFilterAnimation; + + StrokeContent( + LottieDrawable lottieDrawable, + BaseLayer layer, + ShapeStroke stroke, + ) : name = stroke.name, + _hidden = stroke.hidden, + _colorAnimation = stroke.color.createAnimation(), + super( + lottieDrawable, + layer, + cap: lineCapTypeToPaintCap(stroke.capType), + join: lineJoinTypeToPaintJoin(stroke.joinType), + miterLimit: stroke.miterLimit, + opacity: stroke.opacity, + width: stroke.width, + dashPattern: stroke.lineDashPattern, + dashOffset: stroke.dashOffset, + ) { + _colorAnimation.addUpdateListener(onUpdateListener); + layer.addAnimation(_colorAnimation); + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + if (_hidden) { + return; + } + paint.color = _colorAnimation.value.withAlpha( + (paint.color.a * 255).toInt(), + ); + if (_colorFilterAnimation != null) { + paint.colorFilter = _colorFilterAnimation!.value; + } + super.draw(canvas, parentMatrix, parentAlpha: parentAlpha); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + super.addValueCallback(property, callback); + if (property == LottieProperty.strokeColor) { + _colorAnimation.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.colorFilter) { + if (_colorFilterAnimation != null) { + layer.removeAnimation(_colorFilterAnimation); + } + + if (callback == null) { + _colorFilterAnimation = null; + } else { + _colorFilterAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + )..addUpdateListener(onUpdateListener); + layer.addAnimation(_colorAnimation); + } + } + } +} diff --git a/lottie/lib/src/animation/content/trim_path_content.dart b/lottie/lib/src/animation/content/trim_path_content.dart new file mode 100644 index 0000000..56737bb --- /dev/null +++ b/lottie/lib/src/animation/content/trim_path_content.dart @@ -0,0 +1,46 @@ +import '../../model/content/shape_trim_path.dart'; +import '../../model/layer/base_layer.dart'; +import '../keyframe/base_keyframe_animation.dart'; +import 'content.dart'; + +class TrimPathContent implements Content { + @override + final String? name; + final bool hidden; + final _listeners = []; + final ShapeTrimPathType? type; + final BaseKeyframeAnimation start; + final BaseKeyframeAnimation end; + final BaseKeyframeAnimation offset; + + TrimPathContent(BaseLayer layer, ShapeTrimPath trimPath) + : name = trimPath.name, + hidden = trimPath.hidden, + type = trimPath.type, + start = trimPath.start.createAnimation(), + end = trimPath.end.createAnimation(), + offset = trimPath.offset.createAnimation() { + layer.addAnimation(start); + layer.addAnimation(end); + layer.addAnimation(offset); + + start.addUpdateListener(_onValueChanged); + end.addUpdateListener(_onValueChanged); + offset.addUpdateListener(_onValueChanged); + } + + void _onValueChanged() { + for (var i = 0; i < _listeners.length; i++) { + _listeners[i](); + } + } + + @override + void setContents(List contentsBefore, List contentsAfter) { + // Do nothing. + } + + void addListener(void Function() listener) { + _listeners.add(listener); + } +} diff --git a/lottie/lib/src/animation/keyframe/base_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/base_keyframe_animation.dart new file mode 100644 index 0000000..c4defc1 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/base_keyframe_animation.dart @@ -0,0 +1,331 @@ +import 'package:flutter/foundation.dart'; +import '../../l.dart'; +import '../../value/keyframe.dart'; +import '../../value/lottie_value_callback.dart'; + +/// @param K Keyframe type +/// @param A Animation type +abstract class BaseKeyframeAnimation { + // This is not a Set because we don't want to create an iterator object on every setProgress. + final listeners = []; + bool _isDiscrete = false; + + final _KeyframesWrapper _keyframesWrapper; + double _progress = 0; + LottieValueCallback? valueCallback; + + A? _cachedGetValue; + + double _cachedStartDelayProgress = -1.0; + double _cachedEndProgress = -1.0; + + BaseKeyframeAnimation(List> keyframes) + : _keyframesWrapper = _wrap(keyframes); + + void setIsDiscrete() { + _isDiscrete = true; + } + + void addUpdateListener(void Function() listener) { + listeners.add(listener); + } + + void setProgress(double progress) { + if (_keyframesWrapper.isEmpty) { + return; + } + if (progress < getStartDelayProgress()) { + progress = getStartDelayProgress(); + } else if (progress > getEndProgress()) { + progress = getEndProgress(); + } + + if (progress == _progress) { + return; + } + _progress = progress; + if (_keyframesWrapper.isValueChanged(progress)) { + notifyListeners(); + } + } + + void notifyListeners() { + for (var listener in listeners) { + listener(); + } + } + + Keyframe getCurrentKeyframe() { + L.beginSection('BaseKeyframeAnimation#getCurrentKeyframe'); + final keyframe = _keyframesWrapper.getCurrentKeyframe(); + L.endSection('BaseKeyframeAnimation#getCurrentKeyframe'); + return keyframe; + } + + /// Returns the progress into the current keyframe between 0 and 1. This does not take into account + /// any interpolation that the keyframe may have. + double getLinearCurrentKeyframeProgress() { + if (_isDiscrete) { + return 0.0; + } + + var keyframe = getCurrentKeyframe(); + if (keyframe.isStatic) { + return 0.0; + } + var progressIntoFrame = _progress - keyframe.startProgress; + var keyframeProgress = keyframe.endProgress - keyframe.startProgress; + return (progressIntoFrame / keyframeProgress).clamp(0, 1); + } + + /// Takes the value of {@link #getLinearCurrentKeyframeProgress()} and interpolates it with + /// the current keyframe's interpolator. + double getInterpolatedCurrentKeyframeProgress() { + var keyframe = getCurrentKeyframe(); + if (keyframe.isStatic || keyframe.interpolator == null) { + return 0.0; + } + return keyframe.interpolator!.transform(getLinearCurrentKeyframeProgress()); + } + + double getStartDelayProgress() { + if (_cachedStartDelayProgress == -1) { + _cachedStartDelayProgress = _keyframesWrapper.getStartDelayProgress(); + } + return _cachedStartDelayProgress; + } + + double getEndProgress() { + if (_cachedEndProgress == -1) { + _cachedEndProgress = _keyframesWrapper.getEndProgress(); + } + return _cachedEndProgress; + } + + A get value { + A value; + + var linearProgress = getLinearCurrentKeyframeProgress(); + if (valueCallback == null && + _keyframesWrapper.isCachedValueEnabled(linearProgress)) { + return _cachedGetValue!; + } + + final keyframe = getCurrentKeyframe(); + if (keyframe.xInterpolator != null && keyframe.yInterpolator != null) { + var xProgress = keyframe.xInterpolator!.transform(linearProgress); + var yProgress = keyframe.yInterpolator!.transform(linearProgress); + value = getValueSplitDimension( + keyframe, + linearProgress, + xProgress, + yProgress, + ); + } else { + var progress = getInterpolatedCurrentKeyframeProgress(); + value = getValue(keyframe, progress); + } + + _cachedGetValue = value; + + return value; + } + + double get progress { + return _progress; + } + + @protected + set progress(double value) { + _progress = value; + } + + void setValueCallback(LottieValueCallback? valueCallback) { + if (this.valueCallback != null) { + this.valueCallback!.setAnimation(null); + } + this.valueCallback = valueCallback; + if (valueCallback != null) { + valueCallback.setAnimation(this); + } + } + + /// keyframeProgress will be [0, 1] unless the interpolator has overshoot in which case, this + /// should be able to handle values outside of that range. + A getValue(Keyframe keyframe, double keyframeProgress); + + A getValueSplitDimension( + Keyframe keyframe, + double linearKeyframeProgress, + double xKeyframeProgress, + double yKeyframeProgress, + ) { + throw Exception('This animation does not support split dimensions!'); + } + + static _KeyframesWrapper _wrap(List> keyframes) { + if (keyframes.isEmpty) { + return _EmptyKeyframeWrapper(); + } + if (keyframes.length == 1) { + return _SingleKeyframeWrapper(keyframes); + } + return _KeyframesWrapperImpl(keyframes); + } +} + +abstract class _KeyframesWrapper { + bool get isEmpty; + + bool isValueChanged(double progress); + + Keyframe getCurrentKeyframe(); + + double getStartDelayProgress(); + + double getEndProgress(); + + bool isCachedValueEnabled(double progress); +} + +class _EmptyKeyframeWrapper implements _KeyframesWrapper { + @override + bool get isEmpty { + return true; + } + + @override + bool isValueChanged(double progress) { + return false; + } + + @override + Keyframe getCurrentKeyframe() { + throw StateError('not implemented'); + } + + @override + double getStartDelayProgress() { + return 0; + } + + @override + double getEndProgress() { + return 1; + } + + @override + bool isCachedValueEnabled(double progress) { + throw StateError('not implemented'); + } +} + +class _SingleKeyframeWrapper implements _KeyframesWrapper { + final Keyframe keyframe; + double _cachedInterpolatedProgress = -1; + + _SingleKeyframeWrapper(List> keyframes) + : keyframe = keyframes.first; + + @override + bool get isEmpty { + return false; + } + + @override + bool isValueChanged(double progress) { + return !keyframe.isStatic; + } + + @override + Keyframe getCurrentKeyframe() { + return keyframe; + } + + @override + double getStartDelayProgress() { + return keyframe.startProgress; + } + + @override + double getEndProgress() { + return keyframe.endProgress; + } + + @override + bool isCachedValueEnabled(double progress) { + if (_cachedInterpolatedProgress == progress) { + return true; + } + _cachedInterpolatedProgress = progress; + return false; + } +} + +class _KeyframesWrapperImpl implements _KeyframesWrapper { + final List> keyframes; + Keyframe? _currentKeyframe; + Keyframe? _cachedCurrentKeyframe; + double _cachedInterpolatedProgress = -1; + + _KeyframesWrapperImpl(this.keyframes) { + _currentKeyframe = findKeyframe(0); + } + + @override + bool get isEmpty { + return false; + } + + @override + bool isValueChanged(double progress) { + if (_currentKeyframe!.containsProgress(progress)) { + return !_currentKeyframe!.isStatic; + } + _currentKeyframe = findKeyframe(progress); + return true; + } + + Keyframe findKeyframe(double progress) { + var keyframe = keyframes.last; + if (progress >= keyframe.startProgress) { + return keyframe; + } + for (var i = keyframes.length - 2; i >= 1; i--) { + keyframe = keyframes[i]; + if (_currentKeyframe == keyframe) { + continue; + } + if (keyframe.containsProgress(progress)) { + return keyframe; + } + } + return keyframes.first; + } + + @override + Keyframe getCurrentKeyframe() { + return _currentKeyframe!; + } + + @override + double getStartDelayProgress() { + return keyframes.first.startProgress; + } + + @override + double getEndProgress() { + return keyframes.last.endProgress; + } + + @override + bool isCachedValueEnabled(double progress) { + if (_cachedCurrentKeyframe == _currentKeyframe && + _cachedInterpolatedProgress == progress) { + return true; + } + _cachedCurrentKeyframe = _currentKeyframe; + _cachedInterpolatedProgress = progress; + return false; + } +} diff --git a/lottie/lib/src/animation/keyframe/color_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/color_keyframe_animation.dart new file mode 100644 index 0000000..d87c5c9 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/color_keyframe_animation.dart @@ -0,0 +1,38 @@ +import 'dart:ui'; +import '../../utils/gamma_evaluator.dart'; +import '../../value/keyframe.dart'; +import 'keyframe_animation.dart'; + +class ColorKeyframeAnimation extends KeyframeAnimation { + ColorKeyframeAnimation(super.keyframes); + + @override + Color getValue(Keyframe keyframe, double keyframeProgress) { + if (keyframe.startValue == null || keyframe.endValue == null) { + throw Exception('Missing values for keyframe.'); + } + var startColor = keyframe.startValue; + var endColor = keyframe.endValue; + + if (valueCallback != null) { + var value = valueCallback!.getValueInternal( + keyframe.startFrame, + keyframe.endFrame, + startColor, + endColor, + keyframeProgress, + getLinearCurrentKeyframeProgress(), + progress, + ); + if (value != null) { + return value; + } + } + + return GammaEvaluator.evaluate( + keyframeProgress.clamp(0, 1).toDouble(), + startColor!, + endColor!, + ); + } +} diff --git a/lottie/lib/src/animation/keyframe/double_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/double_keyframe_animation.dart new file mode 100644 index 0000000..e689a46 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/double_keyframe_animation.dart @@ -0,0 +1,35 @@ +import 'dart:ui'; +import '../../value/keyframe.dart'; +import 'keyframe_animation.dart'; + +class DoubleKeyframeAnimation extends KeyframeAnimation { + DoubleKeyframeAnimation(super.keyframes); + + @override + double getValue(Keyframe keyframe, double keyframeProgress) { + if (keyframe.startValue == null || keyframe.endValue == null) { + throw Exception('Missing values for keyframe.'); + } + + if (valueCallback != null) { + var value = valueCallback!.getValueInternal( + keyframe.startFrame, + keyframe.endFrame, + keyframe.startValue, + keyframe.endValue, + keyframeProgress, + getLinearCurrentKeyframeProgress(), + progress, + ); + if (value != null) { + return value; + } + } + + return lerpDouble( + keyframe.startValue, + keyframe.endValue, + keyframeProgress, + )!; + } +} diff --git a/lottie/lib/src/animation/keyframe/drop_shadow_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/drop_shadow_keyframe_animation.dart new file mode 100644 index 0000000..7655946 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/drop_shadow_keyframe_animation.dart @@ -0,0 +1,117 @@ +import 'dart:math' as math; +import 'dart:ui'; +import '../../lottie_property.dart'; +import '../../model/content/drop_shadow_effect.dart'; +import '../../model/layer/base_layer.dart'; +import '../../value/drop_shadow.dart'; +import '../../value/lottie_frame_info.dart'; +import '../../value/lottie_value_callback.dart'; +import 'base_keyframe_animation.dart'; +import 'color_keyframe_animation.dart'; + +class DropShadowKeyframeAnimation { + static const double _degToRad = math.pi / 180.0; + + final void Function() listener; + late final ColorKeyframeAnimation _color; + late final BaseKeyframeAnimation _opacity; + late final BaseKeyframeAnimation _direction; + late final BaseKeyframeAnimation _distance; + late final BaseKeyframeAnimation _radius; + + Paint? _paint; + + DropShadowKeyframeAnimation( + this.listener, + BaseLayer layer, + DropShadowEffect dropShadowEffect, + ) { + _color = dropShadowEffect.color.createAnimation() + ..addUpdateListener(onValueChanged); + layer.addAnimation(_color); + _opacity = dropShadowEffect.opacity.createAnimation() + ..addUpdateListener(onValueChanged); + layer.addAnimation(_opacity); + _direction = dropShadowEffect.direction.createAnimation() + ..addUpdateListener(onValueChanged); + layer.addAnimation(_direction); + _distance = dropShadowEffect.distance.createAnimation() + ..addUpdateListener(onValueChanged); + layer.addAnimation(_distance); + _radius = dropShadowEffect.radius.createAnimation() + ..addUpdateListener(onValueChanged); + layer.addAnimation(_radius); + } + + void onValueChanged() { + _paint = null; + listener(); + } + + void draw(Canvas canvas, Path path) { + var directionRad = _direction.value * _degToRad; + var distance = _distance.value; + var x = math.sin(directionRad) * distance; + var y = math.cos(directionRad + math.pi) * distance; + var baseColor = _color.value; + var opacity = _opacity.value.round(); + var color = baseColor.withAlpha(opacity); + var radius = _radius.value; + + var sigma = radius * 0.57735 + 0.5; + + var paint = _paint; + paint ??= _paint = Paint() + ..color = color + ..maskFilter = MaskFilter.blur(BlurStyle.normal, sigma); + + canvas.drawPath(path.shift(Offset(x, y)), paint); + } + + void setCallback(LottieValueCallback? callback) { + if (callback != null) { + _color.setValueCallback( + _createCallback(callback, (c) => c?.color ?? const Color(0xff000000)), + ); + _opacity.setValueCallback( + _createCallback(callback, (c) => c?.color.a ?? 1), + ); + _direction.setValueCallback( + _createCallback(callback, (c) => c?.direction ?? 0), + ); + _distance.setValueCallback( + _createCallback(callback, (c) => c?.distance ?? 0), + ); + _radius.setValueCallback( + _createCallback(callback, (c) => c?.radius ?? 0), + ); + } else { + _color.setValueCallback(null); + _opacity.setValueCallback(null); + _direction.setValueCallback(null); + _distance.setValueCallback(null); + _radius.setValueCallback(null); + } + } + + LottieValueCallback _createCallback( + LottieValueCallback callback, + T Function(DropShadow?) selector, + ) { + return LottieValueCallback(null) + ..callback = (info) { + onValueChanged(); + var frameInfo = LottieFrameInfo( + info.startFrame, + info.endFrame, + LottieProperty.dropShadow, + LottieProperty.dropShadow, + info.linearKeyframeProgress, + info.interpolatedKeyframeProgress, + info.overallProgress, + ); + var dropShadow = callback.getValue(frameInfo); + return selector(dropShadow); + }; + } +} diff --git a/lottie/lib/src/animation/keyframe/gradient_color_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/gradient_color_keyframe_animation.dart new file mode 100644 index 0000000..20df218 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/gradient_color_keyframe_animation.dart @@ -0,0 +1,41 @@ +import 'dart:math' as math; +import 'dart:ui'; +import '../../model/content/gradient_color.dart'; +import '../../value/keyframe.dart'; +import 'keyframe_animation.dart'; + +class GradientColorKeyframeAnimation extends KeyframeAnimation { + late GradientColor _gradientColor; + + GradientColorKeyframeAnimation(List> keyframes) + : super(keyframes) { + // Not all keyframes that this GradientColor are used for will have the same length. + // AnimatableGradientColorValue.ensureInterpolatableKeyframes may add extra positions + // for some keyframes but not others to ensure that it is interpolatable. + // Ensure that there is enough space for the largest keyframe. + var size = 0; + for (var i = 0; i < keyframes.length; i++) { + var startValue = keyframes[i].startValue; + if (startValue != null) { + size = math.max(size, startValue.size); + } + } + _gradientColor = GradientColor( + List.filled(size, 0.0), + List.filled(size, const Color(0x00000000)), + ); + } + + @override + GradientColor getValue( + Keyframe keyframe, + double keyframeProgress, + ) { + _gradientColor.lerp( + keyframe.startValue!, + keyframe.endValue!, + keyframeProgress, + ); + return _gradientColor; + } +} diff --git a/lottie/lib/src/animation/keyframe/integer_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/integer_keyframe_animation.dart new file mode 100644 index 0000000..e615f41 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/integer_keyframe_animation.dart @@ -0,0 +1,33 @@ +import 'dart:ui'; +import '../../value/keyframe.dart'; +import 'keyframe_animation.dart'; + +class IntegerKeyframeAnimation extends KeyframeAnimation { + IntegerKeyframeAnimation(super.keyframes); + + @override + int getValue(Keyframe keyframe, double keyframeProgress) { + if (keyframe.startValue == null) { + throw Exception('Missing values for keyframe.'); + } + + var endValue = keyframe.endValue ?? keyframe.startValue; + + if (valueCallback != null) { + var value = valueCallback!.getValueInternal( + keyframe.startFrame, + keyframe.endFrame, + keyframe.startValue, + endValue, + keyframeProgress, + getLinearCurrentKeyframeProgress(), + progress, + ); + if (value != null) { + return value; + } + } + + return lerpDouble(keyframe.startValue, endValue, keyframeProgress)!.round(); + } +} diff --git a/lottie/lib/src/animation/keyframe/keyframe_animation.dart b/lottie/lib/src/animation/keyframe/keyframe_animation.dart new file mode 100644 index 0000000..790d98e --- /dev/null +++ b/lottie/lib/src/animation/keyframe/keyframe_animation.dart @@ -0,0 +1,6 @@ +import 'base_keyframe_animation.dart'; + +abstract class KeyframeAnimation + extends BaseKeyframeAnimation { + KeyframeAnimation(super.keyframes); +} diff --git a/lottie/lib/src/animation/keyframe/mask_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/mask_keyframe_animation.dart new file mode 100644 index 0000000..c083802 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/mask_keyframe_animation.dart @@ -0,0 +1,17 @@ +import 'dart:ui'; +import '../../model/content/mask.dart'; +import '../../model/content/shape_data.dart'; +import 'base_keyframe_animation.dart'; + +class MaskKeyframeAnimation { + final maskAnimations = >[]; + final opacityAnimations = >[]; + final List masks; + + MaskKeyframeAnimation(this.masks) { + for (var mask in masks) { + maskAnimations.add(mask.maskPath.createAnimation()); + opacityAnimations.add(mask.opacity.createAnimation()); + } + } +} diff --git a/lottie/lib/src/animation/keyframe/path_keyframe.dart b/lottie/lib/src/animation/keyframe/path_keyframe.dart new file mode 100644 index 0000000..97c4761 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/path_keyframe.dart @@ -0,0 +1,40 @@ +import 'dart:ui'; +import '../../composition.dart'; +import '../../utils/utils.dart'; +import '../../value/keyframe.dart'; + +class PathKeyframe extends Keyframe { + Path? _path; + final Keyframe _pointKeyFrame; + + PathKeyframe(LottieComposition super.composition, Keyframe keyframe) + : _pointKeyFrame = keyframe, + super( + startValue: keyframe.startValue, + endValue: keyframe.endValue, + interpolator: keyframe.interpolator, + xInterpolator: keyframe.xInterpolator, + yInterpolator: keyframe.yInterpolator, + startFrame: keyframe.startFrame, + endFrame: keyframe.endFrame, + ); + + Path? _createPath() { + var equals = + endValue != null && startValue != null && startValue == endValue; + if (startValue != null && endValue != null && !equals) { + return Utils.createPath( + startValue!, + endValue!, + _pointKeyFrame.pathCp1, + _pointKeyFrame.pathCp2, + ); + } + return null; + } + + /// This will be null if the startValue and endValue are the same. + Path? getPath() { + return _path ??= _createPath(); + } +} diff --git a/lottie/lib/src/animation/keyframe/path_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/path_keyframe_animation.dart new file mode 100644 index 0000000..713c15f --- /dev/null +++ b/lottie/lib/src/animation/keyframe/path_keyframe_animation.dart @@ -0,0 +1,58 @@ +import 'dart:ui'; +import '../../value/keyframe.dart'; +import 'keyframe_animation.dart'; +import 'path_keyframe.dart'; + +class PathKeyframeAnimation extends KeyframeAnimation { + PathKeyframe? _pathMeasureKeyframe; + late PathMetric _pathMeasure; + + PathKeyframeAnimation(super.keyframes); + + @override + Offset getValue(Keyframe keyframe, double keyframeProgress) { + var pathKeyframe = keyframe as PathKeyframe; + var path = pathKeyframe.getPath(); + if (path == null) { + return keyframe.startValue!; + } + + if (valueCallback != null) { + var value = valueCallback!.getValueInternal( + pathKeyframe.startFrame, + pathKeyframe.endFrame, + pathKeyframe.startValue, + pathKeyframe.endValue, + getLinearCurrentKeyframeProgress(), + keyframeProgress, + progress, + ); + if (value != null) { + return value; + } + } + + if (_pathMeasureKeyframe != pathKeyframe) { + _pathMeasure = path.computeMetrics().toList().first; + _pathMeasureKeyframe = pathKeyframe; + } + + var length = _pathMeasure.length; + + // allow bounce easings to calculate positions outside the path + // by using the tangent at the extremities + + if (keyframeProgress < 0) { + var tangent = _pathMeasure.getTangentForOffset(0)!; + return tangent.position + tangent.vector * (keyframeProgress * length); + } else if (keyframeProgress > 1) { + var tangent = _pathMeasure.getTangentForOffset(length)!; + return tangent.position + + tangent.vector * ((keyframeProgress - 1) * length); + } else { + return _pathMeasure + .getTangentForOffset(keyframeProgress * length)! + .position; + } + } +} diff --git a/lottie/lib/src/animation/keyframe/point_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/point_keyframe_animation.dart new file mode 100644 index 0000000..af5882c --- /dev/null +++ b/lottie/lib/src/animation/keyframe/point_keyframe_animation.dart @@ -0,0 +1,52 @@ +import 'dart:ui'; +import '../../value/keyframe.dart'; +import 'keyframe_animation.dart'; + +class PointKeyframeAnimation extends KeyframeAnimation { + PointKeyframeAnimation(super.keyframes); + + @override + Offset getValue(Keyframe keyframe, double keyframeProgress) { + return getValueSplitDimension( + keyframe, + keyframeProgress, + keyframeProgress, + keyframeProgress, + ); + } + + @override + Offset getValueSplitDimension( + Keyframe keyframe, + double linearKeyframeProgress, + double xKeyframeProgress, + double yKeyframeProgress, + ) { + if (keyframe.startValue == null || keyframe.endValue == null) { + throw Exception('Missing values for keyframe.'); + } + + var startPoint = keyframe.startValue!; + var endPoint = keyframe.endValue!; + + if (valueCallback != null) { + var value = valueCallback!.getValueInternal( + keyframe.startFrame, + keyframe.endFrame, + startPoint, + endPoint, + linearKeyframeProgress, + getLinearCurrentKeyframeProgress(), + progress, + ); + if (value != null) { + return value; + } + } + + return Offset( + startPoint.dx + xKeyframeProgress * (endPoint.dx - startPoint.dx), + startPoint.dy + yKeyframeProgress * (endPoint.dy - startPoint.dy), + ); + } +} diff --git a/lottie/lib/src/animation/keyframe/shape_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/shape_keyframe_animation.dart new file mode 100644 index 0000000..5ee13d6 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/shape_keyframe_animation.dart @@ -0,0 +1,39 @@ +import 'dart:ui'; +import '../../model/content/shape_data.dart'; +import '../../utils/misc.dart'; +import '../../value/keyframe.dart'; +import '../content/shape_modifier_content.dart'; +import 'base_keyframe_animation.dart'; + +class ShapeKeyframeAnimation extends BaseKeyframeAnimation { + final ShapeData _tempShapeData = ShapeData.empty(); + final Path _tempPath = Path(); + List? _shapeModifiers; + + ShapeKeyframeAnimation(super.keyframes); + + @override + Path getValue(Keyframe keyframe, double keyframeProgress) { + var startShapeData = keyframe.startValue!; + var endShapeData = keyframe.endValue ?? startShapeData; + + _tempShapeData.interpolateBetween( + startShapeData, + endShapeData, + keyframeProgress, + ); + var modifiedShapeData = _tempShapeData; + var shapeModifiers = _shapeModifiers; + if (shapeModifiers != null) { + for (var i = shapeModifiers.length - 1; i >= 0; i--) { + modifiedShapeData = shapeModifiers[i].modifyShape(modifiedShapeData); + } + } + MiscUtils.getPathFromData(modifiedShapeData, _tempPath); + return _tempPath; + } + + void setShapeModifiers(List? shapeModifiers) { + _shapeModifiers = shapeModifiers; + } +} diff --git a/lottie/lib/src/animation/keyframe/split_dimension_path_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/split_dimension_path_keyframe_animation.dart new file mode 100644 index 0000000..ae4ebc5 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/split_dimension_path_keyframe_animation.dart @@ -0,0 +1,36 @@ +import 'dart:ui'; +import '../../value/keyframe.dart'; +import 'base_keyframe_animation.dart'; + +class SplitDimensionPathKeyframeAnimation + extends BaseKeyframeAnimation { + late Offset _point; + final BaseKeyframeAnimation _xAnimation; + final BaseKeyframeAnimation _yAnimation; + + SplitDimensionPathKeyframeAnimation(this._xAnimation, this._yAnimation) + : super(>[]) { + // We need to call an initial setProgress so point gets set with the initial value. + setProgress(progress); + } + + @override + void setProgress(double progress) { + _xAnimation.setProgress(progress); + _yAnimation.setProgress(progress); + _point = Offset(_xAnimation.value, _yAnimation.value); + for (var i = 0; i < listeners.length; i++) { + listeners[i](); + } + } + + @override + Offset get value { + return _point; + } + + @override + Offset getValue(Keyframe keyframe, double keyframeProgress) { + return _point; + } +} diff --git a/lottie/lib/src/animation/keyframe/text_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/text_keyframe_animation.dart new file mode 100644 index 0000000..bcf6c45 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/text_keyframe_animation.dart @@ -0,0 +1,74 @@ +import '../../model/document_data.dart'; +import '../../value/keyframe.dart'; +import '../../value/lottie_frame_info.dart'; +import '../../value/lottie_value_callback.dart'; +import 'keyframe_animation.dart'; + +class TextKeyframeAnimation extends KeyframeAnimation { + TextKeyframeAnimation(super.keyframes); + + @override + DocumentData getValue( + Keyframe keyframe, + double keyframeProgress, + ) { + var valueCallback = this.valueCallback; + if (valueCallback != null) { + return valueCallback.getValueInternal( + keyframe.startFrame, + keyframe.endFrame ?? double.maxFinite, + keyframe.startValue, + keyframe.endValue ?? keyframe.startValue, + keyframeProgress, + getInterpolatedCurrentKeyframeProgress(), + progress, + )!; + } else if (keyframeProgress != 1.0 || keyframe.endValue == null) { + return keyframe.startValue!; + } else { + return keyframe.endValue!; + } + } + + void setStringValueCallback(LottieValueCallback valueCallback) { + super.setValueCallback(_DocumentDataValueCallback(valueCallback)); + } +} + +class _DocumentDataValueCallback extends LottieValueCallback { + final LottieValueCallback valueCallback; + + _DocumentDataValueCallback(this.valueCallback) : super(null); + + @override + DocumentData getValue(LottieFrameInfo frameInfo) { + var stringFrameInfo = LottieFrameInfo( + frameInfo.startFrame, + frameInfo.endFrame, + frameInfo.startValue!.text, + frameInfo.endValue!.text, + frameInfo.linearKeyframeProgress, + frameInfo.interpolatedKeyframeProgress, + frameInfo.overallProgress, + ); + var text = valueCallback.getValue(stringFrameInfo)!; + var baseDocumentData = frameInfo.interpolatedKeyframeProgress == 1 + ? frameInfo.endValue! + : frameInfo.startValue!; + return DocumentData( + text: text, + fontName: baseDocumentData.fontName, + size: baseDocumentData.size, + justification: baseDocumentData.justification, + tracking: baseDocumentData.tracking, + lineHeight: baseDocumentData.lineHeight, + baselineShift: baseDocumentData.baselineShift, + color: baseDocumentData.color, + strokeColor: baseDocumentData.strokeColor, + strokeWidth: baseDocumentData.strokeWidth, + strokeOverFill: baseDocumentData.strokeOverFill, + boxPosition: baseDocumentData.boxPosition, + boxSize: baseDocumentData.boxSize, + ); + } +} diff --git a/lottie/lib/src/animation/keyframe/transform_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/transform_keyframe_animation.dart new file mode 100644 index 0000000..8b4baac --- /dev/null +++ b/lottie/lib/src/animation/keyframe/transform_keyframe_animation.dart @@ -0,0 +1,344 @@ +import 'dart:math' hide Point, Rectangle; +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../lottie_property.dart'; +import '../../model/animatable/animatable_transform.dart'; +import '../../model/layer/base_layer.dart'; +import '../../utils.dart'; +import '../../value/keyframe.dart'; +import '../../value/lottie_value_callback.dart'; +import 'base_keyframe_animation.dart'; +import 'double_keyframe_animation.dart'; +import 'value_callback_keyframe_animation.dart'; + +class TransformKeyframeAnimation { + TransformKeyframeAnimation(AnimatableTransform animatableTransform) + : _skewMatrix1 = animatableTransform.skew == null + ? null + : Matrix4.identity(), + _skewMatrix2 = animatableTransform.skew == null + ? null + : Matrix4.identity(), + _skewMatrix3 = animatableTransform.skew == null + ? null + : Matrix4.identity(), + _anchorPoint = animatableTransform.anchorPoint?.createAnimation(), + _position = animatableTransform.position?.createAnimation(), + _scale = animatableTransform.scale?.createAnimation(), + _rotation = animatableTransform.rotation?.createAnimation(), + _autoOrient = animatableTransform.isAutoOrient, + _skew = animatableTransform.skew?.createAnimation(), + _skewAngle = animatableTransform.skewAngle?.createAnimation(), + _opacity = animatableTransform.opacity?.createAnimation(), + _startOpacity = animatableTransform.startOpacity?.createAnimation(), + _endOpacity = animatableTransform.endOpacity?.createAnimation(); + + final _matrix = Matrix4.identity(); + final Matrix4? _skewMatrix1; + final Matrix4? _skewMatrix2; + final Matrix4? _skewMatrix3; + + BaseKeyframeAnimation? _anchorPoint; + BaseKeyframeAnimation? _position; + BaseKeyframeAnimation? _scale; + BaseKeyframeAnimation? _rotation; + DoubleKeyframeAnimation? _skew; + DoubleKeyframeAnimation? _skewAngle; + + BaseKeyframeAnimation? _opacity; + BaseKeyframeAnimation? get opacity => _opacity; + + BaseKeyframeAnimation? _startOpacity; + BaseKeyframeAnimation? get startOpacity => _startOpacity; + + BaseKeyframeAnimation? _endOpacity; + BaseKeyframeAnimation? get endOpacity => _endOpacity; + + final bool _autoOrient; + + void addAnimationsToLayer(BaseLayer layer) { + layer.addAnimation(_opacity); + layer.addAnimation(_startOpacity); + layer.addAnimation(_endOpacity); + + layer.addAnimation(_anchorPoint); + layer.addAnimation(_position); + layer.addAnimation(_scale); + layer.addAnimation(_rotation); + layer.addAnimation(_skew); + layer.addAnimation(_skewAngle); + } + + void addListener(void Function() listener) { + _opacity?.addUpdateListener(listener); + _startOpacity?.addUpdateListener(listener); + _endOpacity?.addUpdateListener(listener); + _anchorPoint?.addUpdateListener(listener); + _position?.addUpdateListener(listener); + _scale?.addUpdateListener(listener); + _rotation?.addUpdateListener(listener); + _skew?.addUpdateListener(listener); + _skewAngle?.addUpdateListener(listener); + } + + void setProgress(double progress) { + _opacity?.setProgress(progress); + _startOpacity?.setProgress(progress); + _endOpacity?.setProgress(progress); + _anchorPoint?.setProgress(progress); + _position?.setProgress(progress); + _scale?.setProgress(progress); + _rotation?.setProgress(progress); + _skew?.setProgress(progress); + _skewAngle?.setProgress(progress); + } + + Matrix4 getMatrix() { + _matrix.reset(); + + if (_position != null) { + final position = _position!.value; + if (position.dx != 0 || position.dy != 0) { + _matrix.translateByDouble(position.dx, position.dy, 0, 1); + } + } + + // If autoOrient is true, the rotation should follow the derivative of the position rather + // than the rotation property. + if (_autoOrient) { + if (_position case var position?) { + var currentProgress = position.progress; + var startPosition = position.value; + // Store the start X and Y values because the pointF will be overwritten by the next getValue call. + var startX = startPosition.dx; + var startY = startPosition.dy; + // 1) Find the next position value. + // 2) Create a vector from the current position to the next position. + // 3) Find the angle of that vector to the X axis (0 degrees). + position.setProgress(currentProgress + 0.0001); + var nextPosition = position.value; + position.setProgress(currentProgress); + var rotationValue = degrees( + atan2(nextPosition.dy - startY, nextPosition.dx - startX), + ); + _matrix.rotateZ(rotationValue); + } + } else { + if (_rotation != null) { + final rotation = _rotation!.value; + if (rotation != 0) { + _matrix.rotateZ(rotation * pi / 180.0); + } + } + } + + if (_skew != null) { + final mCos = _skewAngle == null + ? 0.0 + : cos(radians(-_skewAngle!.value + 90)); + final mSin = _skewAngle == null + ? 1.0 + : sin(radians(-_skewAngle!.value + 90)); + final aTan = tan(radians(_skew!.value)); + + _skewMatrix1!.setValues( + mCos, + mSin, + 0, + 0, + -mSin, + mCos, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, // + ); + + _skewMatrix2!.setValues( + 1, + 0, + 0, + 0, + aTan, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, // + ); + + _skewMatrix3!.setValues( + mCos, + -mSin, + 0, + 0, + mSin, + mCos, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, // + ); + + _skewMatrix2.multiply(_skewMatrix1); + _skewMatrix3.multiply(_skewMatrix2); + _matrix.multiply(_skewMatrix3); + } + + if (_scale != null) { + final scale = _scale!.value; + if (scale.dx != 1 || scale.dy != 1) { + _matrix.scaleByDouble(scale.dx, scale.dy, scale.dx, 1); + } + } + + if (_anchorPoint != null) { + final anchorPoint = _anchorPoint!.value; + if (anchorPoint.dx != 0 || anchorPoint.dy != 0) { + _matrix.translateByDouble(-anchorPoint.dx, -anchorPoint.dy, 0, 1); + } + } + + return _matrix; + } + + /// TODO: see if we can use this for the main {@link #getMatrix()} method. + Matrix4 getMatrixForRepeater(double amount) { + final position = _position?.value; + final scale = _scale?.value; + + _matrix.setIdentity(); + + if (position != null) { + _matrix.translateByDouble( + position.dx * amount, + position.dy * amount, + 0, + 1, + ); + } + + if (scale != null) { + _matrix.scaleByDouble( + pow(scale.dx, amount).toDouble(), + pow(scale.dy, amount).toDouble(), + pow(scale.dx, amount).toDouble(), + 1, + ); + } + + if (_rotation != null) { + var rotation = _rotation!.value; + var anchorPoint = _anchorPoint?.value; + _matrix.rotate( + Vector3( + anchorPoint == null ? 0.0 : anchorPoint.dx, + anchorPoint == null ? 0.0 : anchorPoint.dy, + 1.0, + ), + radians(rotation * amount), + ); + } + + return _matrix; + } + + bool applyValueCallback(T property, LottieValueCallback? callback) { + if (property == LottieProperty.transformAnchorPoint) { + if (_anchorPoint == null) { + _anchorPoint = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + Offset.zero, + ); + } else { + _anchorPoint!.setValueCallback( + callback as LottieValueCallback?, + ); + } + } else if (property == LottieProperty.transformPosition) { + if (_position == null) { + _position = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + Offset.zero, + ); + } else { + _position!.setValueCallback(callback as LottieValueCallback?); + } + } else if (property == LottieProperty.transformScale) { + if (_scale == null) { + _scale = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + const Offset(1, 1), + ); + } else { + _scale!.setValueCallback(callback as LottieValueCallback?); + } + } else if (property == LottieProperty.transformRotation) { + if (_rotation == null) { + _rotation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + 0.0, + ); + } else { + _rotation!.setValueCallback(callback as LottieValueCallback?); + } + } else if (property == LottieProperty.transformOpacity) { + if (_opacity == null) { + _opacity = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + 100, + ); + } else { + _opacity!.setValueCallback(callback as LottieValueCallback?); + } + } else if (property == LottieProperty.transformStartOpacity) { + if (_startOpacity == null) { + _startOpacity = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + 100, + ); + } else { + _startOpacity!.setValueCallback( + callback as LottieValueCallback?, + ); + } + } else if (property == LottieProperty.transformEndOpacity) { + if (_endOpacity == null) { + _endOpacity = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback?, + 100, + ); + } else { + _endOpacity!.setValueCallback(callback as LottieValueCallback?); + } + } else if (property == LottieProperty.transformSkew) { + _skew ??= DoubleKeyframeAnimation([Keyframe.nonAnimated(0.0)]); + _skew!.setValueCallback(callback as LottieValueCallback?); + } else if (property == LottieProperty.transformSkewAngle) { + _skewAngle ??= DoubleKeyframeAnimation([Keyframe.nonAnimated(0.0)]); + _skewAngle!.setValueCallback(callback as LottieValueCallback?); + } else { + return false; + } + + return true; + } +} diff --git a/lottie/lib/src/animation/keyframe/value_callback_keyframe_animation.dart b/lottie/lib/src/animation/keyframe/value_callback_keyframe_animation.dart new file mode 100644 index 0000000..87a7316 --- /dev/null +++ b/lottie/lib/src/animation/keyframe/value_callback_keyframe_animation.dart @@ -0,0 +1,53 @@ +import '../../value/keyframe.dart'; +import '../../value/lottie_value_callback.dart'; +import 'base_keyframe_animation.dart'; + +class ValueCallbackKeyframeAnimation + extends BaseKeyframeAnimation { + final A valueCallbackValue; + + ValueCallbackKeyframeAnimation( + LottieValueCallback? valueCallback, + this.valueCallbackValue, + ) : super([]) { + setValueCallback(valueCallback); + } + + @override + void setProgress(double progress) { + this.progress = progress; + } + + /// If this doesn't return 1, then {@link #setProgress(float)} will always clamp the progress + /// to 0. + @override + double getEndProgress() { + return 1.0; + } + + @override + void notifyListeners() { + if (valueCallback != null) { + super.notifyListeners(); + } + } + + @override + A get value { + return valueCallback!.getValueInternal( + 0.0, + 0.0, + valueCallbackValue, + valueCallbackValue, + progress, + progress, + progress, + ) ?? + valueCallbackValue; + } + + @override + A getValue(Keyframe keyframe, double keyframeProgress) { + return value; + } +} diff --git a/lottie/lib/src/composition.dart b/lottie/lib/src/composition.dart new file mode 100644 index 0000000..b5a2b7a --- /dev/null +++ b/lottie/lib/src/composition.dart @@ -0,0 +1,271 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'package:archive/archive.dart'; +import 'package:flutter/widgets.dart'; +import 'package:path/path.dart' as p; +import 'frame_rate.dart'; +import 'lottie_image_asset.dart'; +import 'model/font.dart'; +import 'model/font_character.dart'; +import 'model/layer/layer.dart'; +import 'model/marker.dart'; +import 'parser/lottie_composition_parser.dart'; +import 'parser/moshi/json_reader.dart'; +import 'performance_tracker.dart'; +import 'providers/load_image.dart'; +import 'utils.dart'; + +typedef WarningCallback = void Function(String); + +/// A function that knows how to transform a list of bytes to a `LottieComposition` +typedef LottieDecoder = Future Function(List bytes); + +class CompositionParameters { + MutableRectangle bounds = MutableRectangle(0, 0, 0, 0); + double startFrame = 0.0; + double endFrame = 0; + double frameRate = 0; + final layers = []; + final layerMap = {}; + final precomps = >{}; + final images = {}; + final characters = {}; + final fonts = {}; + final markers = []; + + static CompositionParameters forComposition(LottieComposition composition) => + composition._parameters; +} + +class LottieComposition { + static LottieComposition parseJsonBytes(List bytes) { + return LottieCompositionParser.parse( + LottieComposition._(), + JsonReader.fromBytes(bytes), + ); + } + + static Future fromByteData( + ByteData data, { + LottieDecoder? decoder, + }) { + return fromBytes(data.buffer.asUint8List(), decoder: decoder); + } + + static Future fromBytes( + List bytes, { + LottieDecoder? decoder, + }) async { + decoder ??= decodeZip; + + var compositionFuture = await decoder(bytes); + if (compositionFuture != null) { + return compositionFuture; + } + return parseJsonBytes(bytes); + } + + static Future decodeZip( + List bytes, { + LottieImageProviderFactory? imageProviderFactory, + ArchiveFile? Function(List)? filePicker, + }) async { + if (bytes[0] == 0x50 && bytes[1] == 0x4B) { + var archive = ZipDecoder().decodeBytes(bytes); + + ArchiveFile? jsonFile; + if (filePicker != null) { + jsonFile = filePicker(archive.files); + } + jsonFile ??= archive.files.firstWhere((e) => e.name.endsWith('.json')); + + var composition = parseJsonBytes(jsonFile.content); + + for (var image in composition.images.values) { + var imagePath = p.posix.join(image.dirName, image.fileName); + var found = archive.files.firstWhereOrNull( + (f) => f.name.toLowerCase() == imagePath.toLowerCase(), + ); + + ImageProvider? provider; + if (imageProviderFactory != null) { + provider = imageProviderFactory(image); + } + + if (provider != null) { + image.loadedImage = await loadImage(composition, image, provider); + } + + if (found != null) { + image.loadedImage ??= await loadImage( + composition, + image, + MemoryImage(found.content), + ); + } + } + + for (var font in archive.files.where((f) => f.name.endsWith('.ttf'))) { + var fileName = p.basenameWithoutExtension(font.name).toLowerCase(); + var existingFont = composition.fonts.values.firstWhereOrNull( + (f) => f.family.toLowerCase() == fileName, + ); + composition._fontsToLoad.add( + FontToLoad(font.content, family: existingFont?.family), + ); + } + return composition; + } + return null; + } + + static Future decodeGZip(List bytes) async { + if (bytes[0] == 31 && bytes[1] == 139) { + var decodedBytes = GZipDecoder().decodeBytes(bytes); + return LottieComposition.parseJsonBytes(decodedBytes); + } + return null; + } + + LottieComposition._(); + + final _performanceTracker = PerformanceTracker(); + // This is stored as a set to avoid duplicates. + final _warnings = {}; + + /// Map of font names to fonts */ + final _parameters = CompositionParameters(); + + /// Used to determine if an animation can be drawn with hardware acceleration. + bool hasDashPattern = false; + + /// Counts the number of mattes and masks. Before Android switched to SKIA + /// for drawing in Oreo (API 28), using hardware acceleration with mattes and masks + /// was only faster until you had ~4 masks after which it would actually become slower. + int _maskAndMatteCount = 0; + + final _fontsToLoad = []; + + WarningCallback? onWarning; + + void addWarning(String warning) { + var isNew = _warnings.add(warning); + if (isNew) { + onWarning?.call(warning); + } + } + + void incrementMatteOrMaskCount(int amount) { + _maskAndMatteCount += amount; + } + + /// Used to determine if an animation can be drawn with hardware acceleration. + int get maskAndMatteCount => _maskAndMatteCount; + + List get warnings => _warnings.toList(); + + bool get performanceTrackingEnabled => _performanceTracker.enabled; + set performanceTrackingEnabled(bool enabled) { + _performanceTracker.enabled = enabled; + } + + PerformanceTracker get performanceTracker => _performanceTracker; + + Layer? layerModelForId(int id) { + return _parameters.layerMap[id]; + } + + Rectangle get bounds => _parameters.bounds; + + Duration get duration { + return Duration(milliseconds: (seconds * 1000).round()); + } + + double get seconds => durationFrames / frameRate; + + double get startFrame => _parameters.startFrame; + + double get endFrame => _parameters.endFrame; + + double get frameRate => _parameters.frameRate; + + List get layers => _parameters.layers; + + List? getPrecomps(String? id) { + return _parameters.precomps[id]; + } + + Map get characters => _parameters.characters; + + Map get fonts => _parameters.fonts; + + List get markers => _parameters.markers; + + Marker? getMarker(String markerName) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i]; + if (marker.matchesName(markerName)) { + return marker; + } + } + return null; + } + + bool get hasImages { + return images.isNotEmpty; + } + + Map get images { + return _parameters.images; + } + + /// Number of frames in the animation + double get durationFrames => endFrame - startFrame; + + /// Returns a "rounded" progress value according to the frameRate + double roundProgress(double progress, {required FrameRate frameRate}) { + num? fps; + if (frameRate == FrameRate.max) { + return progress; + } else if (frameRate == FrameRate.composition) { + fps = this.frameRate; + } + fps ??= frameRate.framesPerSecond; + assert(!fps.isNaN && fps.isFinite && !fps.isNegative); + + var noOffsetDurationFrames = durationFrames + 0.01; + var totalFrameCount = (noOffsetDurationFrames / this.frameRate) * fps; + var frameIndex = (totalFrameCount * progress).toInt(); + var roundedProgress = frameIndex / totalFrameCount; + assert( + roundedProgress >= 0 && roundedProgress <= 1, + 'Progress is $roundedProgress', + ); + return roundedProgress; + } + + @override + String toString() { + final sb = StringBuffer('LottieComposition:\n'); + for (var layer in layers) { + sb.write(layer.toStringWithPrefix('\t')); + } + return sb.toString(); + } +} + +class FontToLoad { + final Uint8List bytes; + final String? family; + + FontToLoad(this.bytes, {this.family}); + + static List? getAndClear(LottieComposition composition) { + if (composition._fontsToLoad.isNotEmpty) { + var fonts = composition._fontsToLoad.toList(); + composition._fontsToLoad.clear(); + return fonts; + } + return null; + } +} diff --git a/lottie/lib/src/frame_rate.dart b/lottie/lib/src/frame_rate.dart new file mode 100644 index 0000000..f806486 --- /dev/null +++ b/lottie/lib/src/frame_rate.dart @@ -0,0 +1,28 @@ +import 'package:flutter/foundation.dart'; + +@immutable +class FrameRate { + static const max = FrameRate._special(0); + static const composition = FrameRate._special(-1); + + final double framesPerSecond; + + const FrameRate(this.framesPerSecond) : assert(framesPerSecond > 0); + const FrameRate._special(this.framesPerSecond); + + @override + int get hashCode => framesPerSecond.hashCode; + + @override + bool operator ==(other) => + other is FrameRate && other.framesPerSecond == framesPerSecond; + + @override + String toString() { + return 'FrameRate(${switch (framesPerSecond) { + 0 => 'max', + -1 => 'composition', + _ => framesPerSecond, + }})'; + } +} diff --git a/lottie/lib/src/l.dart b/lottie/lib/src/l.dart new file mode 100644 index 0000000..f2c8c2d --- /dev/null +++ b/lottie/lib/src/l.dart @@ -0,0 +1,59 @@ +import 'dart:developer'; + +class L { + static const int _maxDepth = 20; + static bool _traceEnabled = false; + static late List _sections; + static late List _startTimeNs; + static int _traceDepth = 0; + static int _depthPastMaxDepth = 0; + + static bool get traceEnabled => _traceEnabled; + static set traceEnabled(bool enabled) { + if (_traceEnabled == enabled) { + return; + } + _traceEnabled = enabled; + if (_traceEnabled) { + _sections = List.filled(_maxDepth, null); + _startTimeNs = List.filled(_maxDepth, 0); + } + } + + static void beginSection(String section) { + if (!_traceEnabled) { + return; + } + if (_traceDepth == _maxDepth) { + _depthPastMaxDepth++; + return; + } + _sections[_traceDepth] = section; + _startTimeNs[_traceDepth] = DateTime.now().microsecondsSinceEpoch; + Timeline.startSync('Lottie::$section'); + _traceDepth++; + } + + static double endSection(String section) { + if (_depthPastMaxDepth > 0) { + _depthPastMaxDepth--; + return 0; + } + if (!_traceEnabled) { + return 0; + } + _traceDepth--; + if (_traceDepth == -1) { + throw StateError("Can't end trace section. There are none."); + } + if (section != _sections[_traceDepth]) { + throw StateError( + 'Unbalanced trace call $section' + '. Expected ${_sections[_traceDepth]}.', + ); + } + Timeline.finishSync(); + return (DateTime.now().microsecondsSinceEpoch - _startTimeNs[_traceDepth]) / + 1000; + } +} diff --git a/lottie/lib/src/lottie.dart b/lottie/lib/src/lottie.dart new file mode 100644 index 0000000..4c8ed6d --- /dev/null +++ b/lottie/lib/src/lottie.dart @@ -0,0 +1,460 @@ +import 'dart:typed_data'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import '../lottie.dart'; +import 'composition.dart'; +import 'l.dart'; +import 'lottie_builder.dart'; +import 'providers/lottie_provider.dart'; + +/// A widget to display a loaded [LottieComposition]. +/// The [controller] property allows to specify a custom AnimationController that +/// will drive the animation. If [controller] is null, the animation will play +/// automatically and the behavior could be adjusted with the properties [animate], +/// [repeat] and [reverse]. +class Lottie extends StatefulWidget { + /// The cache instance for recently loaded Lottie compositions. + static LottieCache get cache => sharedLottieCache; + + const Lottie({ + super.key, + required this.composition, + this.controller, + this.width, + this.height, + this.alignment, + this.fit, + bool? animate, + this.frameRate, + bool? repeat, + bool? reverse, + this.delegates, + this.options, + bool? addRepaintBoundary, + this.filterQuality, + this.renderCache, + }) : animate = animate ?? true, + reverse = reverse ?? false, + repeat = repeat ?? true, + addRepaintBoundary = addRepaintBoundary ?? true; + + /// Creates a widget that displays an [LottieComposition] obtained from an [AssetBundle]. + static LottieBuilder asset( + String name, { + Animation? controller, + bool? animate, + FrameRate? frameRate, + bool? repeat, + bool? reverse, + LottieDelegates? delegates, + LottieOptions? options, + void Function(LottieComposition)? onLoaded, + LottieImageProviderFactory? imageProviderFactory, + Key? key, + AssetBundle? bundle, + LottieFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + double? width, + double? height, + BoxFit? fit, + AlignmentGeometry? alignment, + String? package, + bool? addRepaintBoundary, + FilterQuality? filterQuality, + WarningCallback? onWarning, + LottieDecoder? decoder, + RenderCache? renderCache, + bool? backgroundLoading, + }) => LottieBuilder.asset( + name, + controller: controller, + frameRate: frameRate, + animate: animate, + repeat: repeat, + reverse: reverse, + delegates: delegates, + options: options, + imageProviderFactory: imageProviderFactory, + onLoaded: onLoaded, + key: key, + bundle: bundle, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + width: width, + height: height, + fit: fit, + alignment: alignment, + package: package, + addRepaintBoundary: addRepaintBoundary, + filterQuality: filterQuality, + onWarning: onWarning, + decoder: decoder, + renderCache: renderCache, + backgroundLoading: backgroundLoading, + ); + + /// Creates a widget that displays an [LottieComposition] obtained from a [File]. + static LottieBuilder file( + Object file, { + Animation? controller, + FrameRate? frameRate, + bool? animate, + bool? repeat, + bool? reverse, + LottieDelegates? delegates, + LottieOptions? options, + LottieImageProviderFactory? imageProviderFactory, + void Function(LottieComposition)? onLoaded, + Key? key, + LottieFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + double? width, + double? height, + BoxFit? fit, + AlignmentGeometry? alignment, + bool? addRepaintBoundary, + FilterQuality? filterQuality, + WarningCallback? onWarning, + LottieDecoder? decoder, + RenderCache? renderCache, + bool? backgroundLoading, + }) => LottieBuilder.file( + file, + controller: controller, + frameRate: frameRate, + animate: animate, + repeat: repeat, + reverse: reverse, + delegates: delegates, + options: options, + imageProviderFactory: imageProviderFactory, + onLoaded: onLoaded, + key: key, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + width: width, + height: height, + fit: fit, + alignment: alignment, + addRepaintBoundary: addRepaintBoundary, + filterQuality: filterQuality, + onWarning: onWarning, + decoder: decoder, + renderCache: renderCache, + backgroundLoading: backgroundLoading, + ); + + /// Creates a widget that displays an [LottieComposition] obtained from a [Uint8List]. + static LottieBuilder memory( + Uint8List bytes, { + Animation? controller, + FrameRate? frameRate, + bool? animate, + bool? repeat, + bool? reverse, + LottieDelegates? delegates, + LottieOptions? options, + LottieImageProviderFactory? imageProviderFactory, + void Function(LottieComposition)? onLoaded, + Key? key, + LottieFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + double? width, + double? height, + BoxFit? fit, + AlignmentGeometry? alignment, + bool? addRepaintBoundary, + FilterQuality? filterQuality, + WarningCallback? onWarning, + LottieDecoder? decoder, + RenderCache? renderCache, + bool? backgroundLoading, + }) => LottieBuilder.memory( + bytes, + controller: controller, + frameRate: frameRate, + animate: animate, + repeat: repeat, + reverse: reverse, + delegates: delegates, + options: options, + imageProviderFactory: imageProviderFactory, + onLoaded: onLoaded, + key: key, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + width: width, + height: height, + fit: fit, + alignment: alignment, + addRepaintBoundary: addRepaintBoundary, + filterQuality: filterQuality, + onWarning: onWarning, + decoder: decoder, + renderCache: renderCache, + backgroundLoading: backgroundLoading, + ); + + /// Creates a widget that displays an [LottieComposition] obtained from the network. + static LottieBuilder network( + String url, { + http.Client? client, + Map? headers, + Animation? controller, + FrameRate? frameRate, + bool? animate, + bool? repeat, + bool? reverse, + LottieDelegates? delegates, + LottieOptions? options, + LottieImageProviderFactory? imageProviderFactory, + void Function(LottieComposition)? onLoaded, + Key? key, + LottieFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + double? width, + double? height, + BoxFit? fit, + AlignmentGeometry? alignment, + bool? addRepaintBoundary, + FilterQuality? filterQuality, + WarningCallback? onWarning, + LottieDecoder? decoder, + RenderCache? renderCache, + bool? backgroundLoading, + }) => LottieBuilder.network( + url, + client: client, + headers: headers, + controller: controller, + frameRate: frameRate, + animate: animate, + repeat: repeat, + reverse: reverse, + delegates: delegates, + options: options, + imageProviderFactory: imageProviderFactory, + onLoaded: onLoaded, + key: key, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + width: width, + height: height, + fit: fit, + alignment: alignment, + addRepaintBoundary: addRepaintBoundary, + filterQuality: filterQuality, + onWarning: onWarning, + decoder: decoder, + renderCache: renderCache, + backgroundLoading: backgroundLoading, + ); + + /// The Lottie composition to animate. + /// It could be parsed asynchronously with `LottieComposition.fromBytes`. + final LottieComposition? composition; + + /// The animation controller to animate the Lottie animation. + /// If null, a controller is automatically created by this class and is configured + /// with the properties [animate], [reverse] + final Animation? controller; + + /// The number of frames per second to render. + /// Use `FrameRate.composition` to use the original frame rate of the Lottie composition (default) + /// Use `FrameRate.max` to advance the animation progression at every frame. + /// + /// The advantage of using a low frame rate is to preserve the device battery + /// by doing less rendering work. + final FrameRate? frameRate; + + /// If no controller is specified, this value indicate whether or not the + /// Lottie animation should be played automatically (default to true). + /// If there is an animation controller specified, this property has no effect. + /// + /// See [repeat] to control whether the animation should repeat. + final bool animate; + + /// Specify that the automatic animation should repeat in a loop (default to true). + /// The property has no effect if [animate] is false or [controller] is not null. + final bool repeat; + + /// Specify that the automatic animation should repeat in a loop in a "reverse" + /// mode (go from start to end and then continuously from end to start). + /// It default to false. + /// The property has no effect if [animate] is false, [repeat] is false or [controller] is not null. + final bool reverse; + + /// If non-null, requires the composition to have this width. + /// + /// If null, the composition will pick a size that best preserves its intrinsic + /// aspect ratio. + final double? width; + + /// If non-null, require the composition to have this height. + /// + /// If null, the composition will pick a size that best preserves its intrinsic + /// aspect ratio. + final double? height; + + /// How to inscribe the Lottie composition into the space allocated during layout. + final BoxFit? fit; + + /// How to align the composition within its bounds. + /// + /// The alignment aligns the given position in the image to the given position + /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, + /// -1.0) aligns the image to the top-left corner of its layout bounds, while a + /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the + /// image with the bottom right corner of its layout bounds. Similarly, an + /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the + /// middle of the bottom edge of its layout bounds. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final AlignmentGeometry? alignment; + + /// A group of callbacks to further customize the lottie animation. + /// - A [text] delegate to dynamically change some text displayed in the animation + /// - A value callback to change the properties of the animation at runtime. + /// - A text style factory to map between a font family specified in the animation + /// and the font family in your assets. + final LottieDelegates? delegates; + + /// Some options to enable/disable some feature of Lottie + /// - enableMergePaths: Enable merge path support + /// - enableApplyingOpacityToLayers: Enable layer-level opacity + final LottieOptions? options; + + /// Indicate to automatically add a `RepaintBoundary` widget around the animation. + /// This allows to optimize the app performance by isolating the animation in its + /// own `Layer`. + /// + /// This property is `true` by default. + final bool addRepaintBoundary; + + /// The quality of the image layer. See [FilterQuality] + /// [FilterQuality.high] is highest quality but slowest. + /// + /// Defaults to [FilterQuality.low] + final FilterQuality? filterQuality; + + /// {@template lottie.renderCache} + /// Opt-in to a special render mode where the frames of the animation are + /// lazily rendered and kept in a cache. + /// Subsequent runs of the animation will be cheaper to render. + /// + /// This is useful is the animation is complex and can consume lot of energy + /// from the battery. + /// This will trade an excessive CPU usage for an increase memory usage. + /// The main use-case is a short and small (size on the screen) animation that is + /// played repeatedly. + /// + /// There are 2 kinds of caches: + /// - [RenderCache.raster]: keep the frame rasterized in the cache (as [dart:ui.Image]). + /// Subsequent runs of the animation are very cheap for both the CPU and GPU but it takes + /// a lot of memory (rendered_width * rendered_height * frame_rate * duration_of_the_animation). + /// This should only be used for very short and very small animations. + /// - [RenderCache.drawingCommands]: keep the frame as a list of graphical operations ([dart:ui.Picture]). + /// Subsequent runs of the animation are cheaper for the CPU but not for the GPU. + /// Memory usage is a lot lower than RenderCache.raster. + /// + /// The render cache is managed internally and will release the memory once the + /// animation disappear. The cache is shared between all animations. + + /// Any change in the configuration of the animation (delegates, frame rate etc...) + /// will clear the cache entry. + /// For RenderCache.raster, any change in the size will invalidate the cache entry. The cache + /// use the final size visible on the screen (with all transforms applied). + /// + /// In order to not exceed the memory limit of a device, the raster cache is constrained + /// to maximum 50MB. After that, animations are not cached anymore. + /// {@endtemplate} + final RenderCache? renderCache; + + static bool get traceEnabled => L.traceEnabled; + static set traceEnabled(bool enabled) { + L.traceEnabled = enabled; + } + + @override + State createState() => _LottieState(); +} + +class _LottieState extends State with TickerProviderStateMixin { + late AnimationController _autoAnimation; + + @override + void initState() { + super.initState(); + + _autoAnimation = AnimationController( + vsync: this, + duration: widget.composition?.duration ?? const Duration(seconds: 1), + ); + _updateAutoAnimation(); + } + + @override + void didUpdateWidget(Lottie oldWidget) { + super.didUpdateWidget(oldWidget); + + _autoAnimation.duration = + widget.composition?.duration ?? const Duration(seconds: 1); + _updateAutoAnimation(); + } + + void _updateAutoAnimation() { + _autoAnimation.stop(); + + if (widget.animate && widget.controller == null) { + if (widget.repeat) { + _autoAnimation.repeat(reverse: widget.reverse); + } else { + _autoAnimation.forward(); + } + } + } + + @override + void dispose() { + _autoAnimation.dispose(); + super.dispose(); + } + + Animation get _progressAnimation => + widget.controller ?? _autoAnimation; + + @override + Widget build(BuildContext context) { + Widget child = AnimatedBuilder( + animation: _progressAnimation, + builder: (context, _) { + return RawLottie( + composition: widget.composition, + delegates: widget.delegates, + options: widget.options, + progress: _progressAnimation.value, + frameRate: widget.frameRate, + width: widget.width, + height: widget.height, + fit: widget.fit, + alignment: widget.alignment, + filterQuality: widget.filterQuality, + renderCache: widget.renderCache, + ); + }, + ); + + if (widget.addRepaintBoundary) { + child = RepaintBoundary(child: child); + } + + return child; + } +} diff --git a/lottie/lib/src/lottie_builder.dart b/lottie/lib/src/lottie_builder.dart new file mode 100644 index 0000000..8b5d813 --- /dev/null +++ b/lottie/lib/src/lottie_builder.dart @@ -0,0 +1,592 @@ +import 'dart:async'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import 'composition.dart'; +import 'frame_rate.dart'; +import 'lottie.dart'; +import 'lottie_delegates.dart'; +import 'options.dart'; +import 'providers/asset_provider.dart'; +import 'providers/file_provider.dart'; +import 'providers/load_image.dart'; +import 'providers/lottie_provider.dart'; +import 'providers/memory_provider.dart'; +import 'providers/network_provider.dart'; +import 'render_cache.dart'; + +typedef LottieFrameBuilder = + Widget Function( + BuildContext context, + Widget child, + LottieComposition? composition, + ); + +/// Signature used by [Lottie.errorBuilder] to create a replacement widget to +/// render instead of the image. +typedef LottieErrorWidgetBuilder = + Widget Function(BuildContext context, Object error, StackTrace? stackTrace); + +/// A widget that displays a Lottie animation. +/// +/// Several constructors are provided for the various ways that a Lottie file +/// can be provided: +/// +/// * [Lottie], for obtaining a composition from a [LottieProvider]. +/// * [Lottie.asset], for obtaining a Lottie file from an [AssetBundle] +/// using a key. +/// * [Lottie.network], for obtaining a lottie file from a URL. +/// * [Lottie.file], for obtaining a lottie file from a [File]. +/// * [Lottie.memory], for obtaining a lottie file from a [Uint8List]. +/// +class LottieBuilder extends StatefulWidget { + const LottieBuilder({ + super.key, + required this.lottie, + this.controller, + this.frameRate, + this.animate, + this.reverse, + this.repeat, + this.delegates, + this.options, + this.onLoaded, + this.frameBuilder, + this.errorBuilder, + this.width, + this.height, + this.fit, + this.alignment, + this.addRepaintBoundary, + this.filterQuality, + this.onWarning, + this.renderCache, + }); + + /// Creates a widget that displays an [LottieComposition] obtained from the network. + LottieBuilder.network( + String src, { + http.Client? client, + Map? headers, + this.controller, + this.frameRate, + this.animate, + this.reverse, + this.repeat, + this.delegates, + this.options, + LottieImageProviderFactory? imageProviderFactory, + this.onLoaded, + super.key, + this.frameBuilder, + this.errorBuilder, + this.width, + this.height, + this.fit, + this.alignment, + this.addRepaintBoundary, + this.filterQuality, + this.onWarning, + LottieDecoder? decoder, + this.renderCache, + bool? backgroundLoading, + }) : lottie = NetworkLottie( + src, + client: client, + headers: headers, + imageProviderFactory: imageProviderFactory, + decoder: decoder, + backgroundLoading: backgroundLoading, + ); + + /// Creates a widget that displays an [LottieComposition] obtained from a [File]. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the animation is loaded, which + /// will result in ugly layout changes. + /// + /// On Android, this may require the + /// `android.permission.READ_EXTERNAL_STORAGE` permission. + /// + LottieBuilder.file( + Object file, { + this.controller, + this.frameRate, + this.animate, + this.reverse, + this.repeat, + this.delegates, + this.options, + LottieImageProviderFactory? imageProviderFactory, + this.onLoaded, + super.key, + this.frameBuilder, + this.errorBuilder, + this.width, + this.height, + this.fit, + this.alignment, + this.addRepaintBoundary, + this.filterQuality, + this.onWarning, + LottieDecoder? decoder, + this.renderCache, + bool? backgroundLoading, + }) : lottie = FileLottie( + file, + imageProviderFactory: imageProviderFactory, + decoder: decoder, + backgroundLoading: backgroundLoading, + ); + + /// Creates a widget that displays an [LottieComposition] obtained from an [AssetBundle]. + LottieBuilder.asset( + String name, { + this.controller, + this.frameRate, + this.animate, + this.reverse, + this.repeat, + this.delegates, + this.options, + LottieImageProviderFactory? imageProviderFactory, + this.onLoaded, + super.key, + AssetBundle? bundle, + this.frameBuilder, + this.errorBuilder, + this.width, + this.height, + this.fit, + this.alignment, + String? package, + this.addRepaintBoundary, + this.filterQuality, + this.onWarning, + LottieDecoder? decoder, + this.renderCache, + bool? backgroundLoading, + }) : lottie = AssetLottie( + name, + bundle: bundle, + package: package, + imageProviderFactory: imageProviderFactory, + decoder: decoder, + backgroundLoading: backgroundLoading, + ); + + /// Creates a widget that displays an [LottieComposition] obtained from a [Uint8List]. + LottieBuilder.memory( + Uint8List bytes, { + this.controller, + this.frameRate, + this.animate, + this.reverse, + this.repeat, + this.delegates, + this.options, + LottieImageProviderFactory? imageProviderFactory, + this.onLoaded, + this.errorBuilder, + super.key, + this.frameBuilder, + this.width, + this.height, + this.fit, + this.alignment, + this.addRepaintBoundary, + this.filterQuality, + this.onWarning, + LottieDecoder? decoder, + this.renderCache, + bool? backgroundLoading, + }) : lottie = MemoryLottie( + bytes, + imageProviderFactory: imageProviderFactory, + decoder: decoder, + backgroundLoading: backgroundLoading, + ); + + /// The lottie animation to load. + /// Example of providers: [AssetLottie], [NetworkLottie], [FileLottie], [MemoryLottie] + final LottieProvider lottie; + + /// A callback called when the LottieComposition has been loaded. + /// You can use this callback to set the correct duration on the AnimationController + /// with `composition.duration` + final void Function(LottieComposition)? onLoaded; + + /// The animation controller of the Lottie animation. + /// The animated value will be mapped to the `progress` property of the + /// Lottie animation. + final Animation? controller; + + /// The number of frames per second to render. + /// Use `FrameRate.composition` to use the original frame rate of the Lottie composition (default) + /// Use `FrameRate.max` to advance the animation progression at every frame. + final FrameRate? frameRate; + + /// If no controller is specified, this value indicate whether or not the + /// Lottie animation should be played automatically (default to true). + /// If there is an animation controller specified, this property has no effect. + /// + /// See [repeat] to control whether the animation should repeat. + final bool? animate; + + /// Specify that the automatic animation should repeat in a loop (default to true). + /// The property has no effect if [animate] is false or [controller] is not null. + final bool? repeat; + + /// Specify that the automatic animation should repeat in a loop in a "reverse" + /// mode (go from start to end and then continuously from end to start). + /// It default to false. + /// The property has no effect if [animate] is false, [repeat] is false or [controller] is not null. + final bool? reverse; + + /// A group of options to further customize the lottie animation. + /// - A [text] delegate to dynamically change some text displayed in the animation + /// - A value callback to change the properties of the animation at runtime. + /// - A text style factory to map between a font family specified in the animation + /// and the font family in your assets. + final LottieDelegates? delegates; + + /// Some options to enable/disable some feature of Lottie + /// - enableMergePaths: Enable merge path support + /// - enableApplyingOpacityToLayers: Enable layer-level opacity + final LottieOptions? options; + + /// A builder function responsible for creating the widget that represents + /// this lottie animation. + /// + /// If this is null, this widget will display a lottie animation that is painted as + /// soon as it is available (and will appear to "pop" in + /// if it becomes available asynchronously). Callers might use this builder to + /// add effects to the animation (such as fading the animation in when it becomes + /// available) or to display a placeholder widget while the animation is loading. + /// + /// To have finer-grained control over the way that an animation's loading + /// progress is communicated to the user, see [loadingBuilder]. + /// + /// {@template lottie.chainedBuildersExample} + /// ```dart + /// Lottie( + /// ... + /// frameBuilder: (BuildContext context, Widget child) { + /// return Padding( + /// padding: EdgeInsets.all(8.0), + /// child: child, + /// ); + /// } + /// ) + /// ``` + /// + /// In this example, the widget hierarchy will contain the following: + /// + /// ```dart + /// Center( + /// Padding( + /// padding: EdgeInsets.all(8.0), + /// child: , + /// ), + /// ) + /// ``` + /// {@endtemplate} + /// + /// {@tool snippet --template=stateless_widget_material} + /// + /// The following sample demonstrates how to use this builder to implement an + /// animation that fades in once it's been loaded. + /// + /// This sample contains a limited subset of the functionality that the + /// [FadeInImage] widget provides out of the box. + /// + /// ```dart + /// @override + /// Widget build(BuildContext context) { + /// return DecoratedBox( + /// decoration: BoxDecoration( + /// color: Colors.white, + /// border: Border.all(), + /// borderRadius: BorderRadius.circular(20), + /// ), + /// child: Lottie.network( + /// 'https://example.com/animation.json', + /// frameBuilder: (BuildContext context, Widget child) { + /// if (wasSynchronouslyLoaded) { + /// return child; + /// } + /// return AnimatedOpacity( + /// child: child, + /// opacity: frame == null ? 0 : 1, + /// duration: const Duration(seconds: 1), + /// curve: Curves.easeOut, + /// ); + /// }, + /// ), + /// ); + /// } + /// ``` + /// {@end-tool} + /// + final LottieFrameBuilder? frameBuilder; + + /// If non-null, require the lottie animation to have this width. + /// + /// If null, the lottie animation will pick a size that best preserves its intrinsic + /// aspect ratio. + /// + /// It is strongly recommended that either both the [width] and the [height] + /// be specified, or that the widget be placed in a context that sets tight + /// layout constraints, so that the animation does not change size as it loads. + /// Consider using [fit] to adapt the animation's rendering to fit the given width + /// and height if the exact animation dimensions are not known in advance. + final double? width; + + /// If non-null, require the lottie animation to have this height. + /// + /// If null, the lottie animation will pick a size that best preserves its intrinsic + /// aspect ratio. + /// + /// It is strongly recommended that either both the [width] and the [height] + /// be specified, or that the widget be placed in a context that sets tight + /// layout constraints, so that the animation does not change size as it loads. + /// Consider using [fit] to adapt the animation's rendering to fit the given width + /// and height if the exact animation dimensions are not known in advance. + final double? height; + + /// How to inscribe the animation into the space allocated during layout. + /// + /// The default varies based on the other fields. See the discussion at + /// [paintImage]. + final BoxFit? fit; + + /// How to align the animation within its bounds. + /// + /// The alignment aligns the given position in the animation to the given position + /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, + /// -1.0) aligns the animation to the top-left corner of its layout bounds, while an + /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the + /// animation with the bottom right corner of its layout bounds. Similarly, an + /// alignment of (0.0, 1.0) aligns the bottom middle of the animation with the + /// middle of the bottom edge of its layout bounds. + /// + /// To display a subpart of an animation, consider using a [CustomPainter] and + /// [Canvas.drawImageRect]. + /// + /// If the [alignment] is [TextDirection]-dependent (i.e. if it is a + /// [AlignmentDirectional]), then an ambient [Directionality] widget + /// must be in scope. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final AlignmentGeometry? alignment; + + /// Indicate to automatically add a `RepaintBoundary` widget around the animation. + /// This allows to optimize the app performance by isolating the animation in its + /// own `Layer`. + /// + /// This property is `true` by default. + final bool? addRepaintBoundary; + + /// The quality of the image layer. See [FilterQuality] + /// [FilterQuality.high] is highest quality but slowest. + /// + /// Defaults to [FilterQuality.low] + final FilterQuality? filterQuality; + + /// A callback called when there is a warning during the loading or painting + /// of the animation. + final WarningCallback? onWarning; + + /// A builder function that is called if an error occurs during loading. + /// + /// If this builder is not provided, any exceptions will be reported to + /// [FlutterError.onError]. If it is provided, the caller should either handle + /// the exception by providing a replacement widget, or rethrow the exception. + /// + /// The following sample uses [errorBuilder] to show a '😢' in place of the + /// image that fails to load, and prints the error to the console. + /// + /// ```dart + /// Widget build(BuildContext context) { + /// return DecoratedBox( + /// decoration: BoxDecoration( + /// color: Colors.white, + /// ), + /// child: Lottie.network( + /// 'https://example.does.not.exist/lottie.json', + /// errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { + /// // Appropriate logging or analytics, e.g. + /// // myAnalytics.recordError( + /// // 'An error occurred loading "https://example.does.not.exist/animation.json"', + /// // exception, + /// // stackTrace, + /// // ); + /// return const Text('😢'); + /// }, + /// ), + /// ); + /// } + /// ``` + final ImageErrorWidgetBuilder? errorBuilder; + + /// Opt-in to a special render mode where the frames of the animation are + /// lazily rendered and kept in a cache. + /// Subsequent runs of the animation will be cheaper to render. + /// + /// This is useful is the animation is complex and can consume lot of energy + /// from the battery. + /// This will trade an excessive CPU usage for an increase memory usage. + /// The main use-case is a short and small (size on the screen) animation that is + /// played repeatedly. + /// + /// There are 2 kinds of caches: + /// - [RenderCache.raster]: keep the frame rasterized in the cache (as [dart:ui.Image]). + /// Subsequent runs of the animation are very cheap for both the CPU and GPU but it takes + /// a lot of memory (rendered_width * rendered_height * frame_rate * duration_of_the_animation). + /// This should only be used for very short and very small animations. + /// - [RenderCache.drawingCommands]: keep the frame as a list of graphical operations ([dart:ui.Picture]). + /// Subsequent runs of the animation are cheaper for the CPU but not for the GPU. + /// Memory usage is a lot lower than RenderCache.raster. + /// + /// The render cache is managed internally and will release the memory once the + /// animation disappear. The cache is shared between all animations. + + /// Any change in the configuration of the animation (delegates, frame rate etc...) + /// will clear the cache entry. + /// For RenderCache.raster, any change in the size will invalidate the cache entry. The cache + /// use the final size visible on the screen (with all transforms applied). + /// + /// In order to not exceed the memory limit of a device, the raster cache is constrained + /// to maximum 50MB. After that, animations are not cached anymore. + final RenderCache? renderCache; + + @override + State createState() => _LottieBuilderState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('lottie', lottie)); + properties.add(DiagnosticsProperty('frameBuilder', frameBuilder)); + properties.add(DoubleProperty('width', width, defaultValue: null)); + properties.add(DoubleProperty('height', height, defaultValue: null)); + properties.add(EnumProperty('fit', fit, defaultValue: null)); + properties.add( + DiagnosticsProperty( + 'alignment', + alignment, + defaultValue: null, + ), + ); + } +} + +class _LottieBuilderState extends State { + Future? _loadingFuture; + + @override + void didUpdateWidget(LottieBuilder oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.lottie != widget.lottie) { + _load(); + } + } + + void _load() { + var provider = widget.lottie; + _loadingFuture = widget.lottie.load(context: context).then((composition) { + // LottieProvider.load() can return a Synchronous future and the onLoaded + // callback can call setState, so we wrap it in a microtask to avoid an + // "!_isDirty" error. + scheduleMicrotask(() { + if (mounted && widget.lottie == provider) { + var onWarning = widget.onWarning; + composition.onWarning = onWarning; + if (onWarning != null) { + for (var warning in composition.warnings) { + onWarning(warning); + } + } + + widget.onLoaded?.call(composition); + } + }); + + return composition; + }); + } + + @override + Widget build(BuildContext context) { + // We need to wait the first build instead of initState because AssetLottie + // provider may call DefaultAssetBundle.of + if (_loadingFuture == null) { + _load(); + } + return FutureBuilder( + future: _loadingFuture, + builder: (context, snapshot) { + if (snapshot.hasError) { + var errorBuilder = widget.errorBuilder; + if (errorBuilder != null) { + return errorBuilder(context, snapshot.error!, snapshot.stackTrace); + } else if (kDebugMode) { + return SizedBox( + width: widget.width, + height: widget.height, + child: ErrorWidget(snapshot.error!), + ); + } + } + + var composition = snapshot.data; + var animate = widget.animate; + animate ??= (composition?.durationFrames ?? 0) > 1.0; + + Widget result = Lottie( + composition: composition, + controller: widget.controller, + frameRate: widget.frameRate, + animate: animate, + reverse: widget.reverse, + repeat: widget.repeat, + delegates: widget.delegates, + options: widget.options, + width: widget.width, + height: widget.height, + fit: widget.fit, + alignment: widget.alignment, + addRepaintBoundary: widget.addRepaintBoundary, + filterQuality: widget.filterQuality, + renderCache: widget.renderCache, + ); + + if (widget.frameBuilder != null) { + result = widget.frameBuilder!(context, result, composition); + } + + return result; + }, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder description) { + super.debugFillProperties(description); + description.add( + DiagnosticsProperty>( + 'loadingFuture', + _loadingFuture, + ), + ); + } +} diff --git a/lottie/lib/src/lottie_delegates.dart b/lottie/lib/src/lottie_delegates.dart new file mode 100644 index 0000000..39efce8 --- /dev/null +++ b/lottie/lib/src/lottie_delegates.dart @@ -0,0 +1,95 @@ +import 'dart:ui' as ui; +import 'package:flutter/widgets.dart'; +import 'composition.dart'; +import 'lottie_drawable.dart'; +import 'lottie_image_asset.dart'; +import 'value_delegate.dart'; + +TextStyle defaultTextStyleDelegate(LottieFontStyle font) { + var style = font.style.toLowerCase(); + + var fontStyle = style.contains('italic') ? FontStyle.italic : null; + + FontWeight? fontWeight; + if (style.contains('semibold') || style.contains('semi bold')) { + fontWeight = FontWeight.w600; + } else if (style.contains('bold')) { + fontWeight = FontWeight.bold; + } + return TextStyle( + fontFamily: font.fontFamily, + fontStyle: fontStyle, + fontWeight: fontWeight, + ); +} + +@immutable +class LottieDelegates { + /// Specify a callback to dynamically changes the text displayed in the lottie + /// animation. + /// For instance, this is useful when you want to translate the text in the animation. + final String Function(String)? text; + + /// A callback to map between a font family specified in the json animation + /// with the font family in your assets. + /// This is useful either if: + /// - the name of the font in your asset doesn't match the one in the json file. + /// - you want to use an other font than the one declared in the json + /// + /// If the callback is null, the font family from the json is used as it. + /// + /// Given an object containing the font family and style specified in the json + /// return a configured `TextStyle` that will be used as the base style when + /// painting the text. + final TextStyle Function(LottieFontStyle)? textStyle; + + /// A list of value delegates to dynamically modify the animation + /// properties at runtime. + /// + /// Example: + /// ```dart + /// Lottie.asset( + /// 'lottiefile.json', + /// delegates: LottieDelegates( + /// value: [ + /// ValueDelegate.color(['lake', 'fill'], value: Colors.blue), + /// ValueDelegate.opacity(['**', 'fill'], callback: (frameInfo) => 0.5 * frameInfo.overallProgress), + /// ], + /// ), + /// ); + /// ``` + final List? values; + + /// A callback to dynamically change an image of the animation. + /// + /// Example: + /// ```dart + /// Lottie.asset( + // 'assets/data.json', + // delegates: LottieDelegates( + // image: (composition, image) { + // if (image.id == 'img_0' && _isMouseOver) { + // return myCustomImage; + // } + // + // // Use the default method: composition.images[image.id].loadedImage; + // return null; + // }, + // ) + // ) + /// ``` + final ui.Image? Function(LottieComposition, LottieImageAsset)? image; + + const LottieDelegates({this.text, this.textStyle, this.values, this.image}); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is LottieDelegates && + text == other.text && + textStyle == other.textStyle && + values == other.values; + + @override + int get hashCode => Object.hash(text, textStyle, values); +} diff --git a/lottie/lib/src/lottie_drawable.dart b/lottie/lib/src/lottie_drawable.dart new file mode 100644 index 0000000..22150d3 --- /dev/null +++ b/lottie/lib/src/lottie_drawable.dart @@ -0,0 +1,274 @@ +import 'dart:ui' as ui; +import 'package:flutter/rendering.dart'; +import 'composition.dart'; +import 'frame_rate.dart'; +import 'lottie_delegates.dart'; +import 'model/key_path.dart'; +import 'model/layer/composition_layer.dart'; +import 'parser/layer_parser.dart'; +import 'render_cache.dart'; +import 'utils.dart'; +import 'value_delegate.dart'; + +class LottieDrawable { + final LottieComposition composition; + final _matrix = Matrix4.identity(); + late CompositionLayer _compositionLayer; + final Size size; + final FrameRate? frameRate; + LottieDelegates? _delegates; + bool _isDirty = true; + bool enableMergePaths = false; + FilterQuality? filterQuality; + + /// Gives a suggestion whether to paint with anti-aliasing, or not. Default is true. + bool antiAliasingSuggested = true; + + LottieDrawable(this.composition, {LottieDelegates? delegates, this.frameRate}) + : size = Size( + composition.bounds.width.toDouble(), + composition.bounds.height.toDouble(), + ) { + this.delegates = delegates; + _compositionLayer = CompositionLayer( + this, + LayerParser.parse(composition), + composition.layers, + composition, + ); + } + + CompositionLayer get compositionLayer => _compositionLayer; + + /// Sets whether to apply opacity to the each layer instead of shape. + /// + /// Opacity is normally applied directly to a shape. In cases where translucent + /// shapes overlap, applying opacity to a layer will be more accurate at the + /// expense of performance. + /// + /// The default value is false. + /// + /// Note: This process is very expensive. The performance impact will be reduced + /// when hardware acceleration is enabled. + bool isApplyingOpacityToLayersEnabled = false; + + void invalidateSelf() { + _isDirty = true; + } + + final _progressAliases = {}; + + double get progress => _progress ?? 0.0; + double? _progress; + bool setProgress(double value) { + var frameRate = this.frameRate ?? FrameRate.composition; + var roundedProgress = composition.roundProgress( + value, + frameRate: frameRate, + ); + if (roundedProgress != _progress) { + _isDirty = false; + var previousProgress = _progress; + _progress = roundedProgress; + _compositionLayer.setProgress(roundedProgress); + if (!_isDirty && frameRate != FrameRate.max && previousProgress != null) { + var alias = _progressAliases[previousProgress] ?? previousProgress; + _progressAliases[roundedProgress] = alias; + } + return _isDirty; + } else { + return false; + } + } + + int _delegatesHash = 0; + LottieDelegates? get delegates => _delegates; + set delegates(LottieDelegates? delegates) { + if (_delegates != delegates) { + _delegates = delegates; + _updateValueDelegates(delegates?.values); + _delegatesHash = _computeValueDelegateHash(delegates); + } + } + + List configHash() { + return [ + enableMergePaths, + filterQuality, + frameRate, + isApplyingOpacityToLayersEnabled, + ]; + } + + int delegatesHash() => _delegatesHash; + + int _computeValueDelegateHash(LottieDelegates? delegates) { + if (delegates == null) return 0; + + var valuesHash = []; + if (delegates.values case var values?) { + for (var value in values) { + valuesHash.add( + Object.hash( + value.value, + value.callbackHash, + value.property, + Object.hashAll(value.keyPath), + ), + ); + } + } + + return Object.hash( + delegates.image, + delegates.text, + delegates.textStyle, + Object.hashAll(valuesHash), + ); + } + + bool get useTextGlyphs { + return delegates?.text == null && composition.characters.isNotEmpty; + } + + ui.Image? getImageAsset(String? ref) { + var imageAsset = composition.images[ref]; + if (imageAsset != null) { + var imageDelegate = delegates?.image; + ui.Image? image; + if (imageDelegate != null) { + image = imageDelegate(composition, imageAsset); + } + + return image ?? imageAsset.loadedImage; + } else { + return null; + } + } + + TextStyle getTextStyle(String font, String style) { + return (_delegates?.textStyle ?? defaultTextStyleDelegate)( + LottieFontStyle(fontFamily: font, style: style), + ); + } + + List _valueDelegates = []; + void _updateValueDelegates(List? newDelegates) { + if (identical(_valueDelegates, newDelegates)) return; + + newDelegates ??= const []; + + var delegates = []; + + for (var newDelegate in newDelegates) { + var existingDelegate = _valueDelegates.firstWhereOrNull( + (f) => f.isSameProperty(newDelegate), + ); + if (existingDelegate != null) { + var resolved = internalResolved(existingDelegate); + resolved.updateDelegate(newDelegate); + delegates.add(existingDelegate); + } else { + var keyPaths = _resolveKeyPath(KeyPath(newDelegate.keyPath)); + var resolvedValueDelegate = internalResolve(newDelegate, keyPaths); + resolvedValueDelegate.addValueCallback(this); + delegates.add(newDelegate); + } + } + for (var oldDelegate in _valueDelegates) { + if (delegates.every((c) => !c.isSameProperty(oldDelegate))) { + var resolved = internalResolved(oldDelegate); + resolved.clear(); + } + } + _valueDelegates = delegates; + } + + /// Takes a {@link KeyPath}, potentially with wildcards or globstars and resolve it to a list of + /// zero or more actual {@link KeyPath Keypaths} that exist in the current animation. + ///

+ /// If you want to set value callbacks for any of these values, it is recommend to use the + /// returned {@link KeyPath} objects because they will be internally resolved to their content + /// and won't trigger a tree walk of the animation contents when applied. + List _resolveKeyPath(KeyPath keyPath) { + var keyPaths = []; + _compositionLayer.resolveKeyPath(keyPath, 0, keyPaths, KeyPath([])); + return keyPaths; + } + + void draw( + ui.Canvas canvas, + ui.Rect rect, { + BoxFit? fit, + Alignment? alignment, + RenderCacheContext? renderCache, + }) { + if (rect.isEmpty) { + return; + } + + fit ??= BoxFit.scaleDown; + alignment ??= Alignment.center; + var outputSize = rect.size; + var inputSize = size; + var fittedSizes = applyBoxFit(fit, inputSize, outputSize); + var sourceSize = fittedSizes.source; + var destinationSize = fittedSizes.destination; + var halfWidthDelta = (outputSize.width - destinationSize.width) / 2.0; + var halfHeightDelta = (outputSize.height - destinationSize.height) / 2.0; + var dx = halfWidthDelta + alignment.x * halfWidthDelta; + var dy = halfHeightDelta + alignment.y * halfHeightDelta; + var destinationPosition = rect.topLeft.translate(dx, dy); + var destinationRect = destinationPosition & destinationSize; + var sourceRect = alignment.inscribe(sourceSize, Offset.zero & inputSize); + + _matrix.setIdentity(); + + var cacheUsed = false; + if (renderCache != null) { + var progressForCache = _progressAliases[progress] ?? progress; + + cacheUsed = renderCache.cache.draw( + this, + progressForCache, + canvas, + destinationPosition: destinationPosition, + destinationRect: destinationRect, + sourceSize: sourceSize, + sourceRect: sourceRect, + renderBox: renderCache.renderBox, + devicePixelRatio: renderCache.devicePixelRatio, + ); + } + if (!cacheUsed) { + canvas.save(); + canvas.translate(destinationRect.left, destinationRect.top); + _matrix.scaleByDouble( + destinationSize.width / sourceRect.width, + destinationSize.height / sourceRect.height, + destinationSize.width / sourceRect.width, + 1, + ); + _compositionLayer.draw(canvas, _matrix, parentAlpha: 255); + canvas.restore(); + } + } +} + +class LottieFontStyle { + final String fontFamily, style; + + LottieFontStyle({required this.fontFamily, required this.style}); +} + +class RenderCacheContext { + final AnimationCache cache; + final RenderBox renderBox; + final double devicePixelRatio; + + RenderCacheContext({ + required this.cache, + required this.renderBox, + required this.devicePixelRatio, + }); +} diff --git a/lottie/lib/src/lottie_image_asset.dart b/lottie/lib/src/lottie_image_asset.dart new file mode 100644 index 0000000..1a045c9 --- /dev/null +++ b/lottie/lib/src/lottie_image_asset.dart @@ -0,0 +1,22 @@ +import 'dart:ui' as ui; + +class LottieImageAsset { + final int width; + final int height; + final String id; + final String fileName; + final String dirName; + ui.Image? loadedImage; + + LottieImageAsset({ + required this.width, + required this.height, + required this.id, + required this.fileName, + required this.dirName, + }); + + @override + String toString() => + 'LottieImageAsset(width: $width, height: $height, id: $id, fileName: $fileName, dirName: $dirName)'; +} diff --git a/lottie/lib/src/lottie_property.dart b/lottie/lib/src/lottie_property.dart new file mode 100644 index 0000000..a229b81 --- /dev/null +++ b/lottie/lib/src/lottie_property.dart @@ -0,0 +1,146 @@ +import 'dart:ui'; +import 'value/drop_shadow.dart'; + +/// Property values are the same type as the generic type of their corresponding +/// [LottieValueCallback]. With this, we can use generics to maintain type safety +/// of the callbacks. +/// +/// Supported properties: +/// Transform: +/// {TRANSFORM_ANCHOR_POINT} +/// {TRANSFORM_POSITION} +/// {TRANSFORM_OPACITY} +/// {TRANSFORM_SCALE} +/// {TRANSFORM_ROTATION} +/// {TRANSFORM_SKEW} +/// {TRANSFORM_SKEW_ANGLE} +/// +/// Fill: +/// {#COLOR} (non-gradient) +/// {#OPACITY} +/// {#COLOR_FILTER} +/// +/// Stroke: +/// {#COLOR} (non-gradient) +/// {#STROKE_WIDTH} +/// {#OPACITY} +/// {#COLOR_FILTER} +/// +/// Ellipse: +/// {#POSITION} +/// {#ELLIPSE_SIZE} +/// +/// Polystar: +/// {#POLYSTAR_POINTS} +/// {#POLYSTAR_ROTATION} +/// {#POSITION} +/// {#POLYSTAR_INNER_RADIUS} (star) +/// {#POLYSTAR_OUTER_RADIUS} +/// {#POLYSTAR_INNER_ROUNDEDNESS} (star) +/// {#POLYSTAR_OUTER_ROUNDEDNESS} +/// +/// Repeater: +/// All transform properties +/// {#REPEATER_COPIES} +/// {#REPEATER_OFFSET} +/// {#TRANSFORM_ROTATION} +/// {#TRANSFORM_START_OPACITY} +/// {#TRANSFORM_END_OPACITY} +/// +/// Layers: +/// All transform properties +/// {#TIME_REMAP} (composition layers only) +abstract class LottieProperty { + /// ColorInt **/ + static const Color color = Color(0x00000001); + static const Color strokeColor = Color(0x00000002); + + /// Opacity value are 0-100 to match after effects **/ + static const int transformOpacity = 3; + + /// [0,100] */ + static const int opacity = 4; + + /// In Px */ + static const Offset transformAnchorPoint = Offset(5, 5); + + /// In Px */ + static const Offset transformPosition = Offset(6, 6); + + /// In Px */ + static const Offset ellipseSize = Offset(7, 7); + + /// In Px */ + static const Offset rectangleSize = Offset(8, 8); + + /// In degrees */ + static const double cornerRadius = 9.0; + + /// In Px */ + static const Offset position = Offset(10, 10); + static const Offset transformScale = Offset(11, 11); + + /// In degrees */ + static const double transformRotation = 12.0; + + /// 0-85 */ + static const double transformSkew = 13.0; + + /// In degrees */ + static const double transformSkewAngle = 14.0; + + /// In Px */ + static const double strokeWidth = 15.0; + static const double textTracking = 16.0; + static const double repeaterCopies = 17.0; + static const double repeaterOffset = 18.0; + static const double polystarPoints = 19.0; + + /// In degrees */ + static const double polystarRotation = 20.0; + + /// In Px */ + static const double polystarInnerRadius = 21.0; + + /// In Px */ + static const double polystarOuterRadius = 22.0; + + /// [0,100] */ + static const double polystarInnerRoundedness = 23.0; + + /// [0,100] */ + static const double polystarOuterRoundedness = 24.0; + + /// [0,100] */ + static const double transformStartOpacity = 25.0; + + /// [0,100] */ + static const double transformEndOpacity = 26.0; + + /// The time value in seconds */ + static const double timeRemap = 27.0; + + /// In Dp + static const double textSize = 28.0; + + /// In Px + static const double blurRadius = 29.0; + + static const dropShadow = DropShadow( + color: Color(0x00000000), + direction: 0, + distance: 0, + radius: 0, + ); + + /// Set the color filter for an entire drawable content. Can be applied to fills, strokes, images, and solids. + static const ColorFilter colorFilter = ColorFilter.mode( + Color(0xFF000000), + BlendMode.dst, + ); + + static final List gradientColor = []; + + /// Replace the text for a text layer. + static const text = 'dynamic_text'; +} diff --git a/lottie/lib/src/model/animatable/animatable_color_value.dart b/lottie/lib/src/model/animatable/animatable_color_value.dart new file mode 100644 index 0000000..f03b966 --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_color_value.dart @@ -0,0 +1,12 @@ +import 'dart:ui'; +import '../../animation/keyframe/color_keyframe_animation.dart'; +import 'base_animatable_value.dart'; + +class AnimatableColorValue extends BaseAnimatableValue { + AnimatableColorValue.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + ColorKeyframeAnimation createAnimation() { + return ColorKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_double_value.dart b/lottie/lib/src/model/animatable/animatable_double_value.dart new file mode 100644 index 0000000..4be230b --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_double_value.dart @@ -0,0 +1,13 @@ +import '../../animation/keyframe/double_keyframe_animation.dart'; +import 'base_animatable_value.dart'; + +class AnimatableDoubleValue extends BaseAnimatableValue { + AnimatableDoubleValue() : super.fromValue(0.0); + + AnimatableDoubleValue.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + DoubleKeyframeAnimation createAnimation() { + return DoubleKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_gradient_color_value.dart b/lottie/lib/src/model/animatable/animatable_gradient_color_value.dart new file mode 100644 index 0000000..eb135b1 --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_gradient_color_value.dart @@ -0,0 +1,73 @@ +import '../../animation/keyframe/gradient_color_keyframe_animation.dart'; +import '../../value/keyframe.dart'; +import '../content/gradient_color.dart'; +import 'base_animatable_value.dart'; + +class AnimatableGradientColorValue + extends BaseAnimatableValue { + AnimatableGradientColorValue.fromKeyframes( + List> keyframes, + ) : super.fromKeyframes(_ensureInterpolatableKeyframes(keyframes)); + + static List> _ensureInterpolatableKeyframes( + List> keyframes, + ) { + for (var i = 0; i < keyframes.length; i++) { + keyframes[i] = _ensureInterpolatableKeyframe(keyframes[i]); + } + return keyframes; + } + + static Keyframe _ensureInterpolatableKeyframe( + Keyframe keyframe, + ) { + var startValue = keyframe.startValue; + var endValue = keyframe.endValue; + if (startValue == null || + endValue == null || + startValue.positions.length == endValue.positions.length) { + return keyframe; + } + var mergedPositions = _mergePositions( + startValue.positions, + endValue.positions, + ); + // The start/end has opacity stops which required adding extra positions in between the existing colors. + return keyframe.copyWith( + startValue.copyWithPositions(mergedPositions), + endValue.copyWithPositions(mergedPositions), + ); + } + + static List _mergePositions( + List startPositions, + List endPositions, + ) { + var mergedArray = List.filled( + startPositions.length + endPositions.length, + 0, + ); + mergedArray.setRange(0, startPositions.length, startPositions); + mergedArray.setRange( + startPositions.length, + startPositions.length + endPositions.length, + endPositions, + ); + mergedArray.sort(); + var uniqueValues = 0; + var lastValue = double.nan; + for (var i = 0; i < mergedArray.length; i++) { + if (mergedArray[i] != lastValue) { + mergedArray[uniqueValues] = mergedArray[i]; + uniqueValues++; + lastValue = mergedArray[i]; + } + } + return mergedArray.take(uniqueValues).toList(); + } + + @override + GradientColorKeyframeAnimation createAnimation() { + return GradientColorKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_integer_value.dart b/lottie/lib/src/model/animatable/animatable_integer_value.dart new file mode 100644 index 0000000..4daacb6 --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_integer_value.dart @@ -0,0 +1,14 @@ +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/integer_keyframe_animation.dart'; +import 'base_animatable_value.dart'; + +class AnimatableIntegerValue extends BaseAnimatableValue { + AnimatableIntegerValue() : super.fromValue(100); + + AnimatableIntegerValue.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + BaseKeyframeAnimation createAnimation() { + return IntegerKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_path_value.dart b/lottie/lib/src/model/animatable/animatable_path_value.dart new file mode 100644 index 0000000..d5c14de --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_path_value.dart @@ -0,0 +1,29 @@ +import 'dart:ui'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/path_keyframe_animation.dart'; +import '../../animation/keyframe/point_keyframe_animation.dart'; +import '../../value/keyframe.dart'; +import 'animatable_value.dart'; + +class AnimatablePathValue implements AnimatableValue { + @override + final List> keyframes; + + /// Create a default static animatable path. + AnimatablePathValue() : keyframes = [Keyframe.nonAnimated(Offset.zero)]; + + AnimatablePathValue.fromKeyframes(this.keyframes); + + @override + bool get isStatic { + return keyframes.length == 1 && keyframes[0].isStatic; + } + + @override + BaseKeyframeAnimation createAnimation() { + if (keyframes.first.isStatic) { + return PointKeyframeAnimation(keyframes); + } + return PathKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_point_value.dart b/lottie/lib/src/model/animatable/animatable_point_value.dart new file mode 100644 index 0000000..cad64d8 --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_point_value.dart @@ -0,0 +1,12 @@ +import 'dart:ui'; +import '../../animation/keyframe/point_keyframe_animation.dart'; +import 'base_animatable_value.dart'; + +class AnimatablePointValue extends BaseAnimatableValue { + AnimatablePointValue.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + PointKeyframeAnimation createAnimation() { + return PointKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_scale_value.dart b/lottie/lib/src/model/animatable/animatable_scale_value.dart new file mode 100644 index 0000000..811d2ea --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_scale_value.dart @@ -0,0 +1,17 @@ +import 'dart:ui'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/point_keyframe_animation.dart'; +import 'base_animatable_value.dart'; + +class AnimatableScaleValue extends BaseAnimatableValue { + AnimatableScaleValue.one() : this(const Offset(1, 1)); + + AnimatableScaleValue(super.value) : super.fromValue(); + + AnimatableScaleValue.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + BaseKeyframeAnimation createAnimation() { + return PointKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_shape_value.dart b/lottie/lib/src/model/animatable/animatable_shape_value.dart new file mode 100644 index 0000000..e6dd1fc --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_shape_value.dart @@ -0,0 +1,13 @@ +import 'dart:ui'; +import '../../animation/keyframe/shape_keyframe_animation.dart'; +import '../content/shape_data.dart'; +import 'base_animatable_value.dart'; + +class AnimatableShapeValue extends BaseAnimatableValue { + AnimatableShapeValue.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + ShapeKeyframeAnimation createAnimation() { + return ShapeKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_split_dimension_path_value.dart b/lottie/lib/src/model/animatable/animatable_split_dimension_path_value.dart new file mode 100644 index 0000000..ce57d9f --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_split_dimension_path_value.dart @@ -0,0 +1,36 @@ +import 'dart:ui'; +import '../../animation/keyframe/split_dimension_path_keyframe_animation.dart'; +import '../../value/keyframe.dart'; +import 'animatable_double_value.dart'; +import 'animatable_value.dart'; + +class AnimatableSplitDimensionPathValue + implements AnimatableValue { + final AnimatableDoubleValue _animatableXDimension; + final AnimatableDoubleValue _animatableYDimension; + + AnimatableSplitDimensionPathValue( + this._animatableXDimension, + this._animatableYDimension, + ); + + @override + List> get keyframes { + throw UnsupportedError( + 'Cannot call getKeyframes on AnimatableSplitDimensionPathValue.', + ); + } + + @override + bool get isStatic { + return _animatableXDimension.isStatic && _animatableYDimension.isStatic; + } + + @override + SplitDimensionPathKeyframeAnimation createAnimation() { + return SplitDimensionPathKeyframeAnimation( + _animatableXDimension.createAnimation(), + _animatableYDimension.createAnimation(), + ); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_text_frame.dart b/lottie/lib/src/model/animatable/animatable_text_frame.dart new file mode 100644 index 0000000..76cf3d3 --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_text_frame.dart @@ -0,0 +1,13 @@ +import '../../animation/keyframe/text_keyframe_animation.dart'; +import '../document_data.dart'; +import 'base_animatable_value.dart'; + +class AnimatableTextFrame + extends BaseAnimatableValue { + AnimatableTextFrame.fromKeyframes(super.keyframes) : super.fromKeyframes(); + + @override + TextKeyframeAnimation createAnimation() { + return TextKeyframeAnimation(keyframes); + } +} diff --git a/lottie/lib/src/model/animatable/animatable_text_properties.dart b/lottie/lib/src/model/animatable/animatable_text_properties.dart new file mode 100644 index 0000000..7357241 --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_text_properties.dart @@ -0,0 +1,16 @@ +import 'animatable_color_value.dart'; +import 'animatable_double_value.dart'; + +class AnimatableTextProperties { + final AnimatableColorValue? color; + final AnimatableColorValue? stroke; + final AnimatableDoubleValue? strokeWidth; + final AnimatableDoubleValue? tracking; + + AnimatableTextProperties({ + this.color, + this.stroke, + this.strokeWidth, + this.tracking, + }); +} diff --git a/lottie/lib/src/model/animatable/animatable_transform.dart b/lottie/lib/src/model/animatable/animatable_transform.dart new file mode 100644 index 0000000..91d178b --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_transform.dart @@ -0,0 +1,57 @@ +import 'dart:ui'; +import '../../animation/content/content.dart'; +import '../../animation/content/modifier_content.dart'; +import '../../animation/keyframe/transform_keyframe_animation.dart'; +import '../../lottie_drawable.dart'; +import '../content/content_model.dart'; +import '../layer/base_layer.dart'; +import 'animatable_double_value.dart'; +import 'animatable_integer_value.dart'; +import 'animatable_path_value.dart'; +import 'animatable_scale_value.dart'; +import 'animatable_value.dart'; + +class AnimatableTransform implements ModifierContent, ContentModel { + final AnimatablePathValue? anchorPoint; + + final AnimatableValue? position; + + final AnimatableScaleValue? scale; + + final AnimatableDoubleValue? rotation; + + final AnimatableIntegerValue? opacity; + + final AnimatableDoubleValue? skew; + + final AnimatableDoubleValue? skewAngle; + + // Used for repeaters + + final AnimatableDoubleValue? startOpacity; + + final AnimatableDoubleValue? endOpacity; + + bool isAutoOrient = false; + + AnimatableTransform({ + this.anchorPoint, + this.position, + this.scale, + this.rotation, + this.opacity, + this.skew, + this.skewAngle, + this.startOpacity, + this.endOpacity, + }); + + TransformKeyframeAnimation createAnimation() { + return TransformKeyframeAnimation(this); + } + + @override + Content? toContent(LottieDrawable drawable, BaseLayer layer) { + return null; + } +} diff --git a/lottie/lib/src/model/animatable/animatable_value.dart b/lottie/lib/src/model/animatable/animatable_value.dart new file mode 100644 index 0000000..bc7e82d --- /dev/null +++ b/lottie/lib/src/model/animatable/animatable_value.dart @@ -0,0 +1,8 @@ +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../value/keyframe.dart'; + +abstract class AnimatableValue { + List> get keyframes; + bool get isStatic; + BaseKeyframeAnimation createAnimation(); +} diff --git a/lottie/lib/src/model/animatable/base_animatable_value.dart b/lottie/lib/src/model/animatable/base_animatable_value.dart new file mode 100644 index 0000000..54b400b --- /dev/null +++ b/lottie/lib/src/model/animatable/base_animatable_value.dart @@ -0,0 +1,31 @@ +import '../../value/keyframe.dart'; +import 'animatable_value.dart'; + +abstract class BaseAnimatableValue + implements AnimatableValue { + @override + final List> keyframes; + + /// Create a default static animatable path. + BaseAnimatableValue.fromValue(V value) + : this.fromKeyframes([Keyframe.nonAnimated(value)]); + + BaseAnimatableValue.fromKeyframes(this.keyframes); + + @override + bool get isStatic { + return keyframes.isEmpty || + (keyframes.length == 1 && keyframes.first.isStatic); + } + + @override + String toString() { + final sb = StringBuffer(); + if (keyframes.isNotEmpty) { + sb + ..write('values=') + ..write('$keyframes'); + } + return sb.toString(); + } +} diff --git a/lottie/lib/src/model/content/blur_effect.dart b/lottie/lib/src/model/content/blur_effect.dart new file mode 100644 index 0000000..773af12 --- /dev/null +++ b/lottie/lib/src/model/content/blur_effect.dart @@ -0,0 +1,7 @@ +import '../animatable/animatable_double_value.dart'; + +class BlurEffect { + final AnimatableDoubleValue blurriness; + + BlurEffect(this.blurriness); +} diff --git a/lottie/lib/src/model/content/circle_shape.dart b/lottie/lib/src/model/content/circle_shape.dart new file mode 100644 index 0000000..4ff727d --- /dev/null +++ b/lottie/lib/src/model/content/circle_shape.dart @@ -0,0 +1,29 @@ +import 'dart:ui'; +import '../../animation/content/content.dart'; +import '../../animation/content/ellipse_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_point_value.dart'; +import '../animatable/animatable_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class CircleShape implements ContentModel { + final String? name; + final AnimatableValue position; + final AnimatablePointValue size; + final bool isReversed; + final bool hidden; + + CircleShape({ + this.name, + required this.position, + required this.size, + required this.isReversed, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return EllipseContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/content_model.dart b/lottie/lib/src/model/content/content_model.dart new file mode 100644 index 0000000..6168d11 --- /dev/null +++ b/lottie/lib/src/model/content/content_model.dart @@ -0,0 +1,7 @@ +import '../../animation/content/content.dart'; +import '../../lottie_drawable.dart'; +import '../layer/base_layer.dart'; + +abstract class ContentModel { + Content? toContent(LottieDrawable drawable, BaseLayer layer); +} diff --git a/lottie/lib/src/model/content/drop_shadow_effect.dart b/lottie/lib/src/model/content/drop_shadow_effect.dart new file mode 100644 index 0000000..4d7c701 --- /dev/null +++ b/lottie/lib/src/model/content/drop_shadow_effect.dart @@ -0,0 +1,30 @@ +import 'package:flutter/painting.dart'; +import '../../value/keyframe.dart'; +import '../animatable/animatable_color_value.dart'; +import '../animatable/animatable_double_value.dart'; + +class DropShadowEffect { + final AnimatableColorValue color; + final AnimatableDoubleValue opacity; + final AnimatableDoubleValue direction; + final AnimatableDoubleValue distance; + final AnimatableDoubleValue radius; + + DropShadowEffect({ + required this.color, + required this.opacity, + required this.direction, + required this.distance, + required this.radius, + }); + + static DropShadowEffect createEmpty() => DropShadowEffect( + color: AnimatableColorValue.fromKeyframes([ + Keyframe.nonAnimated(const Color(0x00000000)), + ]), + direction: AnimatableDoubleValue(), + radius: AnimatableDoubleValue(), + distance: AnimatableDoubleValue(), + opacity: AnimatableDoubleValue(), + ); +} diff --git a/lottie/lib/src/model/content/gradient_color.dart b/lottie/lib/src/model/content/gradient_color.dart new file mode 100644 index 0000000..cf8a4c2 --- /dev/null +++ b/lottie/lib/src/model/content/gradient_color.dart @@ -0,0 +1,109 @@ +import 'dart:ui'; +import '../../utils.dart'; +import '../../utils/collection.dart'; +import '../../utils/gamma_evaluator.dart'; + +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + +class GradientColor { + final List positions; + final List colors; + + const GradientColor(this.positions, this.colors); + + int get size => colors.length; + + void lerp(GradientColor gc1, GradientColor gc2, double progress) { + // Fast return in case start and end is the same + // or if progress is at start/end or out of [0,1] bounds + if (gc1 == gc2) { + _copyFrom(gc1); + return; + } else if (progress <= 0) { + _copyFrom(gc1); + return; + } else if (progress >= 1) { + _copyFrom(gc2); + return; + } + + if (gc1.colors.length != gc2.colors.length) { + throw Exception( + 'Cannot interpolate between gradients. ' + 'Lengths vary (${gc1.colors.length} vs ${gc2.colors.length})', + ); + } + + for (var i = 0; i < gc1.colors.length; i++) { + positions[i] = lerpDouble(gc1.positions[i], gc2.positions[i], progress)!; + colors[i] = GammaEvaluator.evaluate( + progress, + gc1.colors[i], + gc2.colors[i], + ); + } + // Not all keyframes that this GradientColor are used for will have the same length. + // AnimatableGradientColorValue.ensureInterpolatableKeyframes may add extra positions + // for some keyframes but not others to ensure that it is interpolatable. + // If there are extra positions here, just duplicate the last value in the gradient. + for (var i = gc1.colors.length; i < positions.length; i++) { + positions[i] = positions[gc1.colors.length - 1]; + colors[i] = colors[gc1.colors.length - 1]; + } + } + + GradientColor copyWithPositions(List positions) { + var colors = List.filled(positions.length, const Color(0x00000000)); + for (var i = 0; i < positions.length; i++) { + colors[i] = _getColorForPosition(positions[i]); + } + return GradientColor(positions, colors); + } + + Color _getColorForPosition(double position) { + var existingIndex = binarySearch(positions, position); + if (existingIndex >= 0) { + return colors[existingIndex]; + } + // binarySearch returns -insertionPoint - 1 if it is not found. + var insertionPoint = -(existingIndex + 1); + if (insertionPoint == 0) { + return colors[0]; + } else if (insertionPoint == colors.length - 1) { + return colors[colors.length - 1]; + } + var startPosition = positions[insertionPoint - 1]; + var endPosition = positions[insertionPoint]; + var startColor = colors[insertionPoint - 1]; + var endColor = colors[insertionPoint]; + + var fraction = (position - startPosition) / (endPosition - startPosition); + return GammaEvaluator.evaluate(fraction, startColor, endColor); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + if (other is! GradientColor) { + return false; + } + return const ListEquality().equals(positions, other.positions) && + const ListEquality().equals(colors, other.colors); + } + + @override + int get hashCode { + var result = Object.hashAll(positions); + result = 31 * result + Object.hashAll(colors); + return result; + } + + void _copyFrom(GradientColor other) { + for (var i = 0; i < other.colors.length; i++) { + positions[i] = other.positions[i]; + colors[i] = other.colors[i]; + } + } +} diff --git a/lottie/lib/src/model/content/gradient_fill.dart b/lottie/lib/src/model/content/gradient_fill.dart new file mode 100644 index 0000000..80c1e75 --- /dev/null +++ b/lottie/lib/src/model/content/gradient_fill.dart @@ -0,0 +1,42 @@ +import 'dart:ui'; +import '../../animation/content/content.dart'; +import '../../animation/content/gradient_fill_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_gradient_color_value.dart'; +import '../animatable/animatable_integer_value.dart'; +import '../animatable/animatable_point_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; +import 'gradient_type.dart'; + +class GradientFill implements ContentModel { + final String? name; + final GradientType gradientType; + final PathFillType fillType; + final AnimatableGradientColorValue gradientColor; + final AnimatableIntegerValue opacity; + final AnimatablePointValue startPoint; + final AnimatablePointValue endPoint; + final AnimatableDoubleValue? highlightLength; + final AnimatableDoubleValue? highlightAngle; + final bool hidden; + + GradientFill({ + this.name, + required this.gradientType, + required this.fillType, + required this.gradientColor, + required this.opacity, + required this.startPoint, + required this.endPoint, + this.highlightLength, + this.highlightAngle, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return GradientFillContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/gradient_stroke.dart b/lottie/lib/src/model/content/gradient_stroke.dart new file mode 100644 index 0000000..42e4f7e --- /dev/null +++ b/lottie/lib/src/model/content/gradient_stroke.dart @@ -0,0 +1,48 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/gradient_stroke_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_gradient_color_value.dart'; +import '../animatable/animatable_integer_value.dart'; +import '../animatable/animatable_point_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; +import 'gradient_type.dart'; +import 'shape_stroke.dart'; + +class GradientStroke implements ContentModel { + final String? name; + final GradientType gradientType; + final AnimatableGradientColorValue gradientColor; + final AnimatableIntegerValue opacity; + final AnimatablePointValue startPoint; + final AnimatablePointValue endPoint; + final AnimatableDoubleValue width; + final LineCapType? capType; + final LineJoinType? joinType; + final double miterLimit; + final List lineDashPattern; + final AnimatableDoubleValue? dashOffset; + final bool hidden; + + GradientStroke({ + this.name, + required this.gradientType, + required this.gradientColor, + required this.opacity, + required this.startPoint, + required this.endPoint, + required this.width, + this.capType, + this.joinType, + required this.miterLimit, + required this.lineDashPattern, + this.dashOffset, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return GradientStrokeContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/gradient_type.dart b/lottie/lib/src/model/content/gradient_type.dart new file mode 100644 index 0000000..a2873d2 --- /dev/null +++ b/lottie/lib/src/model/content/gradient_type.dart @@ -0,0 +1 @@ +enum GradientType { linear, radial } diff --git a/lottie/lib/src/model/content/layer_blend.dart b/lottie/lib/src/model/content/layer_blend.dart new file mode 100644 index 0000000..e5d6b09 --- /dev/null +++ b/lottie/lib/src/model/content/layer_blend.dart @@ -0,0 +1,22 @@ +import 'dart:ui'; + +final blendModes = [ + null, // Normal + BlendMode.multiply, + BlendMode.screen, + BlendMode.overlay, + BlendMode.darken, + BlendMode.lighten, + BlendMode.colorDodge, + BlendMode.colorBurn, + BlendMode.hardLight, + BlendMode.softLight, + BlendMode.difference, + BlendMode.exclusion, + BlendMode.hue, + BlendMode.saturation, + BlendMode.color, + BlendMode.luminosity, + BlendMode.plus, + null, // Hard mix +]; diff --git a/lottie/lib/src/model/content/mask.dart b/lottie/lib/src/model/content/mask.dart new file mode 100644 index 0000000..b9f9f20 --- /dev/null +++ b/lottie/lib/src/model/content/mask.dart @@ -0,0 +1,23 @@ +import '../animatable/animatable_integer_value.dart'; +import '../animatable/animatable_shape_value.dart'; + +enum MaskMode { + maskModeAdd, + maskModeSubstract, + maskModeIntersect, + maskModeNone, +} + +class Mask { + final MaskMode maskMode; + final AnimatableShapeValue maskPath; + final AnimatableIntegerValue opacity; + final bool isInverted; + + Mask({ + required this.maskMode, + required this.maskPath, + required this.opacity, + required this.isInverted, + }); +} diff --git a/lottie/lib/src/model/content/merge_paths.dart b/lottie/lib/src/model/content/merge_paths.dart new file mode 100644 index 0000000..b81f7a1 --- /dev/null +++ b/lottie/lib/src/model/content/merge_paths.dart @@ -0,0 +1,48 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/merge_paths_content.dart'; +import '../../lottie_drawable.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +enum MergePathsMode { merge, add, substract, intersect, excludeIntersections } + +class MergePaths implements ContentModel { + final String name; + final MergePathsMode mode; + final bool hidden; + + MergePaths({required this.name, required this.mode, required this.hidden}); + + @override + Content? toContent(LottieDrawable drawable, BaseLayer layer) { + if (!drawable.enableMergePaths) { + drawable.composition.addWarning( + 'Animation contains merge paths but they are disabled.', + ); + return null; + } + return MergePathsContent(this); + } + + @override + String toString() { + return 'MergePaths{mode=$mode}'; + } + + static MergePathsMode modeForId(int id) { + switch (id) { + case 1: + return MergePathsMode.merge; + case 2: + return MergePathsMode.add; + case 3: + return MergePathsMode.substract; + case 4: + return MergePathsMode.intersect; + case 5: + return MergePathsMode.excludeIntersections; + default: + return MergePathsMode.merge; + } + } +} diff --git a/lottie/lib/src/model/content/polystar_shape.dart b/lottie/lib/src/model/content/polystar_shape.dart new file mode 100644 index 0000000..b35b275 --- /dev/null +++ b/lottie/lib/src/model/content/polystar_shape.dart @@ -0,0 +1,60 @@ +import 'dart:ui'; +import '../../animation/content/content.dart'; +import '../../animation/content/polystar_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class PolystarShapeType { + static const star = PolystarShapeType(1); + static const polygon = PolystarShapeType(2); + static const List values = [star, polygon]; + + final int value; + + const PolystarShapeType(this.value); + + static PolystarShapeType? forValue(int value) { + for (var type in values) { + if (type.value == value) { + return type; + } + } + return null; + } +} + +class PolystarShape implements ContentModel { + final String? name; + final PolystarShapeType? type; + final AnimatableDoubleValue points; + final AnimatableValue position; + final AnimatableDoubleValue rotation; + final AnimatableDoubleValue? innerRadius; + final AnimatableDoubleValue outerRadius; + final AnimatableDoubleValue? innerRoundedness; + final AnimatableDoubleValue outerRoundedness; + final bool hidden; + final bool isReversed; + + PolystarShape({ + this.name, + this.type, + required this.points, + required this.position, + required this.rotation, + this.innerRadius, + required this.outerRadius, + this.innerRoundedness, + required this.outerRoundedness, + required this.hidden, + required this.isReversed, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return PolystarContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/rectangle_shape.dart b/lottie/lib/src/model/content/rectangle_shape.dart new file mode 100644 index 0000000..69b4478 --- /dev/null +++ b/lottie/lib/src/model/content/rectangle_shape.dart @@ -0,0 +1,34 @@ +import 'dart:ui'; +import '../../animation/content/content.dart'; +import '../../animation/content/rectangle_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class RectangleShape implements ContentModel { + final String? name; + final AnimatableValue position; + final AnimatableValue size; + final AnimatableDoubleValue cornerRadius; + final bool hidden; + + RectangleShape({ + this.name, + required this.position, + required this.size, + required this.cornerRadius, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return RectangleContent(drawable, layer, this); + } + + @override + String toString() { + return 'RectangleShape{position=$position, size=$size}'; + } +} diff --git a/lottie/lib/src/model/content/repeater.dart b/lottie/lib/src/model/content/repeater.dart new file mode 100644 index 0000000..fe5858f --- /dev/null +++ b/lottie/lib/src/model/content/repeater.dart @@ -0,0 +1,28 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/repeater_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_transform.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class Repeater implements ContentModel { + final String? name; + final AnimatableDoubleValue copies; + final AnimatableDoubleValue offset; + final AnimatableTransform transform; + final bool hidden; + + Repeater({ + this.name, + required this.copies, + required this.offset, + required this.transform, + required this.hidden, + }); + + @override + Content? toContent(LottieDrawable drawable, BaseLayer layer) { + return RepeaterContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/rounded_corners.dart b/lottie/lib/src/model/content/rounded_corners.dart new file mode 100644 index 0000000..f1d5a7b --- /dev/null +++ b/lottie/lib/src/model/content/rounded_corners.dart @@ -0,0 +1,18 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/rounded_corners_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class RoundedCorners implements ContentModel { + final String name; + final AnimatableValue cornerRadius; + + RoundedCorners(this.name, this.cornerRadius); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return RoundedCornersContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/shape_data.dart b/lottie/lib/src/model/content/shape_data.dart new file mode 100644 index 0000000..4826407 --- /dev/null +++ b/lottie/lib/src/model/content/shape_data.dart @@ -0,0 +1,93 @@ +import 'dart:math'; +import 'dart:ui'; +import '../cubic_curve_data.dart'; + +class ShapeData { + final List curves; + Offset _initialPoint; + bool isClosed; + + ShapeData(List curves, {Offset? initialPoint, bool? closed}) + : curves = curves.toList(), + _initialPoint = initialPoint ?? Offset.zero, + isClosed = closed ?? false; + + ShapeData.empty() : this([]); + + void setInitialPoint(double x, double y) { + _initialPoint = Offset(x, y); + } + + Offset get initialPoint { + return _initialPoint; + } + + void interpolateBetween( + ShapeData shapeData1, + ShapeData shapeData2, + double percentage, + ) { + isClosed = shapeData1.isClosed || shapeData2.isClosed; + + if (shapeData1.curves.length != shapeData2.curves.length) { + // TODO(xha): decide what to do? We don't have access to the LottieDrawble + // to emit the warning + //logger.warning('Curves must have the same number of control points. ' + // 'Shape 1: ${shapeData1.curves.length}' + // '\tShape 2: ${shapeData2.curves.length}'); + } + + var points = min(shapeData1.curves.length, shapeData2.curves.length); + if (curves.length < points) { + for (var i = curves.length; i < points; i++) { + curves.add(CubicCurveData()); + } + } else if (curves.length > points) { + for (var i = curves.length - 1; i >= points; i--) { + curves.removeAt(curves.length - 1); + } + } + + var initialPoint1 = shapeData1.initialPoint; + var initialPoint2 = shapeData2.initialPoint; + + setInitialPoint( + lerpDouble(initialPoint1.dx, initialPoint2.dx, percentage)!, + lerpDouble(initialPoint1.dy, initialPoint2.dy, percentage)!, + ); + + for (var i = curves.length - 1; i >= 0; i--) { + var curve1 = shapeData1.curves[i]; + var curve2 = shapeData2.curves[i]; + + var cp11 = curve1.controlPoint1; + var cp21 = curve1.controlPoint2; + var vertex1 = curve1.vertex; + + var cp12 = curve2.controlPoint1; + var cp22 = curve2.controlPoint2; + var vertex2 = curve2.vertex; + + curves[i].controlPoint1 = Offset( + lerpDouble(cp11.dx, cp12.dx, percentage)!, + lerpDouble(cp11.dy, cp12.dy, percentage)!, + ); + curves[i].controlPoint2 = Offset( + lerpDouble(cp21.dx, cp22.dx, percentage)!, + lerpDouble(cp21.dy, cp22.dy, percentage)!, + ); + curves[i].vertex = Offset( + lerpDouble(vertex1.dx, vertex2.dx, percentage)!, + lerpDouble(vertex1.dy, vertex2.dy, percentage)!, + ); + } + } + + @override + String toString() { + return 'ShapeData{' + 'numCurves=${curves.length}' + 'closed=$isClosed' + '}'; + } +} diff --git a/lottie/lib/src/model/content/shape_fill.dart b/lottie/lib/src/model/content/shape_fill.dart new file mode 100644 index 0000000..e505472 --- /dev/null +++ b/lottie/lib/src/model/content/shape_fill.dart @@ -0,0 +1,39 @@ +import 'dart:ui'; +import '../../animation/content/content.dart'; +import '../../animation/content/fill_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_color_value.dart'; +import '../animatable/animatable_integer_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class ShapeFill implements ContentModel { + final bool fillEnabled; + final PathFillType fillType; + final String? name; + final AnimatableColorValue? color; + final AnimatableIntegerValue? opacity; + final bool hidden; + + ShapeFill({ + required this.fillEnabled, + required this.fillType, + this.name, + this.color, + this.opacity, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return FillContent(drawable, layer, this); + } + + @override + String toString() { + return 'ShapeFill{' + 'color=' + ', fillEnabled=$fillEnabled' + '}'; + } +} diff --git a/lottie/lib/src/model/content/shape_group.dart b/lottie/lib/src/model/content/shape_group.dart new file mode 100644 index 0000000..2aeba40 --- /dev/null +++ b/lottie/lib/src/model/content/shape_group.dart @@ -0,0 +1,23 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/content_group.dart'; +import '../../lottie_drawable.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class ShapeGroup implements ContentModel { + final String? name; + final List items; + final bool hidden; + + ShapeGroup(this.name, this.items, {required this.hidden}); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return ContentGroup(drawable, layer, this); + } + + @override + String toString() { + return "ShapeGroup{name: '$name' Shapes: $items}"; + } +} diff --git a/lottie/lib/src/model/content/shape_path.dart b/lottie/lib/src/model/content/shape_path.dart new file mode 100644 index 0000000..5bee343 --- /dev/null +++ b/lottie/lib/src/model/content/shape_path.dart @@ -0,0 +1,30 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/shape_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_shape_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +class ShapePath implements ContentModel { + final String? name; + final int index; + final AnimatableShapeValue shapePath; + final bool hidden; + + ShapePath({ + this.name, + required this.index, + required this.shapePath, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return ShapeContent(drawable, layer, this); + } + + @override + String toString() { + return 'ShapePath{name=$name, index=$index}'; + } +} diff --git a/lottie/lib/src/model/content/shape_stroke.dart b/lottie/lib/src/model/content/shape_stroke.dart new file mode 100644 index 0000000..ae43365 --- /dev/null +++ b/lottie/lib/src/model/content/shape_stroke.dart @@ -0,0 +1,68 @@ +import 'dart:ui' as ui; +import '../../animation/content/content.dart'; +import '../../animation/content/stroke_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_color_value.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_integer_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +enum LineCapType { butt, round, unknown } + +ui.StrokeCap lineCapTypeToPaintCap(LineCapType? cap) { + switch (cap) { + case LineCapType.butt: + return ui.StrokeCap.butt; + case LineCapType.round: + return ui.StrokeCap.round; + case LineCapType.unknown: + case null: + return ui.StrokeCap.butt; + } +} + +enum LineJoinType { miter, round, bevel } + +ui.StrokeJoin lineJoinTypeToPaintJoin(LineJoinType? join) { + switch (join) { + case LineJoinType.bevel: + return ui.StrokeJoin.bevel; + case LineJoinType.round: + return ui.StrokeJoin.round; + case LineJoinType.miter: + case null: + return ui.StrokeJoin.miter; + } +} + +class ShapeStroke implements ContentModel { + final String? name; + final AnimatableDoubleValue? dashOffset; + final List lineDashPattern; + final AnimatableColorValue color; + final AnimatableIntegerValue opacity; + final AnimatableDoubleValue width; + final LineCapType? capType; + final LineJoinType? joinType; + final double miterLimit; + final bool hidden; + + ShapeStroke({ + this.name, + this.dashOffset, + required this.lineDashPattern, + required this.color, + required this.opacity, + required this.width, + this.capType, + this.joinType, + required this.miterLimit, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return StrokeContent(drawable, layer, this); + } +} diff --git a/lottie/lib/src/model/content/shape_trim_path.dart b/lottie/lib/src/model/content/shape_trim_path.dart new file mode 100644 index 0000000..0667f92 --- /dev/null +++ b/lottie/lib/src/model/content/shape_trim_path.dart @@ -0,0 +1,47 @@ +import '../../animation/content/content.dart'; +import '../../animation/content/trim_path_content.dart'; +import '../../lottie_drawable.dart'; +import '../animatable/animatable_double_value.dart'; +import '../layer/base_layer.dart'; +import 'content_model.dart'; + +enum ShapeTrimPathType { simultaneously, individually } + +class ShapeTrimPath implements ContentModel { + final String? name; + final ShapeTrimPathType type; + final AnimatableDoubleValue start; + final AnimatableDoubleValue end; + final AnimatableDoubleValue offset; + final bool hidden; + + ShapeTrimPath({ + this.name, + required this.type, + required this.start, + required this.end, + required this.offset, + required this.hidden, + }); + + @override + Content toContent(LottieDrawable drawable, BaseLayer layer) { + return TrimPathContent(layer, this); + } + + @override + String toString() { + return 'Trim Path: {start: $start, end: $end, offset: $offset}'; + } + + static ShapeTrimPathType typeForId(int id) { + switch (id) { + case 1: + return ShapeTrimPathType.simultaneously; + case 2: + return ShapeTrimPathType.individually; + default: + throw Exception('Unknown trim path type $id'); + } + } +} diff --git a/lottie/lib/src/model/cubic_curve_data.dart b/lottie/lib/src/model/cubic_curve_data.dart new file mode 100644 index 0000000..0b4d876 --- /dev/null +++ b/lottie/lib/src/model/cubic_curve_data.dart @@ -0,0 +1,48 @@ +import 'dart:ui'; + +/// One cubic path operation. CubicCurveData is structured such that it is easy to iterate through +/// it and build a path. However, it is modeled differently than most path operations. +/// +/// CubicCurveData +/// | - vertex +/// | / +/// | cp1 cp2 +/// | / +/// | | +/// | / +/// -------------------------- +/// +/// When incrementally building a path, it will already have a "current point" so that is +/// not captured in this data structure. +/// The control points here represent {@link android.graphics.Path#cubicTo(float, float, float, float, float, float)}. +/// +/// Most path operations are centered around a vertex and its in control point and out control point like this: +/// | outCp +/// | / +/// | | +/// | v +/// | / +/// | inCp +/// -------------------------- +class CubicCurveData { + Offset controlPoint1 = Offset.zero; + Offset controlPoint2 = Offset.zero; + Offset vertex = Offset.zero; + + void setFrom(CubicCurveData curveData) { + vertex = Offset(curveData.vertex.dx, curveData.vertex.dy); + controlPoint1 = Offset( + curveData.controlPoint1.dx, + curveData.controlPoint1.dy, + ); + controlPoint2 = Offset( + curveData.controlPoint2.dx, + curveData.controlPoint2.dy, + ); + } + + @override + String toString() { + return 'v=$vertex cp1$controlPoint1 cp2=$controlPoint2'; + } +} diff --git a/lottie/lib/src/model/document_data.dart b/lottie/lib/src/model/document_data.dart new file mode 100644 index 0000000..89a023a --- /dev/null +++ b/lottie/lib/src/model/document_data.dart @@ -0,0 +1,77 @@ +import 'dart:ui'; +import 'package:flutter/foundation.dart'; + +enum Justification { leftAlign, rightAlign, center } + +@immutable +class DocumentData { + final String text; + final String? fontName; + final double size; + final Justification justification; + final int tracking; + + /// Extra space in between lines. */ + final double lineHeight; + final double baselineShift; + final Color color; + final Color strokeColor; + final double strokeWidth; + final bool strokeOverFill; + final Offset? boxPosition; + final Offset? boxSize; + + const DocumentData({ + required this.text, + this.fontName, + required this.size, + required this.justification, + required this.tracking, + required this.lineHeight, + required this.baselineShift, + required this.color, + required this.strokeColor, + required this.strokeWidth, + required this.strokeOverFill, + required this.boxPosition, + required this.boxSize, + }); + + @override + int get hashCode { + return Object.hash( + text, + fontName, + size, + justification.index, + tracking, + lineHeight, + baselineShift, + color, + strokeColor, + strokeWidth, + strokeOverFill, + boxPosition, + boxSize, + ); + } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is DocumentData && + runtimeType == other.runtimeType && + text == other.text && + fontName == other.fontName && + size == other.size && + justification == other.justification && + tracking == other.tracking && + lineHeight == other.lineHeight && + baselineShift == other.baselineShift && + color == other.color && + strokeColor == other.strokeColor && + strokeWidth == other.strokeWidth && + strokeOverFill == other.strokeOverFill && + boxPosition == other.boxPosition && + boxSize == other.boxSize; +} diff --git a/lottie/lib/src/model/font.dart b/lottie/lib/src/model/font.dart new file mode 100644 index 0000000..5a3c7fe --- /dev/null +++ b/lottie/lib/src/model/font.dart @@ -0,0 +1,13 @@ +class Font { + final String family; + final String name; + final String style; + final double ascent; + + Font({ + required this.family, + required this.name, + required this.style, + required this.ascent, + }); +} diff --git a/lottie/lib/src/model/font_character.dart b/lottie/lib/src/model/font_character.dart new file mode 100644 index 0000000..a7532d1 --- /dev/null +++ b/lottie/lib/src/model/font_character.dart @@ -0,0 +1,45 @@ +import 'package:flutter/foundation.dart'; +import 'content/shape_group.dart'; + +@immutable +class FontCharacter { + static int hashFor(String character, String fontFamily, String style) { + var result = character.hashCode; + result = 31 * result + fontFamily.hashCode; + result = 31 * result + style.hashCode; + return result; + } + + final List shapes; + final String character; + final double size; + final double width; + final String style; + final String fontFamily; + + const FontCharacter({ + required this.shapes, + required this.character, + required this.size, + required this.width, + required this.style, + required this.fontFamily, + }); + + @override + int get hashCode { + return hashFor(character, fontFamily, style); + } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is FontCharacter && + runtimeType == other.runtimeType && + shapes == other.shapes && + character == other.character && + size == other.size && + width == other.width && + style == other.style && + fontFamily == other.fontFamily; +} diff --git a/lottie/lib/src/model/key_path.dart b/lottie/lib/src/model/key_path.dart new file mode 100644 index 0000000..f26c57d --- /dev/null +++ b/lottie/lib/src/model/key_path.dart @@ -0,0 +1,172 @@ +import 'key_path_element.dart'; + +/// Defines which content to target. +/// The keypath can contain wildcards ('*') with match exactly 1 item. +/// or globstars ('**') which match 0 or more items. +/// +/// For example, if your content were arranged like this: +/// Gabriel (Shape Layer) +/// Body (Shape Group) +/// Left Hand (Shape) +/// Fill (Fill) +/// Transform (Transform) +/// ... +/// Brandon (Shape Layer) +/// Body (Shape Group) +/// Left Hand (Shape) +/// Fill (Fill) +/// Transform (Transform) +/// ... +/// +/// +/// You could: +/// Match Gabriel left hand fill: +/// new KeyPath("Gabriel", "Body", "Left Hand", "Fill"); +/// Match Gabriel and Brandon's left hand fill: +/// new KeyPath("*", "Body", Left Hand", "Fill"); +/// Match anything with the name Fill: +/// new KeyPath("**", "Fill"); +/// +/// +/// NOTE: Content that are part of merge paths or repeaters cannot currently be resolved with +/// a {@link KeyPath}. This may be fixed in the future. +class KeyPath { + final List keys; + KeyPathElement? _resolvedElement; + + KeyPath(List keys) : keys = keys.toList(); + + /// Copy constructor. Copies keys as well. + KeyPath.copy(KeyPath keyPath) + : keys = keyPath.keys.toList(), + _resolvedElement = keyPath._resolvedElement; + + /// Returns a new KeyPath with the key added. + /// This is used during keypath resolution. Children normally don't know about all of their parent + /// elements so this is used to keep track of the fully qualified keypath. + /// This returns a key keypath because during resolution, the full keypath element tree is walked + /// and if this modified the original copy, it would remain after popping back up the element tree. + //@CheckResult + KeyPath addKey(String key) { + var newKeyPath = KeyPath.copy(this); + newKeyPath.keys.add(key); + return newKeyPath; + } + + /// Return a new KeyPath with the element resolved to the specified {@link KeyPathElement}. + KeyPath resolve(KeyPathElement element) { + var keyPath = KeyPath.copy(this); + keyPath._resolvedElement = element; + return keyPath; + } + + /// Returns a {@link KeyPathElement} that this has been resolved to. KeyPaths get resolved with + /// resolveKeyPath on LottieDrawable. + KeyPathElement? get resolvedElement { + return _resolvedElement; + } + + /// Returns whether they key matches at the specified depth. + bool matches(String? key, int depth) { + if (isContainer(key)) { + // This is an artificial layer we programatically create. + return true; + } + if (depth >= keys.length) { + return false; + } + if (keys[depth] == key || keys[depth] == '**' || keys[depth] == '*') { + return true; + } + return false; + } + + /// For a given key and depth, returns how much the depth should be incremented by when + /// resolving a keypath to children. + /// + /// This can be 0 or 2 when there is a globstar and the next key either matches or doesn't match + /// the current key. + int incrementDepthBy(String? key, int depth) { + if (isContainer(key)) { + // If it's a container then we added programatically and it isn't a part of the keypath. + return 0; + } + if (keys[depth] != '**') { + // If it's not a globstar then it is part of the keypath. + return 1; + } + if (depth == keys.length - 1) { + // The last key is a globstar. + return 0; + } + if (keys[depth + 1] == key) { + // We are a globstar and the next key is our current key so consume both. + return 2; + } + return 0; + } + + /// Returns whether the key at specified depth is fully specific enough to match the full set of + /// keys in this keypath. + bool fullyResolvesTo(String? key, int depth) { + if (depth >= keys.length) { + return false; + } + var isLastDepth = depth == keys.length - 1; + var keyAtDepth = keys[depth]; + var isGlobstar = keyAtDepth == '**'; + + if (!isGlobstar) { + var matches = keyAtDepth == key || keyAtDepth == '*'; + return (isLastDepth || + (depth == keys.length - 2 && endsWithGlobstar())) && + matches; + } + + var isGlobstarButNextKeyMatches = !isLastDepth && keys[depth + 1] == key; + if (isGlobstarButNextKeyMatches) { + return depth == keys.length - 2 || + (depth == keys.length - 3 && endsWithGlobstar()); + } + + if (isLastDepth) { + return true; + } + if (depth + 1 < keys.length - 1) { + // We are a globstar but there is more than 1 key after the globstar we we can't fully match. + return false; + } + // Return whether the next key (which we now know is the last one) is the same as the current + // key. + return keys[depth + 1] == key; + } + + /// Returns whether the keypath resolution should propagate to children. Some keypaths resolve + /// to content other than leaf contents (such as a layer or content group transform) so sometimes + /// this will return false. + bool propagateToChildren(String? key, int depth) { + if ('__container' == key) { + return true; + } + return depth < keys.length - 1 || keys[depth] == '**'; + } + + /// We artificially create some container groups (like a root ContentGroup for the entire animation + /// and for the contents of a ShapeLayer). + bool isContainer(String? key) { + return '__container' == key; + } + + bool endsWithGlobstar() { + return keys[keys.length - 1] == '**'; + } + + String keysToString() { + return keys.toString(); + } + + @override + String toString() { + return 'KeyPath{keys=$keys,resolved=${resolvedElement != null}}'; + } +} diff --git a/lottie/lib/src/model/key_path_element.dart b/lottie/lib/src/model/key_path_element.dart new file mode 100644 index 0000000..a8ebfd2 --- /dev/null +++ b/lottie/lib/src/model/key_path_element.dart @@ -0,0 +1,29 @@ +import '../value/lottie_value_callback.dart'; +import 'key_path.dart'; + +/// Any item that can be a part of a {@link KeyPath} should implement this. +abstract class KeyPathElement { + /// Called recursively during keypath resolution. + /// + /// The overridden method should just call: + /// MiscUtils.resolveKeyPath(keyPath, depth, accumulator, currentPartialKeyPath, this); + /// + /// @param keyPath The full keypath being resolved. + /// @param depth The current depth that this element should be checked at in the keypath. + /// @param accumulator A list of fully resolved keypaths. If this element fully matches the + /// keypath then it should add itself to this list. + /// @param currentPartialKeyPath A keypath that contains all parent element of this one. + /// This element should create a copy of this and append itself + /// with KeyPath#addKey when it adds itself to the accumulator + /// or propagates resolution to its children. + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ); + + /// The overridden method should handle appropriate properties and set value callbacks on their + /// animations. + void addValueCallback(T property, LottieValueCallback? callback); +} diff --git a/lottie/lib/src/model/layer/base_layer.dart b/lottie/lib/src/model/layer/base_layer.dart new file mode 100644 index 0000000..4553543 --- /dev/null +++ b/lottie/lib/src/model/layer/base_layer.dart @@ -0,0 +1,689 @@ +import 'dart:math'; +import 'dart:ui' as ui; +import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart' hide Layer; +import '../../animation/content/content.dart'; +import '../../animation/content/drawing_content.dart'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/double_keyframe_animation.dart'; +import '../../animation/keyframe/mask_keyframe_animation.dart'; +import '../../animation/keyframe/transform_keyframe_animation.dart'; +import '../../composition.dart'; +import '../../l.dart'; +import '../../lottie_drawable.dart'; +import '../../utils.dart'; +import '../../value/lottie_value_callback.dart'; +import '../content/blur_effect.dart'; +import '../content/drop_shadow_effect.dart'; +import '../content/mask.dart'; +import '../content/shape_data.dart'; +import '../key_path.dart'; +import '../key_path_element.dart'; +import 'composition_layer.dart'; +import 'image_layer.dart'; +import 'layer.dart'; +import 'null_layer.dart'; +import 'shape_layer.dart'; +import 'solid_layer.dart'; +import 'text_layer.dart'; + +abstract class BaseLayer implements DrawingContent, KeyPathElement { + static BaseLayer? forModel( + CompositionLayer compositionLayer, + Layer layerModel, + LottieDrawable drawable, + LottieComposition composition, + ) { + switch (layerModel.layerType) { + case LayerType.shape: + return ShapeLayer(drawable, layerModel, compositionLayer); + case LayerType.preComp: + return CompositionLayer( + drawable, + layerModel, + composition.getPrecomps(layerModel.refId)!, + composition, + ); + case LayerType.solid: + return SolidLayer(drawable, layerModel); + case LayerType.image: + return ImageLayer(drawable, layerModel); + case LayerType.nullLayer: + return NullLayer(drawable, layerModel); + case LayerType.text: + return TextLayer(drawable, layerModel); + case LayerType.unknown: + // Do nothing + drawable.composition.addWarning( + 'Unknown layer type ${layerModel.layerType}', + ); + return null; + } + } + + final Matrix4 _matrix = Matrix4.identity(); + final Paint _contentPaint = ui.Paint(); + final Paint _dstInPaint = ui.Paint()..blendMode = ui.BlendMode.dstIn; + final Paint _dstOutPaint = ui.Paint()..blendMode = ui.BlendMode.dstOut; + final Paint _mattePaint = ui.Paint(); + final Paint _clearPaint = ui.Paint() + ..isAntiAlias = false + ..blendMode = ui.BlendMode.clear; + final String _drawTraceName; + final Matrix4 boundsMatrix = Matrix4.identity(); + final LottieDrawable lottieDrawable; + final Layer layerModel; + + MaskKeyframeAnimation? _mask; + DoubleKeyframeAnimation? _inOutAnimation; + BaseLayer? _matteLayer; + + /// This should only be used by {@link #buildParentLayerListIfNeeded()} + /// to construct the list of parent layers. + BaseLayer? _parentLayer; + List? _parentLayers; + + final List _animations = []; + final TransformKeyframeAnimation transform; + bool _visible = true; + + double blurMaskFilterRadius = 0; + MaskFilter? blurMaskFilter; + + BaseLayer(this.lottieDrawable, this.layerModel) + : _drawTraceName = '${layerModel.name}#draw', + transform = layerModel.transform.createAnimation() { + if (layerModel.matteType == MatteType.invert) { + _mattePaint.blendMode = BlendMode.dstOut; + } else { + _mattePaint.blendMode = BlendMode.dstIn; + } + + transform.addListener(invalidateSelf); + + if (layerModel.masks.isNotEmpty) { + var mask = _mask = MaskKeyframeAnimation(layerModel.masks); + for (var animation in mask.maskAnimations) { + // Don't call addAnimation() because progress gets set manually in setProgress to + // properly handle time scale. + animation.addUpdateListener(invalidateSelf); + } + for (var animation in mask.opacityAnimations) { + addAnimation(animation); + animation.addUpdateListener(invalidateSelf); + } + } + _setupInOutAnimations(); + } + + void setMatteLayer(BaseLayer? matteLayer) { + _matteLayer = matteLayer; + } + + bool hasMatteOnThisLayer() { + return _matteLayer != null; + } + + void setParentLayer(BaseLayer? parentLayer) { + _parentLayer = parentLayer; + } + + void _setupInOutAnimations() { + if (layerModel.inOutKeyframes.isNotEmpty) { + var inOutAnimation = _inOutAnimation = DoubleKeyframeAnimation( + layerModel.inOutKeyframes, + )..setIsDiscrete(); + inOutAnimation.addUpdateListener(() { + _setVisible(inOutAnimation.value == 1); + }); + _setVisible(inOutAnimation.value == 1); + addAnimation(inOutAnimation); + } else { + _setVisible(true); + } + } + + void invalidateSelf() { + lottieDrawable.invalidateSelf(); + } + + void addAnimation(BaseKeyframeAnimation? newAnimation) { + if (newAnimation == null) { + return; + } + _animations.add(newAnimation); + } + + void removeAnimation(BaseKeyframeAnimation? animation) { + _animations.remove(animation); + } + + @mustCallSuper + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + _buildParentLayerListIfNeeded(); + boundsMatrix.set(parentMatrix); + + if (applyParents) { + if (_parentLayers != null) { + for (var i = _parentLayers!.length - 1; i >= 0; i--) { + boundsMatrix.preConcat(_parentLayers![i].transform.getMatrix()); + } + } else if (_parentLayer != null) { + boundsMatrix.preConcat(_parentLayer!.transform.getMatrix()); + } + } + + boundsMatrix.preConcat(transform.getMatrix()); + + return Rect.zero; + } + + @override + void draw(Canvas canvas, Matrix4 parentMatrix, {required int parentAlpha}) { + L.beginSection(_drawTraceName); + if (!_visible || layerModel.isHidden) { + L.endSection(_drawTraceName); + return; + } + _buildParentLayerListIfNeeded(); + L.beginSection('Layer#parentMatrix'); + _matrix.reset(); + _matrix.set(parentMatrix); + for (var i = _parentLayers!.length - 1; i >= 0; i--) { + _matrix.preConcat(_parentLayers![i].transform.getMatrix()); + } + L.endSection('Layer#parentMatrix'); + var opacity = transform.opacity?.value ?? 100; + var alpha = ((parentAlpha / 255.0 * opacity / 100.0) * 255).toInt(); + var blendMode = this.blendMode; + if (!hasMatteOnThisLayer() && !hasMasksOnThisLayer() && blendMode == null) { + _matrix.preConcat(transform.getMatrix()); + L.beginSection('Layer#drawLayer'); + drawLayer(canvas, _matrix, parentAlpha: alpha); + L.endSection('Layer#drawLayer'); + _recordRenderTime(L.endSection(_drawTraceName)); + return; + } + + L.beginSection('Layer#computeBounds'); + var bounds = getBounds(_matrix, applyParents: false); + + // Uncomment this to draw matte outlines. + /*var paint = Paint() + ..color = Color(0xFF00FF00) + ..style = PaintingStyle.stroke + ..strokeWidth = 3; + canvas.drawRect(bounds, paint);*/ + + bounds = _intersectBoundsWithMatte(bounds, parentMatrix); + + _matrix.preConcat(transform.getMatrix()); + bounds = _intersectBoundsWithMask(bounds, _matrix); + + L.endSection('Layer#computeBounds'); + + if (!bounds.isEmpty) { + L.beginSection('Layer#saveLayer'); + _contentPaint.setAlpha(255); + _contentPaint.blendMode = blendMode ?? ui.BlendMode.srcOver; + canvas.saveLayer(bounds, _contentPaint); + L.endSection('Layer#saveLayer'); + + // Clear the off screen buffer. This is necessary for some phones. + _clearCanvas(canvas, bounds); + L.beginSection('Layer#drawLayer'); + drawLayer(canvas, _matrix, parentAlpha: alpha); + L.endSection('Layer#drawLayer'); + + if (hasMasksOnThisLayer()) { + _applyMasks(canvas, bounds, _matrix); + } + + if (hasMatteOnThisLayer()) { + L.beginSection('Layer#drawMatte'); + L.beginSection('Layer#saveLayer'); + canvas.saveLayer(bounds, _mattePaint); + L.endSection('Layer#saveLayer'); + _clearCanvas(canvas, bounds); + _matteLayer!.draw(canvas, parentMatrix, parentAlpha: alpha); + L.beginSection('Layer#restoreLayer'); + canvas.restore(); + L.endSection('Layer#restoreLayer'); + L.endSection('Layer#drawMatte'); + } + + L.beginSection('Layer#restoreLayer'); + canvas.restore(); + L.endSection('Layer#restoreLayer'); + } + + _recordRenderTime(L.endSection(_drawTraceName)); + } + + void _recordRenderTime(double ms) { + lottieDrawable.composition.performanceTracker.recordRenderTime( + layerModel.name, + ms, + ); + } + + void _clearCanvas(Canvas canvas, Rect bounds) { + L.beginSection('Layer#clearLayer'); + // If we don't pad the clear draw, some phones leave a 1px border of the graphics buffer. + canvas.drawRect(bounds.inflate(1), _clearPaint); + L.endSection('Layer#clearLayer'); + } + + Rect _intersectBoundsWithMask(Rect bounds, Matrix4 matrix) { + if (!hasMasksOnThisLayer()) { + return bounds; + } + var size = _mask!.masks.length; + var maskBoundsRect = Rect.zero; + for (var i = 0; i < size; i++) { + var mask = _mask!.masks[i]; + BaseKeyframeAnimation maskAnimation = + _mask!.maskAnimations[i]; + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + + switch (mask.maskMode) { + case MaskMode.maskModeNone: + // Mask mode none will just render the original content so it is the whole bounds. + return bounds; + case MaskMode.maskModeSubstract: + // If there is a subtract mask, the mask could potentially be the size of the entire + // canvas so we can't use the mask bounds. + return bounds; + case MaskMode.maskModeIntersect: + case MaskMode.maskModeAdd: + if (mask.isInverted) { + return bounds; + } + + var maskBounds = path.getBounds(); + // As we iterate through the masks, we want to calculate the union region of the masks. + // We initialize the rect with the first mask. If we don't call set() on the first call, + // the rect will always extend to (0,0). + if (i == 0) { + maskBoundsRect = maskBounds; + } else { + maskBoundsRect = Rect.fromLTRB( + min(maskBoundsRect.left, maskBounds.left), + min(maskBoundsRect.top, maskBounds.top), + max(maskBoundsRect.right, maskBounds.right), + max(maskBoundsRect.bottom, maskBounds.bottom), + ); + } + } + } + + var intersects = bounds.intersect(maskBoundsRect); + if (intersects.isEmpty) { + return Rect.zero; + } + return bounds; + } + + Rect _intersectBoundsWithMatte(Rect bounds, Matrix4 matrix) { + if (!hasMatteOnThisLayer()) { + return bounds; + } + + if (layerModel.matteType == MatteType.invert) { + // We can't trim the bounds if the mask is inverted since it extends all the way to the + // composition bounds. + return bounds; + } + var matteBounds = _matteLayer!.getBounds(matrix, applyParents: true); + var intersects = bounds.intersect(matteBounds); + if (intersects.isEmpty) { + return Rect.zero; + } + return bounds; + } + + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }); + + void _applyMasks(Canvas canvas, Rect bounds, Matrix4 matrix) { + L.beginSection('Layer#saveLayer'); + canvas.saveLayer(bounds, _dstInPaint); + //TODO(xha): check if needed + //canvas.drawColor(Color(0), BlendMode.dst); + + L.endSection('Layer#saveLayer'); + for (var i = 0; i < _mask!.masks.length; i++) { + var mask = _mask!.masks[i]; + var maskAnimation = _mask!.maskAnimations[i]; + var opacityAnimation = _mask!.opacityAnimations[i]; + switch (mask.maskMode) { + case MaskMode.maskModeNone: + // None mask should have no effect. If all masks are NONE, fill the + // mask canvas with a rectangle so it fully covers the original layer content. + // However, if there are other masks, they should be the only ones that have an effect so + // this should noop. + if (_areAllMasksNone()) { + _contentPaint.setAlpha(255); + canvas.drawRect(bounds, _contentPaint); + } + case MaskMode.maskModeAdd: + if (mask.isInverted) { + _applyInvertedAddMask( + canvas, + bounds, + matrix, + mask, + maskAnimation, + opacityAnimation, + ); + } else { + _applyAddMask( + canvas, + matrix, + mask, + maskAnimation, + opacityAnimation, + ); + } + case MaskMode.maskModeSubstract: + if (i == 0) { + _contentPaint.color = const ui.Color(0xFF000000); + canvas.drawRect(bounds, _contentPaint); + } + if (mask.isInverted) { + _applyInvertedSubtractMask( + canvas, + bounds, + matrix, + mask, + maskAnimation, + opacityAnimation, + ); + } else { + _applySubtractMask( + canvas, + matrix, + mask, + maskAnimation, + opacityAnimation, + ); + } + case MaskMode.maskModeIntersect: + if (mask.isInverted) { + _applyInvertedIntersectMask( + canvas, + bounds, + matrix, + mask, + maskAnimation, + opacityAnimation, + ); + } else { + _applyIntersectMask( + canvas, + bounds, + matrix, + mask, + maskAnimation, + opacityAnimation, + ); + } + } + } + L.beginSection('Layer#restoreLayer'); + canvas.restore(); + L.endSection('Layer#restoreLayer'); + } + + bool _areAllMasksNone() { + if (_mask == null || _mask!.maskAnimations.isEmpty) { + return false; + } + for (var i = 0; i < _mask!.masks.length; i++) { + if (_mask!.masks[i].maskMode != MaskMode.maskModeNone) { + return false; + } + } + return true; + } + + void _applyAddMask( + Canvas canvas, + Matrix4 matrix, + Mask mask, + BaseKeyframeAnimation maskAnimation, + BaseKeyframeAnimation opacityAnimation, + ) { + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + _contentPaint.setAlpha((opacityAnimation.value * 2.55).round()); + canvas.drawPath(path, _contentPaint); + } + + void _applyInvertedAddMask( + Canvas canvas, + Rect bounds, + Matrix4 matrix, + Mask mask, + BaseKeyframeAnimation maskAnimation, + BaseKeyframeAnimation opacityAnimation, + ) { + canvas.saveLayer(bounds, _contentPaint); + canvas.drawRect(bounds, _contentPaint); + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + _contentPaint.setAlpha((opacityAnimation.value * 2.55).round()); + canvas.drawPath(path, _dstOutPaint); + canvas.restore(); + } + + void _applySubtractMask( + Canvas canvas, + Matrix4 matrix, + Mask mask, + BaseKeyframeAnimation maskAnimation, + BaseKeyframeAnimation opacityAnimation, + ) { + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + canvas.drawPath(path, _dstOutPaint); + } + + void _applyInvertedSubtractMask( + Canvas canvas, + Rect bounds, + Matrix4 matrix, + Mask mask, + BaseKeyframeAnimation maskAnimation, + BaseKeyframeAnimation opacityAnimation, + ) { + canvas.saveLayer(bounds, _dstOutPaint); + canvas.drawRect(bounds, _contentPaint); + _dstOutPaint.setAlpha((opacityAnimation.value * 2.55).round()); + + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + canvas.drawPath(path, _dstOutPaint); + canvas.restore(); + } + + void _applyIntersectMask( + Canvas canvas, + Rect bounds, + Matrix4 matrix, + Mask mask, + BaseKeyframeAnimation maskAnimation, + BaseKeyframeAnimation opacityAnimation, + ) { + canvas.saveLayer(bounds, _dstInPaint); + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + _contentPaint.setAlpha((opacityAnimation.value * 2.55).round()); + canvas.drawPath(path, _contentPaint); + canvas.restore(); + } + + void _applyInvertedIntersectMask( + Canvas canvas, + Rect bounds, + Matrix4 matrix, + Mask mask, + BaseKeyframeAnimation maskAnimation, + BaseKeyframeAnimation opacityAnimation, + ) { + canvas.saveLayer(bounds, _dstInPaint); + canvas.drawRect(bounds, _contentPaint); + _dstOutPaint.setAlpha((opacityAnimation.value * 2.55).round()); + var maskPath = maskAnimation.value; + var path = maskPath.transform(matrix.storage); + canvas.drawPath(path, _dstOutPaint); + canvas.restore(); + } + + bool hasMasksOnThisLayer() { + return _mask != null && _mask!.maskAnimations.isNotEmpty; + } + + void _setVisible(bool visible) { + if (visible != _visible) { + _visible = visible; + invalidateSelf(); + } + } + + @protected + void setProgress(double progress) { + // Time stretch should not be applied to the layer transform. + transform.setProgress(progress); + if (_mask != null) { + for (var i = 0; i < _mask!.maskAnimations.length; i++) { + _mask!.maskAnimations[i].setProgress(progress); + } + } + if (_inOutAnimation != null) { + _inOutAnimation!.setProgress(progress); + } + if (_matteLayer != null) { + _matteLayer!.setProgress(progress); + } + for (var i = 0; i < _animations.length; i++) { + _animations[i].setProgress(progress); + } + } + + void _buildParentLayerListIfNeeded() { + if (_parentLayers != null) { + return; + } + if (_parentLayer == null) { + _parentLayers = []; + return; + } + + _parentLayers = []; + var layer = _parentLayer; + while (layer != null) { + _parentLayers!.add(layer); + layer = layer._parentLayer; + } + } + + @override + String get name { + return layerModel.name; + } + + BlurEffect? get blurEffect { + return layerModel.blurEffect; + } + + BlendMode? get blendMode { + return layerModel.blendMode; + } + + MaskFilter? getBlurMaskFilter(double radius) { + if (blurMaskFilterRadius == radius) { + return blurMaskFilter; + } + var sigma = radius * 0.57735 + 0.5; + blurMaskFilter = MaskFilter.blur(BlurStyle.normal, sigma); + blurMaskFilterRadius = radius; + return blurMaskFilter; + } + + DropShadowEffect? get dropShadowEffect => layerModel.dropShadowEffect; + + @override + void setContents(List contentsBefore, List contentsAfter) { + // Do nothing + } + + @override + void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + if (keyPath.keys.isEmpty) return; + var matteLayer = _matteLayer; + if (matteLayer != null) { + var matteCurrentPartialKeyPath = currentPartialKeyPath.addKey( + matteLayer.name, + ); + if (keyPath.fullyResolvesTo(matteLayer.name, depth)) { + accumulator.add(matteCurrentPartialKeyPath.resolve(matteLayer)); + } + + if (keyPath.propagateToChildren(name, depth)) { + var newDepth = depth + keyPath.incrementDepthBy(matteLayer.name, depth); + matteLayer.resolveChildKeyPath( + keyPath, + newDepth, + accumulator, + matteCurrentPartialKeyPath, + ); + } + } + + if (!keyPath.matches(name, depth)) { + return; + } + + if (name != '__container') { + currentPartialKeyPath = currentPartialKeyPath.addKey(name); + + if (keyPath.fullyResolvesTo(name, depth)) { + accumulator.add(currentPartialKeyPath.resolve(this)); + } + } + + if (keyPath.propagateToChildren(name, depth)) { + var newDepth = depth + keyPath.incrementDepthBy(name, depth); + resolveChildKeyPath( + keyPath, + newDepth, + accumulator, + currentPartialKeyPath, + ); + } + } + + void resolveChildKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) {} + + @mustCallSuper + @override + void addValueCallback(T property, LottieValueCallback? callback) { + transform.applyValueCallback(property, callback); + } +} diff --git a/lottie/lib/src/model/layer/composition_layer.dart b/lottie/lib/src/model/layer/composition_layer.dart new file mode 100644 index 0000000..5d3424a --- /dev/null +++ b/lottie/lib/src/model/layer/composition_layer.dart @@ -0,0 +1,230 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/value_callback_keyframe_animation.dart'; +import '../../composition.dart'; +import '../../l.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../utils.dart'; +import '../../value/lottie_value_callback.dart'; +import '../key_path.dart'; +import 'base_layer.dart'; +import 'layer.dart'; +import 'shape_layer.dart'; + +class CompositionLayer extends BaseLayer { + BaseKeyframeAnimation? _timeRemapping; + final List _layers = []; + final Paint _layerPaint = Paint(); + + bool? _hasMatte; + bool? _hasMasks; + + CompositionLayer( + LottieDrawable lottieDrawable, + Layer layerModel, + List layerModels, + LottieComposition composition, + ) : super(lottieDrawable, layerModel) { + var timeRemapping = layerModel.timeRemapping; + if (timeRemapping != null) { + _timeRemapping = timeRemapping.createAnimation(); + addAnimation(_timeRemapping); + _timeRemapping!.addUpdateListener(invalidateSelf); + } + + var layerMap = {}; + + BaseLayer? mattedLayer; + for (var i = layerModels.length - 1; i >= 0; i--) { + var lm = layerModels[i]; + var layer = BaseLayer.forModel(this, lm, lottieDrawable, composition); + if (layer == null) { + continue; + } + layerMap[layer.layerModel.id] = layer; + if (mattedLayer != null) { + mattedLayer.setMatteLayer(layer); + mattedLayer = null; + } else { + _layers.insert(0, layer); + switch (lm.matteType) { + case MatteType.add: + case MatteType.invert: + mattedLayer = layer; + case MatteType.luma: + case MatteType.lumaInverted: + case MatteType.none: + case MatteType.unknown: + break; + } + } + } + + for (var key in layerMap.keys) { + var layerView = layerMap[key]; + // This shouldn't happen but it appears as if sometimes on pre-lollipop devices when + // compiled with d8, layerView is null sometimes. + // https://github.com/airbnb/lottie-android/issues/524 + if (layerView == null) { + continue; + } + var parentLayer = layerMap[layerView.layerModel.parentId]; + if (parentLayer != null) { + layerView.setParentLayer(parentLayer); + } + } + } + + @override + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }) { + L.beginSection('CompositionLayer#draw'); + var newClipRect = Rect.fromLTWH( + 0, + 0, + layerModel.preCompWidth.toDouble(), + layerModel.preCompHeight.toDouble(), + ); + newClipRect = parentMatrix.mapRect(newClipRect); + + // Apply off-screen rendering only when needed in order to improve rendering performance. + var isDrawingWithOffScreen = + lottieDrawable.isApplyingOpacityToLayersEnabled && + _layers.length > 1 && + parentAlpha != 255; + if (isDrawingWithOffScreen) { + _layerPaint.setAlpha(parentAlpha); + canvas.saveLayer(newClipRect, _layerPaint); + } else { + canvas.save(); + } + + var childAlpha = isDrawingWithOffScreen ? 255 : parentAlpha; + for (var i = _layers.length - 1; i >= 0; i--) { + if (!newClipRect.isEmpty) { + canvas.clipRect(newClipRect); + } + + var layer = _layers[i]; + layer.draw(canvas, parentMatrix, parentAlpha: childAlpha); + } + canvas.restore(); + L.endSection('CompositionLayer#draw'); + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + var bounds = super.getBounds(parentMatrix, applyParents: applyParents); + for (var i = _layers.length - 1; i >= 0; i--) { + var layerBounds = _layers[i].getBounds(boundsMatrix, applyParents: true); + bounds = bounds.expandToInclude(layerBounds); + } + return bounds; + } + + @override + void setProgress(double progress) { + super.setProgress(progress); + if (_timeRemapping != null) { + // The duration has 0.01 frame offset to show end of animation properly. + // https://github.com/airbnb/lottie-android/pull/766 + // Ignore this offset for calculating time-remapping because time-remapping value is based on original duration. + var durationFrames = lottieDrawable.composition.durationFrames + 0.01; + var compositionDelayFrames = layerModel.composition.startFrame; + var remappedFrames = + _timeRemapping!.value * layerModel.composition.frameRate - + compositionDelayFrames; + progress = remappedFrames / durationFrames; + } + + if (_timeRemapping == null) { + progress -= layerModel.startProgress; + } + //Time stretch needs to be divided if is not "__container" + if (layerModel.timeStretch != 0 && layerModel.name != '__container') { + progress /= layerModel.timeStretch; + } + for (var i = _layers.length - 1; i >= 0; i--) { + _layers[i].setProgress(progress); + } + } + + bool? get hasMasks { + if (_hasMasks == null) { + for (var i = _layers.length - 1; i >= 0; i--) { + var layer = _layers[i]; + if (layer is ShapeLayer) { + if (layer.hasMasksOnThisLayer()) { + _hasMasks = true; + return true; + } + } else if (layer is CompositionLayer && layer.hasMasks!) { + _hasMasks = true; + return true; + } + } + _hasMasks = false; + } + return _hasMasks; + } + + bool get hasMatte { + if (_hasMatte == null) { + if (hasMatteOnThisLayer()) { + _hasMatte = true; + return true; + } + + for (var i = _layers.length - 1; i >= 0; i--) { + if (_layers[i].hasMatteOnThisLayer()) { + _hasMatte = true; + return true; + } + } + _hasMatte = false; + } + return _hasMatte!; + } + + @override + void resolveChildKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + for (var i = 0; i < _layers.length; i++) { + _layers[i].resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + ); + } + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + super.addValueCallback(property, callback); + + if (property == LottieProperty.timeRemap) { + if (callback == null) { + if (_timeRemapping != null) { + _timeRemapping!.setValueCallback(null); + } + } else { + _timeRemapping = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + 1, + ); + _timeRemapping!.addUpdateListener(invalidateSelf); + addAnimation(_timeRemapping); + } + } + } +} diff --git a/lottie/lib/src/model/layer/image_layer.dart b/lottie/lib/src/model/layer/image_layer.dart new file mode 100644 index 0000000..3c089cc --- /dev/null +++ b/lottie/lib/src/model/layer/image_layer.dart @@ -0,0 +1,85 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/value_callback_keyframe_animation.dart'; +import '../../lottie_property.dart'; +import '../../utils.dart'; +import '../../value/lottie_value_callback.dart'; +import 'base_layer.dart'; + +class ImageLayer extends BaseLayer { + final Paint paint = Paint(); + BaseKeyframeAnimation? _colorFilterAnimation; + + ImageLayer(super.lottieDrawable, super.layerModel); + + @override + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }) { + var bitmap = getBitmap(); + if (bitmap == null) { + return; + } + + paint.filterQuality = lottieDrawable.filterQuality ?? FilterQuality.low; + paint.setAlpha(parentAlpha); + if (_colorFilterAnimation != null) { + paint.colorFilter = _colorFilterAnimation!.value; + } + canvas.save(); + canvas.transform(parentMatrix.storage); + var src = Rect.fromLTWH( + 0, + 0, + bitmap.width.toDouble(), + bitmap.height.toDouble(), + ); + var dst = Rect.fromLTWH( + 0, + 0, + bitmap.width.toDouble(), + bitmap.height.toDouble(), + ); + canvas.drawImageRect(bitmap, src, dst, paint); + canvas.restore(); + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + var superBounds = super.getBounds(parentMatrix, applyParents: applyParents); + var bitmap = getBitmap(); + if (bitmap != null) { + var bounds = Rect.fromLTWH( + 0, + 0, + bitmap.width.toDouble(), + bitmap.height.toDouble(), + ); + return boundsMatrix.mapRect(bounds); + } + return superBounds; + } + + Image? getBitmap() { + var refId = layerModel.refId; + return lottieDrawable.getImageAsset(refId); + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + super.addValueCallback(property, callback); + if (property == LottieProperty.colorFilter) { + if (callback == null) { + _colorFilterAnimation = null; + } else { + _colorFilterAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + ); + } + } + } +} diff --git a/lottie/lib/src/model/layer/layer.dart b/lottie/lib/src/model/layer/layer.dart new file mode 100644 index 0000000..f4be7f0 --- /dev/null +++ b/lottie/lib/src/model/layer/layer.dart @@ -0,0 +1,129 @@ +import 'dart:ui'; +import '../../composition.dart'; +import '../../value/keyframe.dart'; +import '../animatable/animatable_double_value.dart'; +import '../animatable/animatable_text_frame.dart'; +import '../animatable/animatable_text_properties.dart'; +import '../animatable/animatable_transform.dart'; +import '../content/blur_effect.dart'; +import '../content/content_model.dart'; +import '../content/drop_shadow_effect.dart'; +import '../content/mask.dart'; + +enum LayerType { preComp, solid, image, nullLayer, shape, text, unknown } + +enum MatteType { none, add, invert, luma, lumaInverted, unknown } + +class Layer { + final List shapes; + final LottieComposition composition; + final String name; + final int id; + final LayerType layerType; + final int parentId; + final String? refId; + final List masks; + final AnimatableTransform transform; + final int solidWidth; + final int solidHeight; + final Color solidColor; + final double timeStretch; + final double startFrame; + final int preCompWidth; + final int preCompHeight; + final AnimatableTextFrame? text; + final AnimatableTextProperties? textProperties; + final List> inOutKeyframes; + final MatteType matteType; + final AnimatableDoubleValue? timeRemapping; + final bool isHidden; + final BlurEffect? blurEffect; + final DropShadowEffect? dropShadowEffect; + final BlendMode? blendMode; + + double get startProgress { + return startFrame / composition.durationFrames; + } + + Layer({ + required this.shapes, + required this.composition, + required this.name, + required this.id, + required this.layerType, + required this.parentId, + this.refId, + required this.masks, + required this.transform, + required this.solidWidth, + required this.solidHeight, + required this.solidColor, + required this.timeStretch, + required this.startFrame, + required this.preCompWidth, + required this.preCompHeight, + this.text, + this.textProperties, + required this.inOutKeyframes, + required this.matteType, + this.timeRemapping, + required this.isHidden, + this.blurEffect, + this.dropShadowEffect, + this.blendMode, + }); + + @override + String toString() { + return toStringWithPrefix(''); + } + + String toStringWithPrefix(String prefix) { + var sb = StringBuffer() + ..write(prefix) + ..write(name) + ..write('\n'); + var parent = composition.layerModelForId(parentId); + if (parent != null) { + sb + ..write('\t\tParents: ') + ..write(parent.name); + parent = composition.layerModelForId(parent.parentId); + while (parent != null) { + sb + ..write('->') + ..write(parent.name); + parent = composition.layerModelForId(parent.parentId); + } + sb + ..write(prefix) + ..write('\n'); + } + if (masks.isNotEmpty) { + sb + ..write(prefix) + ..write('\tMasks: ') + ..write(masks.length) + ..write('\n'); + } + if (solidWidth != 0 && solidHeight != 0) { + sb + ..write(prefix) + ..write('\tBackground: ') + ..write('${solidWidth}x$solidHeight $solidColor'); + } + if (shapes.isNotEmpty) { + sb + ..write(prefix) + ..write('\tShapes:\n'); + for (Object shape in shapes) { + sb + ..write(prefix) + ..write('\t\t') + ..write(shape) + ..write('\n'); + } + } + return sb.toString(); + } +} diff --git a/lottie/lib/src/model/layer/null_layer.dart b/lottie/lib/src/model/layer/null_layer.dart new file mode 100644 index 0000000..9b388a2 --- /dev/null +++ b/lottie/lib/src/model/layer/null_layer.dart @@ -0,0 +1,22 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import 'base_layer.dart'; + +class NullLayer extends BaseLayer { + NullLayer(super.lottieDrawable, super.layerModel); + + @override + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }) { + // Do nothing. + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + super.getBounds(parentMatrix, applyParents: applyParents); + return Rect.zero; + } +} diff --git a/lottie/lib/src/model/layer/shape_layer.dart b/lottie/lib/src/model/layer/shape_layer.dart new file mode 100644 index 0000000..fef4a4a --- /dev/null +++ b/lottie/lib/src/model/layer/shape_layer.dart @@ -0,0 +1,83 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../animation/content/content.dart'; +import '../../animation/content/content_group.dart'; +import '../../lottie_drawable.dart'; +import '../content/blur_effect.dart'; +import '../content/drop_shadow_effect.dart'; +import '../content/shape_group.dart'; +import '../key_path.dart'; +import 'base_layer.dart'; +import 'composition_layer.dart'; +import 'layer.dart'; + +class ShapeLayer extends BaseLayer { + late ContentGroup _contentGroup; + final CompositionLayer _compositionLayer; + + ShapeLayer( + LottieDrawable lottieDrawable, + Layer layerModel, + this._compositionLayer, + ) : super(lottieDrawable, layerModel) { + // Naming this __container allows it to be ignored in KeyPath matching. + var shapeGroup = ShapeGroup( + '__container', + layerModel.shapes, + hidden: false, + ); + _contentGroup = ContentGroup(lottieDrawable, this, shapeGroup) + ..setContents([], []); + } + + @override + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }) { + _contentGroup.draw(canvas, parentMatrix, parentAlpha: parentAlpha); + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + var bounds = super.getBounds(parentMatrix, applyParents: applyParents); + bounds = bounds.expandToInclude( + _contentGroup.getBounds(boundsMatrix, applyParents: applyParents), + ); + return bounds; + } + + @override + BlurEffect? get blurEffect { + var layerBlur = super.blurEffect; + if (layerBlur != null) { + return layerBlur; + } + return _compositionLayer.blurEffect; + } + + @override + DropShadowEffect? get dropShadowEffect { + var layerDropShadow = super.dropShadowEffect; + if (layerDropShadow != null) { + return layerDropShadow; + } + return _compositionLayer.dropShadowEffect; + } + + @override + void resolveChildKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + ) { + _contentGroup.resolveKeyPath( + keyPath, + depth, + accumulator, + currentPartialKeyPath, + ); + } +} diff --git a/lottie/lib/src/model/layer/solid_layer.dart b/lottie/lib/src/model/layer/solid_layer.dart new file mode 100644 index 0000000..1b8b733 --- /dev/null +++ b/lottie/lib/src/model/layer/solid_layer.dart @@ -0,0 +1,101 @@ +import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/value_callback_keyframe_animation.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../utils.dart'; +import '../../value/lottie_value_callback.dart'; +import 'base_layer.dart'; +import 'layer.dart'; + +class SolidLayer extends BaseLayer { + final Paint paint = Paint()..style = PaintingStyle.fill; + final Path path = Path(); + BaseKeyframeAnimation? _colorFilterAnimation; + BaseKeyframeAnimation? _colorAnimation; + + SolidLayer(LottieDrawable lottieDrawable, Layer layerModel) + : super(lottieDrawable, layerModel) { + paint.color = layerModel.solidColor.withAlpha(0); + } + + @override + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }) { + var backgroundAlpha = layerModel.solidColor.a; + if (backgroundAlpha == 0) { + return; + } + + paint.color = _colorAnimation?.value ?? layerModel.solidColor; + + var opacity = transform.opacity?.value ?? 100; + var alpha = + (parentAlpha / 255.0 * (backgroundAlpha * opacity / 100.0) * 255.0) + .round(); + paint.setAlpha(alpha); + + if (_colorFilterAnimation != null) { + paint.colorFilter = _colorFilterAnimation!.value; + } + if (alpha > 0) { + var points = List.filled(8, 0.0); + points[2] = points[4] = layerModel.solidWidth.toDouble(); + points[5] = points[7] = layerModel.solidHeight.toDouble(); + + // We can't map rect here because if there is rotation on the transform then we aren't + // actually drawing a rect. + parentMatrix.mapPoints(points); + path.reset(); + path.moveTo(points[0], points[1]); + path.lineTo(points[2], points[3]); + path.lineTo(points[4], points[5]); + path.lineTo(points[6], points[7]); + path.lineTo(points[0], points[1]); + path.close(); + canvas.drawPath(path, paint); + } + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + super.getBounds(parentMatrix, applyParents: applyParents); + var rect = Rect.fromLTWH( + 0, + 0, + layerModel.solidWidth.toDouble(), + layerModel.solidHeight.toDouble(), + ); + rect = boundsMatrix.mapRect(rect); + return rect; + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + super.addValueCallback(property, callback); + if (property == LottieProperty.colorFilter) { + if (callback == null) { + _colorFilterAnimation = null; + } else { + _colorFilterAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + ); + } + } else if (property == LottieProperty.color) { + if (callback == null) { + _colorAnimation = null; + paint.color = layerModel.solidColor; + } else { + _colorAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + null, + ); + } + } + } +} diff --git a/lottie/lib/src/model/layer/text_layer.dart b/lottie/lib/src/model/layer/text_layer.dart new file mode 100644 index 0000000..87558d3 --- /dev/null +++ b/lottie/lib/src/model/layer/text_layer.dart @@ -0,0 +1,638 @@ +import 'package:flutter/widgets.dart'; +import '../../animation/content/content_group.dart'; +import '../../animation/keyframe/base_keyframe_animation.dart'; +import '../../animation/keyframe/text_keyframe_animation.dart'; +import '../../animation/keyframe/value_callback_keyframe_animation.dart'; +import '../../composition.dart'; +import '../../lottie_drawable.dart'; +import '../../lottie_property.dart'; +import '../../utils.dart'; +import '../../utils/characters.dart'; +import '../../value/lottie_value_callback.dart'; +import '../document_data.dart'; +import '../font.dart'; +import '../font_character.dart'; +import 'base_layer.dart'; +import 'layer.dart'; + +class TextLayer extends BaseLayer { + // TODO(xha): take from context. + final TextDirection _textDirection = TextDirection.ltr; + final _matrix = Matrix4.identity(); + final _fillPaint = Paint()..style = PaintingStyle.fill; + final _strokePaint = Paint()..style = PaintingStyle.stroke; + final _contentsForCharacter = >{}; + + /// If this is paragraph text, one line may wrap depending on the size of the document data box. + final _textSubLines = <_TextSubLine>[]; + final TextKeyframeAnimation _textAnimation; + final LottieComposition _composition; + + BaseKeyframeAnimation? _colorAnimation; + + BaseKeyframeAnimation? _colorCallbackAnimation; + + BaseKeyframeAnimation? _strokeColorAnimation; + + BaseKeyframeAnimation? _strokeColorCallbackAnimation; + + BaseKeyframeAnimation? _strokeWidthAnimation; + + BaseKeyframeAnimation? _strokeWidthCallbackAnimation; + + BaseKeyframeAnimation? _trackingAnimation; + + BaseKeyframeAnimation? _trackingCallbackAnimation; + + BaseKeyframeAnimation? _textSizeAnimation; + + BaseKeyframeAnimation? _textSizeCallbackAnimation; + + TextLayer(LottieDrawable lottieDrawable, Layer layerModel) + : _composition = layerModel.composition, + _textAnimation = layerModel.text!.createAnimation(), + super(lottieDrawable, layerModel) { + _textAnimation.addUpdateListener(invalidateSelf); + addAnimation(_textAnimation); + + var textProperties = layerModel.textProperties; + if (textProperties != null && textProperties.color != null) { + _colorAnimation = textProperties.color!.createAnimation() + ..addUpdateListener(invalidateSelf); + addAnimation(_colorAnimation); + } + + if (textProperties != null && textProperties.stroke != null) { + _strokeColorAnimation = textProperties.stroke!.createAnimation() + ..addUpdateListener(invalidateSelf); + addAnimation(_strokeColorAnimation); + } + + if (textProperties != null && textProperties.strokeWidth != null) { + _strokeWidthAnimation = textProperties.strokeWidth!.createAnimation() + ..addUpdateListener(invalidateSelf); + addAnimation(_strokeWidthAnimation); + } + + if (textProperties != null && textProperties.tracking != null) { + _trackingAnimation = textProperties.tracking!.createAnimation() + ..addUpdateListener(invalidateSelf); + addAnimation(_trackingAnimation); + } + } + + @override + Rect getBounds(Matrix4 parentMatrix, {required bool applyParents}) { + super.getBounds(parentMatrix, applyParents: applyParents); + // TODO: use the correct text bounds. + return Rect.fromLTWH( + 0, + 0, + _composition.bounds.width.toDouble(), + _composition.bounds.height.toDouble(), + ); + } + + @override + void drawLayer( + Canvas canvas, + Matrix4 parentMatrix, { + required int parentAlpha, + }) { + var documentData = _textAnimation.value; + var font = _composition.fonts[documentData.fontName]; + if (font == null) { + return; + } + canvas.save(); + canvas.transform(parentMatrix.storage); + + _configurePaint(documentData, parentAlpha); + + if (lottieDrawable.useTextGlyphs) { + _drawTextWithGlyphs(documentData, parentMatrix, font, canvas); + } else { + _drawTextWithFont(documentData, font, canvas); + } + + canvas.restore(); + } + + void _configurePaint(DocumentData documentData, int parentAlpha) { + Color fillPaintColor; + if (_colorCallbackAnimation != null) { + fillPaintColor = _colorCallbackAnimation!.value; + } else if (_colorAnimation != null) { + fillPaintColor = _colorAnimation!.value; + } else { + fillPaintColor = documentData.color; + } + _fillPaint.color = fillPaintColor.withValues(alpha: _fillPaint.color.a); + + Color strokePaintColor; + if (_strokeColorCallbackAnimation != null) { + strokePaintColor = _strokeColorCallbackAnimation!.value; + } else if (_strokeColorAnimation != null) { + strokePaintColor = _strokeColorAnimation!.value; + } else { + strokePaintColor = documentData.strokeColor; + } + _strokePaint.color = strokePaintColor.withValues( + alpha: _strokePaint.color.a, + ); + + var opacity = transform.opacity?.value ?? 100; + var alpha = opacity * 255 / 100 * parentAlpha ~/ 255; + _fillPaint.setAlpha(alpha); + _strokePaint.setAlpha(alpha); + + if (_strokeWidthCallbackAnimation != null) { + _strokePaint.strokeWidth = _strokeWidthCallbackAnimation!.value; + } else if (_strokeWidthAnimation != null) { + _strokePaint.strokeWidth = _strokeWidthAnimation!.value; + } else { + _strokePaint.strokeWidth = documentData.strokeWidth; + } + } + + void _drawTextWithGlyphs( + DocumentData documentData, + Matrix4 parentMatrix, + Font font, + Canvas canvas, + ) { + double textSize; + if (_textSizeCallbackAnimation != null) { + textSize = _textSizeCallbackAnimation!.value; + } else if (_textSizeAnimation != null) { + textSize = _textSizeAnimation!.value; + } else { + textSize = documentData.size; + } + var fontScale = textSize / 100.0; + var parentScale = parentMatrix.getScale(); + + var text = documentData.text; + + // Split full text in multiple lines + var textLines = _getTextLines(text); + var textLineCount = textLines.length; + // Add tracking + var tracking = documentData.tracking / 10; + if (_trackingCallbackAnimation != null) { + tracking += _trackingCallbackAnimation!.value; + } else if (_trackingAnimation != null) { + tracking += _trackingAnimation!.value; + } + var lineIndex = -1; + for (var i = 0; i < textLineCount; i++) { + var textLine = textLines[i]; + var boxWidth = documentData.boxSize?.dx ?? 0.0; + var lines = _splitGlyphTextIntoLines( + textLine, + boxWidth, + font, + fontScale, + tracking, + null, + ); + for (var j = 0; j < lines.length; j++) { + var line = lines[j]; + lineIndex++; + + canvas.save(); + + _offsetCanvas(canvas, documentData, lineIndex, line.width); + _drawGlyphTextLine( + line.text, + documentData, + font, + canvas, + parentScale, + fontScale, + tracking, + ); + + canvas.restore(); + } + } + } + + void _drawGlyphTextLine( + Characters text, + DocumentData documentData, + Font font, + Canvas canvas, + double parentScale, + double fontScale, + double tracking, + ) { + for (var c in text) { + var characterHash = FontCharacter.hashFor(c, font.family, font.style); + var character = _composition.characters[characterHash]; + if (character == null) { + // Something is wrong. Potentially, they didn't export the text as a glyph. + continue; + } + _drawCharacterAsGlyph(character, fontScale, documentData, canvas); + var tx = character.width * fontScale + tracking; + canvas.translate(tx, 0); + } + } + + void _drawTextWithFont(DocumentData documentData, Font font, Canvas canvas) { + var textStyle = lottieDrawable.getTextStyle(font.family, font.style); + var text = documentData.text; + var textDelegate = lottieDrawable.delegates?.text; + if (textDelegate != null) { + text = textDelegate(text); + } + double textSize; + if (_textSizeCallbackAnimation != null) { + textSize = _textSizeCallbackAnimation!.value; + } else if (_textSizeAnimation != null) { + textSize = _textSizeAnimation!.value; + } else { + textSize = documentData.size; + } + textStyle = textStyle.copyWith(fontSize: textSize); + + // Calculate tracking + var tracking = documentData.tracking / 10; + if (_trackingCallbackAnimation != null) { + tracking += _trackingCallbackAnimation!.value; + } else if (_trackingAnimation != null) { + tracking += _trackingAnimation!.value; + } + tracking = tracking * textSize / 100.0; + + // Split full text in multiple lines + var textLines = _getTextLines(text); + var textLineCount = textLines.length; + var lineIndex = -1; + for (var i = 0; i < textLineCount; i++) { + var textLine = textLines[i]; + var boxWidth = documentData.boxSize?.dx ?? 0.0; + var lines = _splitGlyphTextIntoLines( + textLine, + boxWidth, + font, + 0.0, + tracking, + textStyle, + ); + for (var j = 0; j < lines.length; j++) { + var line = lines[j]; + lineIndex++; + + canvas.save(); + + _offsetCanvas(canvas, documentData, lineIndex, line.width); + _drawFontTextLine(line.text, textStyle, documentData, canvas, tracking); + + canvas.restore(); + } + } + } + + void _offsetCanvas( + Canvas canvas, + DocumentData documentData, + int lineIndex, + double lineWidth, + ) { + var position = documentData.boxPosition; + var size = documentData.boxSize; + var lineStartY = position == null + ? 0 + : documentData.lineHeight + position.dy; + var lineOffset = lineIndex * documentData.lineHeight + lineStartY; + var lineStart = position?.dx ?? 0.0; + var boxWidth = size?.dx ?? 0.0; + switch (documentData.justification) { + case Justification.leftAlign: + canvas.translate(lineStart, lineOffset); + case Justification.rightAlign: + canvas.translate(lineStart + boxWidth - lineWidth, lineOffset); + case Justification.center: + canvas.translate( + lineStart + boxWidth / 2.0 - lineWidth / 2.0, + lineOffset, + ); + } + } + + List _getTextLines(String text) { + // Split full text by carriage return character + var formattedText = text + .replaceAll('\r\n', '\r') + .replaceAll('\u0003', '\r') + .replaceAll('\n', '\r'); + var textLinesArray = formattedText.split('\r'); + return textLinesArray.map((l) => l.characters).toList(); + } + + void _drawFontTextLine( + Characters text, + TextStyle textStyle, + DocumentData documentData, + Canvas canvas, + double tracking, + ) { + for (var char in text) { + var charString = char; + _drawCharacterFromFont(charString, textStyle, documentData, canvas); + var textPainter = TextPainter( + text: TextSpan(text: charString, style: textStyle), + textDirection: _textDirection, + ); + textPainter.layout(); + var charWidth = textPainter.width; + var tx = charWidth + tracking; + canvas.translate(tx, 0); + } + } + + List<_TextSubLine> _splitGlyphTextIntoLines( + Characters textLine, + double boxWidth, + Font font, + double fontScale, + double tracking, + TextStyle? textStyle, + ) { + var usingGlyphs = textStyle == null; + var lineCount = 0; + + var currentLineWidth = 0.0; + var currentLineStartIndex = 0; + + var currentWordStartIndex = 0; + var currentWordWidth = 0.0; + var nextCharacterStartsWord = false; + + // The measured size of a space. + var spaceWidth = 0.0; + + var textPainter = TextPainter( + text: TextSpan(text: '', style: textStyle), + textDirection: _textDirection, + ); + var i = 0; + for (var c in textLine) { + double currentCharWidth; + if (usingGlyphs) { + var characterHash = FontCharacter.hashFor(c, font.family, font.style); + var character = _composition.characters[characterHash]; + if (character == null) { + continue; + } + currentCharWidth = character.width * fontScale + tracking; + } else { + textPainter.text = TextSpan(text: c, style: textStyle); + textPainter.layout(); + currentCharWidth = textPainter.width + tracking; + } + + if (c == ' ') { + spaceWidth = currentCharWidth; + nextCharacterStartsWord = true; + } else if (nextCharacterStartsWord) { + nextCharacterStartsWord = false; + currentWordStartIndex = i; + currentWordWidth = currentCharWidth; + } else { + currentWordWidth += currentCharWidth; + } + currentLineWidth += currentCharWidth; + + if (boxWidth > 0 && currentLineWidth >= boxWidth) { + if (c == ' ') { + // Spaces at the end of a line don't do anything. Ignore it. + // The next non-space character will hit the conditions below. + continue; + } + var subLine = _ensureEnoughSubLines(++lineCount); + if (currentWordStartIndex == currentLineStartIndex) { + // Only word on line is wider than box, start wrapping mid-word. + var substr = textLine.getRange(currentLineStartIndex, i); + var trimmed = substr.trim(' '.characters); + var trimmedSpace = (trimmed.length - substr.length) * spaceWidth; + subLine.set( + trimmed, + currentLineWidth - currentCharWidth - trimmedSpace, + ); + currentLineStartIndex = i; + currentLineWidth = currentCharWidth; + currentWordStartIndex = currentLineStartIndex; + currentWordWidth = currentCharWidth; + } else { + var substr = textLine.getRange( + currentLineStartIndex, + currentWordStartIndex - 1, + ); + var trimmed = substr.trim(' '.characters); + var trimmedSpace = (substr.length - trimmed.length) * spaceWidth; + subLine.set( + trimmed, + currentLineWidth - currentWordWidth - trimmedSpace - spaceWidth, + ); + currentLineStartIndex = currentWordStartIndex; + currentLineWidth = currentWordWidth; + } + } + ++i; + } + if (currentLineWidth > 0) { + var line = _ensureEnoughSubLines(++lineCount); + line.set(textLine.getRange(currentLineStartIndex), currentLineWidth); + } + return _textSubLines.sublist(0, lineCount); + } + + /// Elements are reused and not deleted to save allocations. + _TextSubLine _ensureEnoughSubLines(int numLines) { + for (var i = _textSubLines.length; i < numLines; i++) { + _textSubLines.add(_TextSubLine()); + } + return _textSubLines[numLines - 1]; + } + + void _drawCharacterAsGlyph( + FontCharacter character, + double fontScale, + DocumentData documentData, + Canvas canvas, + ) { + var contentGroups = _getContentsForCharacter(character); + for (var j = 0; j < contentGroups.length; j++) { + var path = contentGroups[j].getPath(); + _matrix.reset(); + _matrix.translateByDouble(0.0, -documentData.baselineShift, 0, 1); + _matrix.scaleByDouble(fontScale, fontScale, fontScale, 1); + path = path.transform(_matrix.storage); + if (documentData.strokeOverFill) { + _drawGlyph(path, _fillPaint, canvas); + _drawGlyph(path, _strokePaint, canvas); + } else { + _drawGlyph(path, _strokePaint, canvas); + _drawGlyph(path, _fillPaint, canvas); + } + } + } + + void _drawGlyph(Path path, Paint paint, Canvas canvas) { + if (paint.color.a == 0) { + return; + } + if (paint.style == PaintingStyle.stroke && paint.strokeWidth == 0) { + return; + } + canvas.drawPath(path, paint); + } + + void _drawCharacterFromFont( + String character, + TextStyle textStyle, + DocumentData documentData, + Canvas canvas, + ) { + if (documentData.strokeOverFill) { + _drawCharacter(character, textStyle, _fillPaint, canvas); + _drawCharacter(character, textStyle, _strokePaint, canvas); + } else { + _drawCharacter(character, textStyle, _strokePaint, canvas); + _drawCharacter(character, textStyle, _fillPaint, canvas); + } + } + + void _drawCharacter( + String character, + TextStyle textStyle, + Paint paint, + Canvas canvas, + ) { + if (paint.color.a == 0) { + return; + } + if (paint.style == PaintingStyle.stroke && paint.strokeWidth == 0) { + return; + } + + textStyle = textStyle.copyWith(foreground: paint); + + var painter = TextPainter( + text: TextSpan(text: character, style: textStyle), + textDirection: _textDirection, + ); + painter.layout(); + painter.paint(canvas, Offset(0, -textStyle.fontSize!)); + } + + List _getContentsForCharacter(FontCharacter character) { + if (_contentsForCharacter.containsKey(character)) { + return _contentsForCharacter[character]!; + } + var shapes = character.shapes; + var size = shapes.length; + var contents = []; + for (var i = 0; i < size; i++) { + var sg = shapes[i]; + contents.add(ContentGroup(lottieDrawable, this, sg)); + } + _contentsForCharacter[character] = contents; + return contents; + } + + @override + void addValueCallback(T property, LottieValueCallback? callback) { + super.addValueCallback(property, callback); + if (property == LottieProperty.color) { + if (_colorCallbackAnimation != null) { + removeAnimation(_colorCallbackAnimation); + } + + if (callback == null) { + _colorCallbackAnimation = null; + } else { + _colorCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + const Color(0x00000000), + )..addUpdateListener(invalidateSelf); + addAnimation(_colorCallbackAnimation); + } + } else if (property == LottieProperty.strokeColor) { + if (_strokeColorCallbackAnimation != null) { + removeAnimation(_strokeColorCallbackAnimation); + } + + if (callback == null) { + _strokeColorCallbackAnimation = null; + } else { + _strokeColorCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + const Color(0x00000000), + )..addUpdateListener(invalidateSelf); + addAnimation(_strokeColorCallbackAnimation); + } + } else if (property == LottieProperty.strokeWidth) { + if (_strokeWidthCallbackAnimation != null) { + removeAnimation(_strokeWidthCallbackAnimation); + } + + if (callback == null) { + _strokeWidthCallbackAnimation = null; + } else { + _strokeWidthCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + 0, + )..addUpdateListener(invalidateSelf); + addAnimation(_strokeWidthCallbackAnimation); + } + } else if (property == LottieProperty.textTracking) { + if (_trackingCallbackAnimation != null) { + removeAnimation(_trackingCallbackAnimation); + } + + if (callback == null) { + _trackingCallbackAnimation = null; + } else { + _trackingCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + 0, + )..addUpdateListener(invalidateSelf); + addAnimation(_trackingCallbackAnimation); + } + } else if (property == LottieProperty.textSize) { + if (_textSizeCallbackAnimation != null) { + removeAnimation(_textSizeCallbackAnimation); + } + + if (callback == null) { + _textSizeCallbackAnimation = null; + } else { + _textSizeCallbackAnimation = ValueCallbackKeyframeAnimation( + callback as LottieValueCallback, + 10, + )..addUpdateListener(invalidateSelf); + addAnimation(_textSizeCallbackAnimation); + } + } else if (property == LottieProperty.text) { + if (callback != null) { + _textAnimation.setStringValueCallback( + callback as LottieValueCallback, + ); + } + } + } +} + +class _TextSubLine { + Characters text = Characters.empty; + double width = 0.0; + + void set(Characters text, double width) { + this.text = text; + this.width = width; + } +} diff --git a/lottie/lib/src/model/marker.dart b/lottie/lib/src/model/marker.dart new file mode 100644 index 0000000..63e11d5 --- /dev/null +++ b/lottie/lib/src/model/marker.dart @@ -0,0 +1,26 @@ +import '../../lottie.dart'; + +class Marker { + final LottieComposition _composition; + final String name; + final double startFrame; + final double durationFrames; + + Marker( + this._composition, + this.name, { + required this.startFrame, + required this.durationFrames, + }); + + bool matchesName(String name) { + return this.name.trim().toLowerCase() == name.toLowerCase(); + } + + double get start => + (startFrame - _composition.startFrame) / _composition.durationFrames; + + double get end => + (startFrame + durationFrames - _composition.startFrame) / + _composition.durationFrames; +} diff --git a/lottie/lib/src/options.dart b/lottie/lib/src/options.dart new file mode 100644 index 0000000..6e52c3d --- /dev/null +++ b/lottie/lib/src/options.dart @@ -0,0 +1,21 @@ +class LottieOptions { + /// Enable merge path support. + /// + /// Merge paths currently don't work if the the operand shape is entirely contained within the + /// first shape. If you need to cut out one shape from another shape, use an even-odd fill type + /// instead of using merge paths. + final bool enableMergePaths; + + /// Enable layer-level opacity. + /// + /// Add the ability to render opacity on the layer level rather than the shape level. + /// Opacity is normally applied directly to a shape. In cases where translucent shapes overlap, + /// applying opacity to a layer will be more accurate at the expense of performance. + /// Details: https://github.com/airbnb/lottie-android/issues/902 + final bool enableApplyingOpacityToLayers; + + LottieOptions({ + this.enableMergePaths = false, + this.enableApplyingOpacityToLayers = false, + }); +} diff --git a/lottie/lib/src/parser/animatable_path_value_parser.dart b/lottie/lib/src/parser/animatable_path_value_parser.dart new file mode 100644 index 0000000..10b8db0 --- /dev/null +++ b/lottie/lib/src/parser/animatable_path_value_parser.dart @@ -0,0 +1,85 @@ +import 'dart:ui'; +import '../composition.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_path_value.dart'; +import '../model/animatable/animatable_split_dimension_path_value.dart'; +import '../model/animatable/animatable_value.dart'; +import '../value/keyframe.dart'; +import 'animatable_value_parser.dart'; +import 'json_utils.dart'; +import 'keyframes_parser.dart'; +import 'moshi/json_reader.dart'; +import 'path_keyframe_parser.dart'; + +class AnimatablePathValueParser { + static final _names = JsonReaderOptions.of(['k', 'x', 'y']); + + AnimatablePathValueParser._(); + + static AnimatablePathValue parse( + JsonReader reader, + LottieComposition composition, + ) { + var keyframes = >[]; + if (reader.peek() == Token.beginArray) { + reader.beginArray(); + while (reader.hasNext()) { + keyframes.add(PathKeyframeParser.parse(reader, composition)); + } + reader.endArray(); + KeyframesParser.setEndFrames(keyframes); + } else { + keyframes.add( + Keyframe.nonAnimated(JsonUtils.jsonToPoint(reader)), + ); + } + return AnimatablePathValue.fromKeyframes(keyframes); + } + + /// Returns either an {@link AnimatablePathValue} or an {@link AnimatableSplitDimensionPathValue}. + static AnimatableValue parseSplitPath( + JsonReader reader, + LottieComposition composition, + ) { + AnimatablePathValue? pathAnimation; + AnimatableDoubleValue? xAnimation; + AnimatableDoubleValue? yAnimation; + + var hasExpressions = false; + + reader.beginObject(); + while (reader.peek() != Token.endObject) { + switch (reader.selectName(_names)) { + case 0: + pathAnimation = AnimatablePathValueParser.parse(reader, composition); + case 1: + if (reader.peek() == Token.string) { + hasExpressions = true; + reader.skipValue(); + } else { + xAnimation = AnimatableValueParser.parseFloat(reader, composition); + } + case 2: + if (reader.peek() == Token.string) { + hasExpressions = true; + reader.skipValue(); + } else { + yAnimation = AnimatableValueParser.parseFloat(reader, composition); + } + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + if (hasExpressions) { + composition.addWarning("Lottie doesn't support expressions."); + } + + if (pathAnimation != null) { + return pathAnimation; + } + return AnimatableSplitDimensionPathValue(xAnimation!, yAnimation!); + } +} diff --git a/lottie/lib/src/parser/animatable_text_properties_parser.dart b/lottie/lib/src/parser/animatable_text_properties_parser.dart new file mode 100644 index 0000000..781977a --- /dev/null +++ b/lottie/lib/src/parser/animatable_text_properties_parser.dart @@ -0,0 +1,73 @@ +import '../composition.dart'; +import '../model/animatable/animatable_color_value.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_text_properties.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class AnimatableTextPropertiesParser { + static final JsonReaderOptions _propertiesNames = JsonReaderOptions.of(['a']); + static final JsonReaderOptions _animatablePropertiesNames = + JsonReaderOptions.of(['fc', 'sc', 'sw', 't']); + + AnimatableTextPropertiesParser(); + + static AnimatableTextProperties parse( + JsonReader reader, + LottieComposition composition, + ) { + AnimatableTextProperties? anim; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_propertiesNames)) { + case 0: + anim = _parseAnimatableTextProperties(reader, composition); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + if (anim == null) { + // Not sure if this is possible. + return AnimatableTextProperties(); + } + return anim; + } + + static AnimatableTextProperties _parseAnimatableTextProperties( + JsonReader reader, + LottieComposition composition, + ) { + AnimatableColorValue? color; + AnimatableColorValue? stroke; + AnimatableDoubleValue? strokeWidth; + AnimatableDoubleValue? tracking; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_animatablePropertiesNames)) { + case 0: + color = AnimatableValueParser.parseColor(reader, composition); + case 1: + stroke = AnimatableValueParser.parseColor(reader, composition); + case 2: + strokeWidth = AnimatableValueParser.parseFloat(reader, composition); + case 3: + tracking = AnimatableValueParser.parseFloat(reader, composition); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + return AnimatableTextProperties( + color: color, + stroke: stroke, + strokeWidth: strokeWidth, + tracking: tracking, + ); + } +} diff --git a/lottie/lib/src/parser/animatable_transform_parser.dart b/lottie/lib/src/parser/animatable_transform_parser.dart new file mode 100644 index 0000000..07908dd --- /dev/null +++ b/lottie/lib/src/parser/animatable_transform_parser.dart @@ -0,0 +1,192 @@ +import 'dart:ui'; +import '../composition.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/animatable/animatable_path_value.dart'; +import '../model/animatable/animatable_scale_value.dart'; +import '../model/animatable/animatable_split_dimension_path_value.dart'; +import '../model/animatable/animatable_transform.dart'; +import '../model/animatable/animatable_value.dart'; +import '../value/keyframe.dart'; +import 'animatable_path_value_parser.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class AnimatableTransformParser { + AnimatableTransformParser._(); + + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'a', + 'p', + 's', + 'rz', + 'r', + 'o', + 'so', + 'eo', + 'sk', + 'sa', + ]); + static final JsonReaderOptions _animatableNames = JsonReaderOptions.of(['k']); + + static AnimatableTransform parse( + JsonReader reader, + LottieComposition composition, + ) { + AnimatablePathValue? anchorPoint; + AnimatableValue? position; + AnimatableScaleValue? scale; + AnimatableDoubleValue? rotation; + AnimatableIntegerValue? opacity; + AnimatableDoubleValue? startOpacity; + AnimatableDoubleValue? endOpacity; + AnimatableDoubleValue? skew; + AnimatableDoubleValue? skewAngle; + + var isObject = reader.peek() == Token.beginObject; + if (isObject) { + reader.beginObject(); + } + while (reader.hasNext()) { + var name = reader.selectName(_names); + switch (name) { + case 0: + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_animatableNames)) { + case 0: + anchorPoint = AnimatablePathValueParser.parse( + reader, + composition, + ); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + case 1: + position = AnimatablePathValueParser.parseSplitPath( + reader, + composition, + ); + case 2: + scale = AnimatableValueParser.parseScale(reader, composition); + case 3: + case 4: + if (name == 3) { + composition.addWarning("Lottie doesn't support 3D layers."); + } + + // Sometimes split path rotation gets exported like: + // "rz": { + // "a": 1, + // "k": [ + // {} + // ] + // }, + // which doesn't parse to a real keyframe. + rotation = AnimatableValueParser.parseFloat(reader, composition); + if (rotation.keyframes.isEmpty) { + rotation.keyframes.add( + Keyframe( + composition, + startValue: 0.0, + endValue: 0.0, + startFrame: 0.0, + endFrame: composition.endFrame, + ), + ); + } else if (rotation.keyframes.first.startValue == null) { + rotation.keyframes.first = Keyframe( + composition, + startValue: 0.0, + endValue: 0.0, + startFrame: 0.0, + endFrame: composition.endFrame, + ); + } + case 5: + opacity = AnimatableValueParser.parseInteger(reader, composition); + case 6: + startOpacity = AnimatableValueParser.parseFloat(reader, composition); + case 7: + endOpacity = AnimatableValueParser.parseFloat(reader, composition); + case 8: + skew = AnimatableValueParser.parseFloat(reader, composition); + case 9: + skewAngle = AnimatableValueParser.parseFloat(reader, composition); + default: + reader.skipName(); + reader.skipValue(); + } + } + if (isObject) { + reader.endObject(); + } + + if (isAnchorPointIdentity(anchorPoint)) { + anchorPoint = null; + } + if (isPositionIdentity(position)) { + position = null; + } + if (isRotationIdentity(rotation)) { + rotation = null; + } + if (isScaleIdentity(scale)) { + scale = null; + } + if (isSkewIdentity(skew)) { + skew = null; + } + if (isSkewAngleIdentity(skewAngle)) { + skewAngle = null; + } + return AnimatableTransform( + anchorPoint: anchorPoint, + position: position, + scale: scale, + rotation: rotation, + opacity: opacity, + startOpacity: startOpacity, + endOpacity: endOpacity, + skew: skew, + skewAngle: skewAngle, + ); + } + + static bool isAnchorPointIdentity(AnimatablePathValue? anchorPoint) { + return anchorPoint == null || + (anchorPoint.isStatic && + anchorPoint.keyframes.first.startValue == Offset.zero); + } + + static bool isPositionIdentity(AnimatableValue? position) { + return position == null || + (position is! AnimatableSplitDimensionPathValue && + position.isStatic && + position.keyframes.first.startValue == Offset.zero); + } + + static bool isRotationIdentity(AnimatableDoubleValue? rotation) { + return rotation == null || + (rotation.isStatic && rotation.keyframes.first.startValue == 0.0); + } + + static bool isScaleIdentity(AnimatableScaleValue? scale) { + return scale == null || + (scale.isStatic && + scale.keyframes.first.startValue == const Offset(1.0, 1.0)); + } + + static bool isSkewIdentity(AnimatableDoubleValue? skew) { + return skew == null || + (skew.isStatic && skew.keyframes.first.startValue == 0.0); + } + + static bool isSkewAngleIdentity(AnimatableDoubleValue? skewAngle) { + return skewAngle == null || + (skewAngle.isStatic && skewAngle.keyframes.first.startValue == 0.0); + } +} diff --git a/lottie/lib/src/parser/animatable_value_parser.dart b/lottie/lib/src/parser/animatable_value_parser.dart new file mode 100644 index 0000000..17471df --- /dev/null +++ b/lottie/lib/src/parser/animatable_value_parser.dart @@ -0,0 +1,111 @@ +import '../composition.dart'; +import '../model/animatable/animatable_color_value.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_gradient_color_value.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/animatable/animatable_point_value.dart'; +import '../model/animatable/animatable_scale_value.dart'; +import '../model/animatable/animatable_shape_value.dart'; +import '../model/animatable/animatable_text_frame.dart'; +import '../value/keyframe.dart'; +import 'color_parser.dart'; +import 'document_data_parser.dart'; +import 'float_parser.dart'; +import 'gradient_color_parser.dart'; +import 'integer_parser.dart'; +import 'keyframes_parser.dart'; +import 'moshi/json_reader.dart'; +import 'offset_parser.dart'; +import 'scale_xy_parser.dart'; +import 'shape_data_parser.dart'; +import 'value_parser.dart'; + +class AnimatableValueParser { + AnimatableValueParser._(); + + static AnimatableDoubleValue parseFloat( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatableDoubleValue.fromKeyframes( + parse(reader, composition, floatParser), + ); + } + + static AnimatableIntegerValue parseInteger( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatableIntegerValue.fromKeyframes( + parse(reader, composition, integerParser), + ); + } + + static AnimatablePointValue parsePoint( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatablePointValue.fromKeyframes( + KeyframesParser.parse( + reader, + composition, + offsetParser, + multiDimensional: true, + ), + ); + } + + static AnimatableScaleValue parseScale( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatableScaleValue.fromKeyframes( + parse(reader, composition, scaleXYParser), + ); + } + + static AnimatableShapeValue parseShapeData( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatableShapeValue.fromKeyframes( + parse(reader, composition, shapeDataParser), + ); + } + + static AnimatableTextFrame parseDocumentData( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatableTextFrame.fromKeyframes( + parse(reader, composition, documentDataParser), + ); + } + + static AnimatableColorValue parseColor( + JsonReader reader, + LottieComposition composition, + ) { + return AnimatableColorValue.fromKeyframes( + parse(reader, composition, colorParser), + ); + } + + static AnimatableGradientColorValue parseGradientColor( + JsonReader reader, + LottieComposition composition, + int points, + ) { + return AnimatableGradientColorValue.fromKeyframes( + parse(reader, composition, GradientColorParser(points).parse), + ); + } + + static List> parse( + JsonReader reader, + LottieComposition composition, + ValueParser valueParser, + ) { + return KeyframesParser.parse(reader, composition, valueParser); + } +} diff --git a/lottie/lib/src/parser/blur_effect_parser.dart b/lottie/lib/src/parser/blur_effect_parser.dart new file mode 100644 index 0000000..c3d466e --- /dev/null +++ b/lottie/lib/src/parser/blur_effect_parser.dart @@ -0,0 +1,63 @@ +import '../composition.dart'; +import '../model/content/blur_effect.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class BlurEffectParser { + static final JsonReaderOptions _blurEffectNames = JsonReaderOptions.of([ + 'ef', + ]); + static final JsonReaderOptions _innerBlurEffectNames = JsonReaderOptions.of([ + 'ty', + 'v', + ]); + + static BlurEffect? parse(JsonReader reader, LottieComposition composition) { + BlurEffect? blurEffect; + while (reader.hasNext()) { + switch (reader.selectName(_blurEffectNames)) { + case 0: + reader.beginArray(); + while (reader.hasNext()) { + var be = _maybeParseInnerEffect(reader, composition); + if (be != null) { + blurEffect = be; + } + } + reader.endArray(); + default: + reader.skipName(); + reader.skipValue(); + } + } + return blurEffect; + } + + static BlurEffect? _maybeParseInnerEffect( + JsonReader reader, + LottieComposition composition, + ) { + BlurEffect? blurEffect; + var isCorrectType = false; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_innerBlurEffectNames)) { + case 0: + isCorrectType = reader.nextInt() == 0; + case 1: + if (isCorrectType) { + blurEffect = BlurEffect( + AnimatableValueParser.parseFloat(reader, composition), + ); + } else { + reader.skipValue(); + } + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + return blurEffect; + } +} diff --git a/lottie/lib/src/parser/circle_shape_parser.dart b/lottie/lib/src/parser/circle_shape_parser.dart new file mode 100644 index 0000000..4ba7617 --- /dev/null +++ b/lottie/lib/src/parser/circle_shape_parser.dart @@ -0,0 +1,62 @@ +import 'dart:ui'; +import '../../lottie.dart'; +import '../model/animatable/animatable_point_value.dart'; +import '../model/animatable/animatable_value.dart'; +import '../model/content/circle_shape.dart'; +import 'animatable_path_value_parser.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class CircleShapeParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'p', + 's', + 'hd', + 'd', + ]); + + CircleShapeParser._(); + + static CircleShape parse( + JsonReader reader, + LottieComposition composition, + int d, + ) { + String? name; + late AnimatableValue position; + late AnimatablePointValue size; + var reversed = d == 3; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + position = AnimatablePathValueParser.parseSplitPath( + reader, + composition, + ); + case 2: + size = AnimatableValueParser.parsePoint(reader, composition); + case 3: + hidden = reader.nextBoolean(); + case 4: + // "d" is 2 for normal and 3 for reversed. + reversed = reader.nextInt() == 3; + default: + reader.skipName(); + reader.skipValue(); + } + } + + return CircleShape( + name: name, + position: position, + size: size, + isReversed: reversed, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/color_parser.dart b/lottie/lib/src/parser/color_parser.dart new file mode 100644 index 0000000..5e1391c --- /dev/null +++ b/lottie/lib/src/parser/color_parser.dart @@ -0,0 +1,35 @@ +import 'dart:ui'; +import 'moshi/json_reader.dart'; + +Color colorParser(JsonReader reader) { + var isArray = reader.peek() == Token.beginArray; + if (isArray) { + reader.beginArray(); + } + var r = reader.nextDouble(); + var g = reader.nextDouble(); + var b = reader.nextDouble(); + var a = 1.0; + + // Sometimes, Lottie editors only export rgb instead of rgba. + // https://github.com/airbnb/lottie-android/issues/1601 + if (reader.peek() == Token.number) { + a = reader.nextDouble(); + } + + if (isArray) { + reader.endArray(); + } + + if (r <= 1 && g <= 1 && b <= 1) { + r *= 255; + g *= 255; + b *= 255; + // It appears as if sometimes, Telegram Lottie stickers are exported with rgb [0,1] and a [0,255]. + // This shouldn't happen but we can gracefully handle it when it does. + // https://github.com/airbnb/lottie-android/issues/1478 + if (a <= 1) a *= 255; + } + + return Color.fromARGB(a.round(), r.round(), g.round(), b.round()); +} diff --git a/lottie/lib/src/parser/content_model_parser.dart b/lottie/lib/src/parser/content_model_parser.dart new file mode 100644 index 0000000..c2aa673 --- /dev/null +++ b/lottie/lib/src/parser/content_model_parser.dart @@ -0,0 +1,91 @@ +import '../composition.dart'; +import '../model/content/content_model.dart'; +import 'animatable_transform_parser.dart'; +import 'circle_shape_parser.dart'; +import 'gradient_fill_parser.dart'; +import 'gradient_stroke_parser.dart'; +import 'merge_paths_parser.dart'; +import 'moshi/json_reader.dart'; +import 'polysar_shape_parser.dart'; +import 'rectangle_shape_parser.dart'; +import 'repeat_parser.dart'; +import 'rounded_corners_parser.dart'; +import 'shape_fill_parser.dart'; +import 'shape_group_parser.dart'; +import 'shape_path_parser.dart'; +import 'shape_stroke_parser.dart'; +import 'shape_trim_path_parser.dart'; + +class ContentModelParser { + static final JsonReaderOptions _names = JsonReaderOptions.of(['ty', 'd']); + + ContentModelParser._(); + + static ContentModel? parse(JsonReader reader, LottieComposition composition) { + String? type; + + reader.beginObject(); + // Unfortunately, for an ellipse, d is before "ty" which means that it will get parsed + // before we are in the ellipse parser. + // "d" is 2 for normal and 3 for reversed. + var d = 2; + typeLoop: + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + type = reader.nextString(); + break typeLoop; + case 1: + d = reader.nextInt(); + default: + reader.skipName(); + reader.skipValue(); + } + } + + if (type == null) { + return null; + } + + ContentModel? model; + switch (type) { + case 'gr': + model = ShapeGroupParser.parse(reader, composition); + case 'st': + model = ShapeStrokeParser.parse(reader, composition); + case 'gs': + model = GradientStrokeParser.parse(reader, composition); + case 'fl': + model = ShapeFillParser.parse(reader, composition); + case 'gf': + model = GradientFillParser.parse(reader, composition); + case 'tr': + model = AnimatableTransformParser.parse(reader, composition); + case 'sh': + model = ShapePathParser.parse(reader, composition); + case 'el': + model = CircleShapeParser.parse(reader, composition, d); + case 'rc': + model = RectangleShapeParser.parse(reader, composition); + case 'tm': + model = ShapeTrimPathParser.parse(reader, composition); + case 'sr': + model = PolystarShapeParser.parse(reader, composition, d: d); + case 'mm': + model = MergePathsParser.parse(reader); + case 'rp': + model = RepeaterParser.parse(reader, composition); + case 'rd': + model = RoundedCornersParser.parse(reader, composition); + default: + composition.addWarning('Unknown shape type $type'); + } + + while (reader.hasNext()) { + reader.skipValue(); + } + reader.endObject(); + + return model; + } +} diff --git a/lottie/lib/src/parser/document_data_parser.dart b/lottie/lib/src/parser/document_data_parser.dart new file mode 100644 index 0000000..ad067ec --- /dev/null +++ b/lottie/lib/src/parser/document_data_parser.dart @@ -0,0 +1,98 @@ +import 'dart:ui'; +import '../model/document_data.dart'; +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; + +final JsonReaderOptions _names = JsonReaderOptions.of([ + 't', // 0 + 'f', // 1 + 's', // 2 + 'j', // 3 + 'tr', // 4 + 'lh', // 5 + 'ls', // 6 + 'fc', // 7 + 'sc', // 8 + 'sw', // 9 + 'of', // 10 + 'ps', // 11 + 'sz', // 12 +]); + +DocumentData documentDataParser(JsonReader reader) { + String? text; + String? fontName; + var size = 0.0; + var justification = Justification.center; + var tracking = 0; + var lineHeight = 0.0; + var baselineShift = 0.0; + var fillColor = const Color(0x00000000); + var strokeColor = const Color(0x00000000); + var strokeWidth = 0.0; + var strokeOverFill = true; + Offset? boxPosition; + Offset? boxSize; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + text = reader.nextString(); + case 1: + fontName = reader.nextString(); + case 2: + size = reader.nextDouble(); + case 3: + var justificationInt = reader.nextInt(); + if (justificationInt > Justification.center.index || + justificationInt < 0) { + justification = Justification.center; + } else { + justification = Justification.values[justificationInt]; + } + case 4: + tracking = reader.nextInt(); + case 5: + lineHeight = reader.nextDouble(); + case 6: + baselineShift = reader.nextDouble(); + case 7: + fillColor = JsonUtils.jsonToColor(reader); + case 8: + strokeColor = JsonUtils.jsonToColor(reader); + case 9: + strokeWidth = reader.nextDouble(); + case 10: + strokeOverFill = reader.nextBoolean(); + case 11: + reader.beginArray(); + boxPosition = Offset(reader.nextDouble(), reader.nextDouble()); + reader.endArray(); + case 12: + reader.beginArray(); + boxSize = Offset(reader.nextDouble(), reader.nextDouble()); + reader.endArray(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + return DocumentData( + text: text ?? '', + fontName: fontName, + size: size, + justification: justification, + tracking: tracking, + lineHeight: lineHeight, + baselineShift: baselineShift, + color: fillColor, + strokeColor: strokeColor, + strokeWidth: strokeWidth, + strokeOverFill: strokeOverFill, + boxPosition: boxPosition, + boxSize: boxSize, + ); +} diff --git a/lottie/lib/src/parser/drop_shadow_effect_parser.dart b/lottie/lib/src/parser/drop_shadow_effect_parser.dart new file mode 100644 index 0000000..b756079 --- /dev/null +++ b/lottie/lib/src/parser/drop_shadow_effect_parser.dart @@ -0,0 +1,95 @@ +import '../composition.dart'; +import '../model/animatable/animatable_color_value.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/content/drop_shadow_effect.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class DropShadowEffectParser { + static final JsonReaderOptions _dropShadowEffectNames = JsonReaderOptions.of([ + 'ef', + ]); + + static final JsonReaderOptions _innerEffectNames = JsonReaderOptions.of([ + 'nm', + 'v', + ]); + + AnimatableColorValue? _color; + AnimatableDoubleValue? _opacity; + AnimatableDoubleValue? _direction; + AnimatableDoubleValue? _distance; + AnimatableDoubleValue? _radius; + + DropShadowEffect? parse(JsonReader reader, LottieComposition composition) { + while (reader.hasNext()) { + switch (reader.selectName(_dropShadowEffectNames)) { + case 0: + reader.beginArray(); + while (reader.hasNext()) { + _maybeParseInnerEffect(reader, composition); + } + reader.endArray(); + default: + reader.skipName(); + reader.skipValue(); + } + } + + var color = _color; + var opacity = _opacity; + var direction = _direction; + var distance = _distance; + var radius = _radius; + if (color != null && + opacity != null && + direction != null && + distance != null && + radius != null) { + return DropShadowEffect( + color: color, + opacity: opacity, + direction: direction, + distance: distance, + radius: radius, + ); + } + return null; + } + + void _maybeParseInnerEffect( + JsonReader reader, + LottieComposition composition, + ) { + var currentEffectName = ''; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_innerEffectNames)) { + case 0: + currentEffectName = reader.nextString(); + case 1: + switch (currentEffectName) { + case 'Shadow Color': + _color = AnimatableValueParser.parseColor(reader, composition); + case 'Opacity': + _opacity = AnimatableValueParser.parseFloat(reader, composition); + case 'Direction': + _direction = AnimatableValueParser.parseFloat( + reader, + composition, + ); + case 'Distance': + _distance = AnimatableValueParser.parseFloat(reader, composition); + case 'Softness': + _radius = AnimatableValueParser.parseFloat(reader, composition); + default: + reader.skipValue(); + } + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + } +} diff --git a/lottie/lib/src/parser/float_parser.dart b/lottie/lib/src/parser/float_parser.dart new file mode 100644 index 0000000..c80ecc6 --- /dev/null +++ b/lottie/lib/src/parser/float_parser.dart @@ -0,0 +1,6 @@ +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; + +double floatParser(JsonReader reader) { + return JsonUtils.valueFromObject(reader); +} diff --git a/lottie/lib/src/parser/font_character_parser.dart b/lottie/lib/src/parser/font_character_parser.dart new file mode 100644 index 0000000..7d55c74 --- /dev/null +++ b/lottie/lib/src/parser/font_character_parser.dart @@ -0,0 +1,76 @@ +import '../composition.dart'; +import '../model/content/shape_group.dart'; +import '../model/font_character.dart'; +import 'content_model_parser.dart'; +import 'moshi/json_reader.dart'; + +class FontCharacterParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'ch', + 'size', + 'w', + 'style', + 'fFamily', + 'data', + ]); + static final JsonReaderOptions _dataNames = JsonReaderOptions.of(['shapes']); + + FontCharacterParser._(); + + static FontCharacter parse(JsonReader reader, LottieComposition composition) { + String? character = ''; + var size = 0.0; + var width = 0.0; + String? style; + String? fontFamily; + var shapes = []; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + character = reader.nextString(); + case 1: + size = reader.nextDouble(); + case 2: + width = reader.nextDouble(); + case 3: + style = reader.nextString(); + case 4: + fontFamily = reader.nextString(); + case 5: + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_dataNames)) { + case 0: + reader.beginArray(); + while (reader.hasNext()) { + if (ContentModelParser.parse(reader, composition) + case var shape?) { + shapes.add(shape as ShapeGroup); + } + } + reader.endArray(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + return FontCharacter( + shapes: shapes, + character: character!, + size: size, + width: width, + style: style ?? '', + fontFamily: fontFamily ?? '', + ); + } +} diff --git a/lottie/lib/src/parser/font_parser.dart b/lottie/lib/src/parser/font_parser.dart new file mode 100644 index 0000000..1a32c83 --- /dev/null +++ b/lottie/lib/src/parser/font_parser.dart @@ -0,0 +1,45 @@ +import '../model/font.dart'; +import 'moshi/json_reader.dart'; + +class FontParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'fFamily', + 'fName', + 'fStyle', + 'ascent', + ]); + + FontParser._(); + + static Font parse(JsonReader reader) { + String? family; + String? name; + String? style; + var ascent = 0.0; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + family = reader.nextString(); + case 1: + name = reader.nextString(); + case 2: + style = reader.nextString(); + case 3: + ascent = reader.nextDouble(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + return Font( + family: family ?? '', + name: name ?? '', + style: style ?? '', + ascent: ascent, + ); + } +} diff --git a/lottie/lib/src/parser/gradient_color_parser.dart b/lottie/lib/src/parser/gradient_color_parser.dart new file mode 100644 index 0000000..397c442 --- /dev/null +++ b/lottie/lib/src/parser/gradient_color_parser.dart @@ -0,0 +1,275 @@ +import 'dart:ui'; +import '../model/content/gradient_color.dart'; +import '../utils/collection.dart'; +import '../utils/gamma_evaluator.dart'; +import 'moshi/json_reader.dart'; + +class GradientColorParser { + /// The number of colors if it exists in the json or -1 if it doesn't (legacy bodymovin) + int _colorPoints; + + GradientColorParser(this._colorPoints); + + /// Both the color stops and opacity stops are in the same array. + /// There are {@link #colorPoints} colors sequentially as: + /// [ + /// ..., + /// position, + /// red, + /// green, + /// blue, + /// ... + /// ] + ///

+ /// The remainder of the array is the opacity stops sequentially as: + /// [ + /// ..., + /// position, + /// opacity, + /// ... + /// ] + GradientColor parse(JsonReader reader) { + var array = []; + // The array was started by Keyframe because it thought that this may be an array of keyframes + // but peek returned a number so it considered it a static array of numbers. + var isArray = reader.peek() == Token.beginArray; + if (isArray) { + reader.beginArray(); + } + while (reader.hasNext()) { + array.add(reader.nextDouble()); + } + if (array.length == 4 && array[0] == 1) { + // If a gradient color only contains one color at position 1, add a second stop with the same + // color at position 0. Android's LinearGradient shader requires at least two colors. + // https://github.com/airbnb/lottie-android/issues/1967 + array[0] = 0; + array.add(1); + array.add(array[1]); + array.add(array[2]); + array.add(array[3]); + _colorPoints = 2; + } + if (isArray) { + reader.endArray(); + } + if (_colorPoints == -1) { + _colorPoints = array.length ~/ 4; + } + + var positions = List.filled(_colorPoints, 0.0); + var colors = List.filled(_colorPoints, const Color(0x00000000)); + + var r = 0; + var g = 0; + for (var i = 0; i < _colorPoints * 4; i++) { + var colorIndex = i ~/ 4; + var value = array[i]; + switch (i % 4) { + case 0: + // position + positions[colorIndex] = value; + case 1: + r = (value * 255).round(); + case 2: + g = (value * 255).round(); + case 3: + var b = (value * 255).round(); + colors[colorIndex] = Color.fromARGB(255, r, g, b); + } + } + + var gradientColor = GradientColor(positions, colors); + gradientColor = _addOpacityStopsToGradientIfNeeded(gradientColor, array); + return gradientColor; + } + + /// This cheats a little bit. + /// Opacity stops can be at arbitrary intervals independent of color stops. + /// This uses the existing color stops and modifies the opacity at each existing color stop + /// based on what the opacity would be. + ///

+ /// This should be a good approximation is nearly all cases. However, if there are many more + /// opacity stops than color stops, information will be lost. + GradientColor _addOpacityStopsToGradientIfNeeded( + GradientColor gradientColor, + List array, + ) { + var startIndex = _colorPoints * 4; + if (array.length <= startIndex) { + return gradientColor; + } + + // When there are opacity stops, we create a merged list of color stops and opacity stops. + // For a given color stop, we linearly interpolate the opacity for the two opacity stops around it. + // For a given opacity stop, we linearly interpolate the color for the two color stops around it. + var colorStopPositions = gradientColor.positions; + var colorStopColors = gradientColor.colors; + + var opacityStops = (array.length - startIndex) ~/ 2; + var opacityStopPositions = List.filled(opacityStops, 0.0); + var opacityStopOpacities = List.filled(opacityStops, 0.0); + + for (var i = startIndex, j = 0; i < array.length; i++) { + if (i % 2 == 0) { + opacityStopPositions[j] = array[i]; + } else { + opacityStopOpacities[j] = array[i]; + j++; + } + } + + // Pre-SKIA (Oreo) devices render artifacts when there is two stops in the same position. + // As a result, we have to de-dupe the merge color and opacity stop positions. + var newPositions = mergeUniqueElements( + gradientColor.positions, + opacityStopPositions, + ); + var newColorPoints = newPositions.length; + var newColors = List.filled(newColorPoints, const Color(0xff000000)); + + for (var i = 0; i < newColorPoints; i++) { + var position = newPositions[i]; + var colorStopIndex = binarySearch(colorStopPositions, position); + var opacityIndex = binarySearch(opacityStopPositions, position); + if (colorStopIndex < 0 || opacityIndex > 0) { + // This is a stop derived from an opacity stop. + if (opacityIndex < 0) { + // The formula here is derived from the return value for binarySearch. When an item isn't found, it returns -insertionPoint - 1. + opacityIndex = -(opacityIndex + 1); + } + newColors[i] = _getColorInBetweenColorStops( + position, + opacityStopOpacities[opacityIndex], + colorStopPositions, + colorStopColors, + ); + } else { + // This os a step derived from a color stop. + newColors[i] = _getColorInBetweenOpacityStops( + position, + colorStopColors[colorStopIndex], + opacityStopPositions, + opacityStopOpacities, + ); + } + } + return GradientColor(newPositions, newColors); + } + + Color _getColorInBetweenColorStops( + double position, + double opacity, + List colorStopPositions, + List colorStopColors, + ) { + if (colorStopColors.length < 2 || position == colorStopPositions[0]) { + return colorStopColors[0]; + } + for (var i = 1; i < colorStopPositions.length; i++) { + var colorStopPosition = colorStopPositions[i]; + if (colorStopPosition < position && i != colorStopPositions.length - 1) { + continue; + } + if (i == colorStopPositions.length - 1 && position >= colorStopPosition) { + return colorStopColors[i].withValues(alpha: opacity); + } + // We found the position in which position is between i - 1 and i. + var distanceBetweenColors = + colorStopPositions[i] - colorStopPositions[i - 1]; + var distanceToLowerColor = position - colorStopPositions[i - 1]; + var percentage = distanceToLowerColor / distanceBetweenColors; + var upperColor = colorStopColors[i]; + var lowerColor = colorStopColors[i - 1]; + return GammaEvaluator.evaluate( + percentage, + lowerColor.withValues(alpha: 1), + upperColor.withValues(alpha: 1), + ).withValues(alpha: opacity); + } + throw Exception('Unreachable code.'); + } + + Color _getColorInBetweenOpacityStops( + double position, + Color color, + List opacityStopPositions, + List opacityStopOpacities, + ) { + if (opacityStopOpacities.length < 2 || + position <= opacityStopPositions[0]) { + return color.withValues(alpha: opacityStopOpacities[0]); + } + for (var i = 1; i < opacityStopPositions.length; i++) { + var opacityStopPosition = opacityStopPositions[i]; + if (opacityStopPosition < position && + i != opacityStopPositions.length - 1) { + continue; + } + final double opacity; + if (opacityStopPosition <= position) { + opacity = opacityStopOpacities[i]; + } else { + // We found the position in which position in between i - 1 and i. + var distanceBetweenOpacities = + opacityStopPositions[i] - opacityStopPositions[i - 1]; + var distanceToLowerOpacity = position - opacityStopPositions[i - 1]; + var percentage = distanceToLowerOpacity / distanceBetweenOpacities; + opacity = lerpDouble( + opacityStopOpacities[i - 1], + opacityStopOpacities[i], + percentage, + )!; + } + return color.withValues(alpha: opacity); + } + throw Exception('Unreachable code.'); + } + + /// Takes two sorted float arrays and merges their elements while removing duplicates. + static List mergeUniqueElements( + List arrayA, + List arrayB, + ) { + if (arrayA.isEmpty) { + return arrayB; + } else if (arrayB.isEmpty) { + return arrayA; + } + + var aIndex = 0; + var bIndex = 0; + var numDuplicates = 0; + // This will be the merged list but may be longer than what is needed if there are duplicates. + // If there are, the 0 elements at the end need to be truncated. + var mergedNotTruncated = List.filled( + arrayA.length + arrayB.length, + 0, + ); + for (var i = 0; i < mergedNotTruncated.length; i++) { + final a = aIndex < arrayA.length ? arrayA[aIndex] : double.nan; + final b = bIndex < arrayB.length ? arrayB[bIndex] : double.nan; + + if (b.isNaN || a < b) { + mergedNotTruncated[i] = a; + aIndex++; + } else if (a.isNaN || b < a) { + mergedNotTruncated[i] = b; + bIndex++; + } else { + mergedNotTruncated[i] = a; + aIndex++; + bIndex++; + numDuplicates++; + } + } + + if (numDuplicates == 0) { + return mergedNotTruncated; + } + + return mergedNotTruncated + .take(mergedNotTruncated.length - numDuplicates) + .toList(); + } +} diff --git a/lottie/lib/src/parser/gradient_fill_parser.dart b/lottie/lib/src/parser/gradient_fill_parser.dart new file mode 100644 index 0000000..85a2ff3 --- /dev/null +++ b/lottie/lib/src/parser/gradient_fill_parser.dart @@ -0,0 +1,101 @@ +import 'dart:ui'; +import '../../lottie.dart'; +import '../model/animatable/animatable_gradient_color_value.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/animatable/animatable_point_value.dart'; +import '../model/content/gradient_fill.dart'; +import '../model/content/gradient_type.dart'; +import '../value/keyframe.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class GradientFillParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'g', + 'o', + 't', + 's', + 'e', + 'r', + 'hd', + ]); + static final JsonReaderOptions _gradientNames = JsonReaderOptions.of([ + 'p', + 'k', + ]); + + GradientFillParser._(); + + static GradientFill parse(JsonReader reader, LottieComposition composition) { + String? name; + AnimatableGradientColorValue? color; + AnimatableIntegerValue? opacity; + GradientType? gradientType; + AnimatablePointValue? startPoint; + AnimatablePointValue? endPoint; + var fillType = PathFillType.nonZero; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + var points = -1; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_gradientNames)) { + case 0: + points = reader.nextInt(); + case 1: + color = AnimatableValueParser.parseGradientColor( + reader, + composition, + points, + ); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + case 2: + opacity = AnimatableValueParser.parseInteger(reader, composition); + case 3: + gradientType = reader.nextInt() == 1 + ? GradientType.linear + : GradientType.radial; + case 4: + startPoint = AnimatableValueParser.parsePoint(reader, composition); + case 5: + endPoint = AnimatableValueParser.parsePoint(reader, composition); + case 6: + fillType = reader.nextInt() == 1 + ? PathFillType.nonZero + : PathFillType.evenOdd; + case 7: + hidden = reader.nextBoolean(); + default: + reader.skipName(); + reader.skipValue(); + } + } + + // Telegram sometimes omits opacity. + // https://github.com/airbnb/lottie-android/issues/1600 + opacity ??= AnimatableIntegerValue.fromKeyframes([ + Keyframe.nonAnimated(100), + ]); + return GradientFill( + name: name, + gradientType: gradientType ?? GradientType.linear, + fillType: fillType, + gradientColor: color!, + opacity: opacity, + startPoint: startPoint!, + endPoint: endPoint!, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/gradient_stroke_parser.dart b/lottie/lib/src/parser/gradient_stroke_parser.dart new file mode 100644 index 0000000..4298467 --- /dev/null +++ b/lottie/lib/src/parser/gradient_stroke_parser.dart @@ -0,0 +1,158 @@ +import '../../lottie.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_gradient_color_value.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/animatable/animatable_point_value.dart'; +import '../model/content/gradient_stroke.dart'; +import '../model/content/gradient_type.dart'; +import '../model/content/shape_stroke.dart'; +import '../value/keyframe.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class GradientStrokeParser { + GradientStrokeParser._(); + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'g', + 'o', + 't', + 's', + 'e', + 'w', + 'lc', + 'lj', + 'ml', + 'hd', + 'd', + ]); + static final JsonReaderOptions _gradientNames = JsonReaderOptions.of([ + 'p', + 'k', + ]); + static final JsonReaderOptions _dashPatternNames = JsonReaderOptions.of([ + 'n', + 'v', + ]); + + static GradientStroke parse( + JsonReader reader, + LottieComposition composition, + ) { + String? name; + AnimatableGradientColorValue? color; + AnimatableIntegerValue? opacity; + GradientType? gradientType; + AnimatablePointValue? startPoint; + AnimatablePointValue? endPoint; + AnimatableDoubleValue? width; + LineCapType? capType; + LineJoinType? joinType; + AnimatableDoubleValue? offset; + var miterLimit = 0.0; + var hidden = false; + + var lineDashPattern = []; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + var points = -1; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_gradientNames)) { + case 0: + points = reader.nextInt(); + case 1: + color = AnimatableValueParser.parseGradientColor( + reader, + composition, + points, + ); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + case 2: + opacity = AnimatableValueParser.parseInteger(reader, composition); + case 3: + gradientType = reader.nextInt() == 1 + ? GradientType.linear + : GradientType.radial; + case 4: + startPoint = AnimatableValueParser.parsePoint(reader, composition); + case 5: + endPoint = AnimatableValueParser.parsePoint(reader, composition); + case 6: + width = AnimatableValueParser.parseFloat(reader, composition); + case 7: + capType = LineCapType.values[reader.nextInt() - 1]; + case 8: + joinType = LineJoinType.values[reader.nextInt() - 1]; + case 9: + miterLimit = reader.nextDouble(); + case 10: + hidden = reader.nextBoolean(); + case 11: + reader.beginArray(); + while (reader.hasNext()) { + String? n; + AnimatableDoubleValue? val; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_dashPatternNames)) { + case 0: + n = reader.nextString(); + case 1: + val = AnimatableValueParser.parseFloat(reader, composition); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + if (n == 'o') { + offset = val; + } else if (n == 'd' || n == 'g') { + composition.hasDashPattern = true; + lineDashPattern.add(val!); + } + } + reader.endArray(); + if (lineDashPattern.length == 1) { + // If there is only 1 value then it is assumed to be equal parts on and off. + lineDashPattern.add(lineDashPattern[0]); + } + default: + reader.skipName(); + reader.skipValue(); + } + } + + // Telegram sometimes omits opacity. + // https://github.com/airbnb/lottie-android/issues/1600 + opacity ??= AnimatableIntegerValue.fromKeyframes([ + Keyframe.nonAnimated(100), + ]); + return GradientStroke( + name: name, + gradientType: gradientType ?? GradientType.linear, + gradientColor: color!, + opacity: opacity, + startPoint: startPoint!, + endPoint: endPoint!, + width: width!, + capType: capType, + joinType: joinType, + miterLimit: miterLimit, + lineDashPattern: lineDashPattern, + dashOffset: offset, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/integer_parser.dart b/lottie/lib/src/parser/integer_parser.dart new file mode 100644 index 0000000..53d8731 --- /dev/null +++ b/lottie/lib/src/parser/integer_parser.dart @@ -0,0 +1,6 @@ +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; + +int integerParser(JsonReader reader) { + return JsonUtils.valueFromObject(reader).round(); +} diff --git a/lottie/lib/src/parser/json_utils.dart b/lottie/lib/src/parser/json_utils.dart new file mode 100644 index 0000000..cad22db --- /dev/null +++ b/lottie/lib/src/parser/json_utils.dart @@ -0,0 +1,117 @@ +import 'dart:ui'; +import 'moshi/json_reader.dart'; + +class JsonUtils { + static Color jsonToColor(JsonReader reader) { + reader.beginArray(); + var r = (reader.nextDouble() * 255).round(); + var g = (reader.nextDouble() * 255).round(); + var b = (reader.nextDouble() * 255).round(); + while (reader.hasNext()) { + reader.skipValue(); + } + reader.endArray(); + return Color.fromARGB(255, r, g, b); + } + + static List jsonToPoints(JsonReader reader) { + var points = []; + + reader.beginArray(); + while (reader.peek() == Token.beginArray) { + reader.beginArray(); + points.add(jsonToPoint(reader)); + reader.endArray(); + } + reader.endArray(); + return points; + } + + static Offset jsonToPoint(JsonReader reader) { + switch (reader.peek()) { + case Token.number: + return _jsonNumbersToPoint(reader); + case Token.beginArray: + return _jsonArrayToPoint(reader); + case Token.beginObject: + return _jsonObjectToPoint(reader); + case Token.nullToken: + return Offset.zero; + case Token.endArray: + case Token.endObject: + case Token.name: + case Token.string: + case Token.boolean: + case Token.endDocument: + throw Exception('Unknown point starts with ${reader.peek()}'); + } + } + + static Offset _jsonNumbersToPoint(JsonReader reader) { + var x = reader.nextDouble(); + var y = reader.nextDouble(); + while (reader.hasNext()) { + reader.skipValue(); + } + return Offset(x, y); + } + + static Offset _jsonArrayToPoint(JsonReader reader) { + double x; + double y; + reader.beginArray(); + x = reader.nextDouble(); + y = reader.nextDouble(); + while (reader.peek() != Token.endArray) { + reader.skipValue(); + } + reader.endArray(); + return Offset(x, y); + } + + static final JsonReaderOptions _pointNames = JsonReaderOptions.of(['x', 'y']); + + static Offset _jsonObjectToPoint(JsonReader reader) { + var x = 0.0; + var y = 0.0; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_pointNames)) { + case 0: + x = valueFromObject(reader); + case 1: + y = valueFromObject(reader); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + return Offset(x, y); + } + + static double valueFromObject(JsonReader reader) { + var token = reader.peek(); + switch (token) { + case Token.number: + return reader.nextDouble(); + case Token.beginArray: + reader.beginArray(); + var val = reader.nextDouble(); + while (reader.hasNext()) { + reader.skipValue(); + } + reader.endArray(); + return val; + case Token.endArray: + case Token.beginObject: + case Token.endObject: + case Token.name: + case Token.string: + case Token.boolean: + case Token.nullToken: + case Token.endDocument: + throw Exception('Unknown value for token of type $token'); + } + } +} diff --git a/lottie/lib/src/parser/keyframe_parser.dart b/lottie/lib/src/parser/keyframe_parser.dart new file mode 100644 index 0000000..c1d7cb7 --- /dev/null +++ b/lottie/lib/src/parser/keyframe_parser.dart @@ -0,0 +1,334 @@ +import 'dart:math'; +import 'package:flutter/widgets.dart'; +import '../composition.dart'; +import '../utils/path_interpolator.dart'; +import '../utils/utils.dart'; +import '../value/keyframe.dart'; +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; +import 'value_parser.dart'; + +class KeyframeParser { + /// Some animations get exported with insane cp values in the tens of thousands. + /// PathInterpolator fails to create the interpolator in those cases and hangs. + /// Clamping the cp helps prevent that. + static const _maxCpValue = 100.0; + static const _linearInterpolator = Curves.linear; + static final _pathInterpolatorCache = {}; + + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 't', + 's', + 'e', + 'o', + 'i', + 'h', + 'to', + 'ti', + ]); + + static final JsonReaderOptions _interpolatorNames = JsonReaderOptions.of([ + 'x', // 1 + 'y', // 2 + ]); + + /// @param multiDimensional When true, the keyframe interpolators can be independent for the X and Y axis. + static Keyframe parse( + JsonReader reader, + LottieComposition composition, + ValueParser valueParser, { + required bool animated, + bool multiDimensional = false, + }) { + if (animated && multiDimensional) { + return _parseMultiDimensionalKeyframe(composition, reader, valueParser); + } else if (animated) { + return _parseKeyframe(composition, reader, valueParser); + } else { + return _parseStaticValue(reader, valueParser); + } + } + + /// beginObject will already be called on the keyframe so it can be differentiated with + /// a non animated value. + static Keyframe _parseKeyframe( + LottieComposition composition, + JsonReader reader, + ValueParser valueParser, + ) { + Offset? cp1; + Offset? cp2; + var startFrame = 0.0; + T? startValue; + T? endValue; + var hold = false; + Curve interpolator; + + // Only used by PathKeyframe + Offset? pathCp1; + Offset? pathCp2; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + startFrame = reader.nextDouble(); + case 1: + startValue = valueParser(reader); + case 2: + endValue = valueParser(reader); + case 3: + cp1 = JsonUtils.jsonToPoint(reader); + case 4: + cp2 = JsonUtils.jsonToPoint(reader); + case 5: + hold = reader.nextInt() == 1; + case 6: + pathCp1 = JsonUtils.jsonToPoint(reader); + case 7: + pathCp2 = JsonUtils.jsonToPoint(reader); + default: + reader.skipValue(); + } + } + reader.endObject(); + + if (hold) { + endValue = startValue; + // TODO: create a HoldInterpolator so progress changes don't invalidate. + interpolator = _linearInterpolator; + } else if (cp1 != null && cp2 != null) { + interpolator = _interpolatorFor(cp1, cp2); + } else { + interpolator = _linearInterpolator; + } + + var keyframe = Keyframe( + composition, + startValue: startValue, + endValue: endValue, + interpolator: interpolator, + startFrame: startFrame, + ); + keyframe.pathCp1 = pathCp1; + keyframe.pathCp2 = pathCp2; + return keyframe; + } + + static Keyframe _parseMultiDimensionalKeyframe( + LottieComposition composition, + JsonReader reader, + ValueParser valueParser, + ) { + Offset? cp1; + Offset? cp2; + + Offset? xCp1; + Offset? xCp2; + Offset? yCp1; + Offset? yCp2; + + var startFrame = 0.0; + T? startValue; + T? endValue; + var hold = false; + Curve? interpolator; + Curve? xInterpolator; + Curve? yInterpolator; + + // Only used by PathKeyframe + Offset? pathCp1; + Offset? pathCp2; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: // t + startFrame = reader.nextDouble(); + case 1: // s + startValue = valueParser(reader); + case 2: // e + endValue = valueParser(reader); + case 3: // o + if (reader.peek() == Token.beginObject) { + reader.beginObject(); + var xCp1x = 0.0; + var xCp1y = 0.0; + var yCp1x = 0.0; + var yCp1y = 0.0; + while (reader.hasNext()) { + switch (reader.selectName(_interpolatorNames)) { + case 0: // x + if (reader.peek() == Token.number) { + xCp1x = reader.nextDouble(); + yCp1x = xCp1x; + } else { + reader.beginArray(); + xCp1x = reader.nextDouble(); + if (reader.peek() == Token.number) { + yCp1x = reader.nextDouble(); + } else { + yCp1x = xCp1x; + } + reader.endArray(); + } + case 1: // y + if (reader.peek() == Token.number) { + xCp1y = reader.nextDouble(); + yCp1y = xCp1y; + } else { + reader.beginArray(); + xCp1y = reader.nextDouble(); + if (reader.peek() == Token.number) { + yCp1y = reader.nextDouble(); + } else { + yCp1y = xCp1y; + } + reader.endArray(); + } + default: + reader.skipValue(); + } + } + xCp1 = Offset(xCp1x, xCp1y); + yCp1 = Offset(yCp1x, yCp1y); + reader.endObject(); + } else { + cp1 = JsonUtils.jsonToPoint(reader); + } + case 4: // i + if (reader.peek() == Token.beginObject) { + reader.beginObject(); + var xCp2x = 0.0; + var xCp2y = 0.0; + var yCp2x = 0.0; + var yCp2y = 0.0; + while (reader.hasNext()) { + switch (reader.selectName(_interpolatorNames)) { + case 0: // x + if (reader.peek() == Token.number) { + xCp2x = reader.nextDouble(); + yCp2x = xCp2x; + } else { + reader.beginArray(); + xCp2x = reader.nextDouble(); + if (reader.peek() == Token.number) { + yCp2x = reader.nextDouble(); + } else { + yCp2x = xCp2x; + } + reader.endArray(); + } + case 1: // y + if (reader.peek() == Token.number) { + xCp2y = reader.nextDouble(); + yCp2y = xCp2y; + } else { + reader.beginArray(); + xCp2y = reader.nextDouble(); + if (reader.peek() == Token.number) { + yCp2y = reader.nextDouble(); + } else { + yCp2y = xCp2y; + } + reader.endArray(); + } + default: + reader.skipValue(); + } + } + xCp2 = Offset(xCp2x, xCp2y); + yCp2 = Offset(yCp2x, yCp2y); + reader.endObject(); + } else { + cp2 = JsonUtils.jsonToPoint(reader); + } + case 5: // h + hold = reader.nextInt() == 1; + case 6: // to + pathCp1 = JsonUtils.jsonToPoint(reader); + case 7: // ti + pathCp2 = JsonUtils.jsonToPoint(reader); + default: + reader.skipValue(); + } + } + reader.endObject(); + + if (hold) { + endValue = startValue; + // TODO: create a HoldInterpolator so progress changes don't invalidate. + interpolator = _linearInterpolator; + } else if (cp1 != null && cp2 != null) { + interpolator = _interpolatorFor(cp1, cp2); + } else if (xCp1 != null && yCp1 != null && xCp2 != null && yCp2 != null) { + xInterpolator = _interpolatorFor(xCp1, xCp2); + yInterpolator = _interpolatorFor(yCp1, yCp2); + } else { + interpolator = _linearInterpolator; + } + + Keyframe keyframe; + if (xInterpolator != null && yInterpolator != null) { + keyframe = Keyframe( + composition, + startValue: startValue, + endValue: endValue, + xInterpolator: xInterpolator, + yInterpolator: yInterpolator, + startFrame: startFrame, + ); + } else { + keyframe = Keyframe( + composition, + startValue: startValue, + endValue: endValue, + interpolator: interpolator, + startFrame: startFrame, + ); + } + + keyframe.pathCp1 = pathCp1; + keyframe.pathCp2 = pathCp2; + return keyframe; + } + + static Curve _interpolatorFor(Offset cp1, Offset cp2) { + Curve interpolator; + cp1 = Offset(cp1.dx.clamp(-1, 1), cp1.dy.clamp(-_maxCpValue, _maxCpValue)); + cp2 = Offset(cp2.dx.clamp(-1, 1), cp2.dy.clamp(-_maxCpValue, _maxCpValue)); + var hash = Utils.hashFor(cp1.dx, cp1.dy, cp2.dx, cp2.dy); + + interpolator = _pathInterpolatorCache.putIfAbsent(hash, () { + try { + return PathInterpolator.cubic(cp1.dx, cp1.dy, cp2.dx, cp2.dy); + } catch (e) { + debugPrint('DEBUG: Path interpolator error $e'); + //TODO(xha): check the error message for Flutter + if ('$e'.contains('The Path cannot loop back on itself.')) { + // If a control point extends beyond the previous/next point then it will cause the value of the interpolator to no + // longer monotonously increase. This clips the control point bounds to prevent that from happening. + // NOTE: this will make the rendered animation behave slightly differently than the original. + return PathInterpolator.cubic( + min(cp1.dx, 1.0), + cp1.dy, + max(cp2.dx, 0.0), + cp2.dy, + ); + } else { + // We failed to create the interpolator. Fall back to linear. + return Curves.linear; + } + } + }); + return interpolator; + } + + static Keyframe _parseStaticValue( + JsonReader reader, + ValueParser valueParser, + ) { + var value = valueParser(reader); + return Keyframe.nonAnimated(value); + } +} diff --git a/lottie/lib/src/parser/keyframes_parser.dart b/lottie/lib/src/parser/keyframes_parser.dart new file mode 100644 index 0000000..07bd563 --- /dev/null +++ b/lottie/lib/src/parser/keyframes_parser.dart @@ -0,0 +1,99 @@ +import '../composition.dart'; +import '../value/keyframe.dart'; +import 'keyframe_parser.dart'; +import 'moshi/json_reader.dart'; +import 'value_parser.dart'; + +class KeyframesParser { + static final JsonReaderOptions _names = JsonReaderOptions.of(['k']); + + KeyframesParser._(); + + static List> parse( + JsonReader reader, + LottieComposition composition, + ValueParser valueParser, { + bool multiDimensional = false, + }) { + var keyframes = >[]; + + if (reader.peek() == Token.string) { + composition.addWarning("Lottie doesn't support expressions."); + return keyframes; + } + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + if (reader.peek() == Token.beginArray) { + reader.beginArray(); + + if (reader.peek() == Token.number) { + // For properties in which the static value is an array of numbers. + keyframes.add( + KeyframeParser.parse( + reader, + composition, + valueParser, + animated: false, + multiDimensional: multiDimensional, + ), + ); + } else { + while (reader.hasNext()) { + keyframes.add( + KeyframeParser.parse( + reader, + composition, + valueParser, + animated: true, + multiDimensional: multiDimensional, + ), + ); + } + } + reader.endArray(); + } else { + keyframes.add( + KeyframeParser.parse( + reader, + composition, + valueParser, + animated: false, + multiDimensional: multiDimensional, + ), + ); + } + default: + reader.skipValue(); + } + } + reader.endObject(); + + setEndFrames(keyframes); + return keyframes; + } + + /// The json doesn't include end frames. The data can be taken from the start frame of the next + /// keyframe though. + static void setEndFrames(List> keyframes) { + var size = keyframes.length; + for (var i = 0; i < size - 1; i++) { + // In the json, the keyframes only contain their starting frame. + var keyframe = keyframes[i]; + var nextKeyframe = keyframes[i + 1]; + keyframe.endFrame = nextKeyframe.startFrame; + if (keyframe.endValue == null && nextKeyframe.startValue != null) { + keyframe.endValue = nextKeyframe.startValue; + } + } + var lastKeyframe = keyframes[size - 1]; + if ((lastKeyframe.startValue == null || lastKeyframe.endValue == null) && + keyframes.length > 1) { + // The only purpose the last keyframe has is to provide the end frame of the previous + // keyframe. + keyframes.remove(lastKeyframe); + } + } +} diff --git a/lottie/lib/src/parser/layer_parser.dart b/lottie/lib/src/parser/layer_parser.dart new file mode 100644 index 0000000..c7bd41f --- /dev/null +++ b/lottie/lib/src/parser/layer_parser.dart @@ -0,0 +1,341 @@ +import 'dart:ui'; +import '../composition.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_text_frame.dart'; +import '../model/animatable/animatable_text_properties.dart'; +import '../model/animatable/animatable_transform.dart'; +import '../model/content/blur_effect.dart'; +import '../model/content/content_model.dart'; +import '../model/content/drop_shadow_effect.dart'; +import '../model/content/layer_blend.dart'; +import '../model/content/mask.dart'; +import '../model/layer/layer.dart'; +import '../utils/misc.dart'; +import '../value/keyframe.dart'; +import 'animatable_text_properties_parser.dart'; +import 'animatable_transform_parser.dart'; +import 'animatable_value_parser.dart'; +import 'blur_effect_parser.dart'; +import 'content_model_parser.dart'; +import 'drop_shadow_effect_parser.dart'; +import 'mask_parser.dart'; +import 'moshi/json_reader.dart'; + +class LayerParser { + LayerParser._(); + + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', // 0 + 'ind', // 1 + 'refId', // 2 + 'ty', // 3 + 'parent', // 4 + 'sw', // 5 + 'sh', // 6 + 'sc', // 7 + 'ks', // 8 + 'tt', // 9 + 'masksProperties', // 10 + 'shapes', // 11 + 't', // 12 + 'ef', // 13 + 'sr', // 14 + 'st', // 15 + 'w', // 16 + 'h', // 17 + 'ip', // 18 + 'op', // 19 + 'tm', // 20 + 'cl', // 21 + 'hd', // 22 + 'ao', // 23 + 'bm', // 24 + ]); + + static Layer parse(LottieComposition composition) { + var bounds = composition.bounds; + return Layer( + shapes: [], + composition: composition, + name: '__container', + id: -1, + layerType: LayerType.preComp, + parentId: -1, + masks: [], + transform: AnimatableTransform(), + solidWidth: 0, + solidHeight: 0, + solidColor: const Color(0x00000000), + timeStretch: 0, + startFrame: 0, + preCompWidth: bounds.width, + preCompHeight: bounds.height, + inOutKeyframes: >[], + matteType: MatteType.none, + isHidden: false, + ); + } + + static final JsonReaderOptions _textNames = JsonReaderOptions.of(['d', 'a']); + + static final JsonReaderOptions _effectsNames = JsonReaderOptions.of([ + 'ty', + 'nm', + ]); + + static Layer parseJson(JsonReader reader, LottieComposition composition) { + // This should always be set by After Effects. However, if somebody wants to minify + // and optimize their json, the name isn't critical for most cases so it can be removed. + var layerName = 'UNSET'; + var layerType = LayerType.unknown; + String? refId; + var layerId = 0; + var solidWidth = 0; + var solidHeight = 0; + var solidColor = const Color(0x00000000); + var preCompWidth = 0; + var preCompHeight = 0; + var parentId = -1; + var timeStretch = 1.0; + var startFrame = 0.0; + var inFrame = 0.0; + var outFrame = 0.0; + String? cl; + var hidden = false; + BlurEffect? blurEffect; + DropShadowEffect? dropShadowEffect; + var autoOrient = false; + + var matteType = MatteType.none; + BlendMode? blendMode; + AnimatableTransform? transform; + AnimatableTextFrame? text; + AnimatableTextProperties? textProperties; + AnimatableDoubleValue? timeRemapping; + + var masks = []; + var shapes = []; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + layerName = reader.nextString(); + case 1: + layerId = reader.nextInt(); + case 2: + refId = reader.nextString(); + case 3: + var layerTypeInt = reader.nextInt(); + if (layerTypeInt < LayerType.unknown.index) { + layerType = LayerType.values[layerTypeInt]; + } else { + layerType = LayerType.unknown; + } + case 4: + parentId = reader.nextInt(); + case 5: + solidWidth = reader.nextInt(); + case 6: + solidHeight = reader.nextInt(); + case 7: + solidColor = MiscUtils.parseColor( + reader.nextString(), + warningCallback: composition.addWarning, + ); + case 8: + transform = AnimatableTransformParser.parse(reader, composition); + case 9: + var matteTypeIndex = reader.nextInt(); + if (matteTypeIndex >= MatteType.values.length) { + composition.addWarning('Unsupported matte type: $matteTypeIndex'); + break; + } + matteType = MatteType.values[matteTypeIndex]; + if (matteType == MatteType.luma) { + composition.addWarning('Unsupported matte type: Luma'); + } else if (matteType == MatteType.lumaInverted) { + composition.addWarning('Unsupported matte type: Luma Inverted'); + } + composition.incrementMatteOrMaskCount(1); + case 10: + reader.beginArray(); + while (reader.hasNext()) { + masks.add(MaskParser.parse(reader, composition)); + } + composition.incrementMatteOrMaskCount(masks.length); + reader.endArray(); + case 11: + reader.beginArray(); + while (reader.hasNext()) { + var shape = ContentModelParser.parse(reader, composition); + if (shape != null) { + shapes.add(shape); + } + } + reader.endArray(); + case 12: + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_textNames)) { + case 0: + text = AnimatableValueParser.parseDocumentData( + reader, + composition, + ); + case 1: + reader.beginArray(); + if (reader.hasNext()) { + textProperties = AnimatableTextPropertiesParser.parse( + reader, + composition, + ); + } + while (reader.hasNext()) { + reader.skipValue(); + } + reader.endArray(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + case 13: + reader.beginArray(); + var effectNames = []; + while (reader.hasNext()) { + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_effectsNames)) { + case 0: + var type = reader.nextInt(); + if (type == 29) { + blurEffect = BlurEffectParser.parse(reader, composition); + } else if (type == 25) { + dropShadowEffect = DropShadowEffectParser().parse( + reader, + composition, + ); + } + case 1: + var effectName = reader.nextString(); + effectNames.add(effectName); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + } + reader.endArray(); + composition.addWarning( + "Lottie doesn't support layer effects. If you are using them for " + ' fills, strokes, trim paths etc. then try adding them directly as contents ' + ' in your shape. Found: $effectNames', + ); + case 14: + timeStretch = reader.nextDouble(); + case 15: + startFrame = reader.nextDouble(); + case 16: + preCompWidth = reader.nextDouble().toInt(); + case 17: + preCompHeight = reader.nextDouble().toInt(); + case 18: + inFrame = reader.nextDouble(); + case 19: + outFrame = reader.nextDouble(); + case 20: + timeRemapping = AnimatableValueParser.parseFloat(reader, composition); + case 21: + cl = reader.nextString(); + case 22: + hidden = reader.nextBoolean(); + case 23: + autoOrient = reader.nextInt() == 1; + case 24: + var blendModeIndex = reader.nextInt(); + if (blendModeIndex >= blendModes.length) { + composition.addWarning('Unsupported Blend Mode: $blendModeIndex'); + break; + } + blendMode = blendModes[blendModeIndex]; + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + var inOutKeyframes = >[]; + // Before the in frame + if (inFrame > 0) { + var preKeyframe = Keyframe( + composition, + startValue: 0.0, + endValue: 0.0, + startFrame: 0.0, + endFrame: inFrame, + ); + inOutKeyframes.add(preKeyframe); + } + + outFrame = outFrame > 0 ? outFrame : composition.endFrame; + var visibleKeyframe = Keyframe( + composition, + startValue: 1.0, + endValue: 1.0, + startFrame: inFrame, + endFrame: outFrame, + ); + inOutKeyframes.add(visibleKeyframe); + + var outKeyframe = Keyframe( + composition, + startValue: 0.0, + endValue: 0.0, + startFrame: outFrame, + endFrame: double.maxFinite, + ); + inOutKeyframes.add(outKeyframe); + + if (layerName.endsWith('.ai') || 'ai' == cl) { + composition.addWarning( + 'Convert your Illustrator layers to shape layers.', + ); + } + if (autoOrient) { + transform ??= AnimatableTransform(); + transform.isAutoOrient = autoOrient; + } + + return Layer( + shapes: shapes, + composition: composition, + name: layerName, + id: layerId, + layerType: layerType, + parentId: parentId, + refId: refId, + masks: masks, + transform: transform!, + solidWidth: solidWidth, + solidHeight: solidHeight, + solidColor: solidColor, + timeStretch: timeStretch, + startFrame: startFrame, + preCompWidth: preCompWidth, + preCompHeight: preCompHeight, + text: text, + textProperties: textProperties, + inOutKeyframes: inOutKeyframes, + matteType: matteType, + timeRemapping: timeRemapping, + isHidden: hidden, + blurEffect: blurEffect, + dropShadowEffect: dropShadowEffect, + blendMode: blendMode, + ); + } +} diff --git a/lottie/lib/src/parser/lottie_composition_parser.dart b/lottie/lib/src/parser/lottie_composition_parser.dart new file mode 100644 index 0000000..348cd35 --- /dev/null +++ b/lottie/lib/src/parser/lottie_composition_parser.dart @@ -0,0 +1,271 @@ +import '../composition.dart'; +import '../lottie_image_asset.dart'; +import '../model/font.dart'; +import '../model/font_character.dart'; +import '../model/layer/layer.dart'; +import '../model/marker.dart'; +import '../utils/misc.dart'; +import 'font_character_parser.dart'; +import 'font_parser.dart'; +import 'layer_parser.dart'; +import 'moshi/json_reader.dart'; + +class LottieCompositionParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'w', // 0 + 'h', // 1 + 'ip', // 2 + 'op', // 3 + 'fr', // 4 + 'v', // 5 + 'layers', // 6 + 'assets', // 7 + 'fonts', // 8 + 'chars', // 9 + 'markers', // 10 + ]); + + static LottieComposition parse( + LottieComposition composition, + JsonReader reader, + ) { + var parameters = CompositionParameters.forComposition(composition); + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + parameters.bounds.width = reader.nextDouble().toInt(); + case 1: + parameters.bounds.height = reader.nextDouble().toInt(); + case 2: + parameters.startFrame = reader.nextDouble(); + case 3: + parameters.endFrame = reader.nextDouble() - 0.01; + case 4: + parameters.frameRate = reader.nextDouble(); + case 5: + var version = reader.nextString(); + var versions = version.split('.'); + var majorVersion = int.parse(versions[0]); + var minorVersion = int.parse(versions[1]); + var patchVersion = int.parse(versions[2]); + if (!MiscUtils.isAtLeastVersion( + majorVersion, + minorVersion, + patchVersion, + 4, + 4, + 0, + )) { + composition.addWarning('Lottie only supports bodymovin >= 4.4.0'); + } + case 6: + _parseLayers( + reader, + composition, + parameters.layers, + parameters.layerMap, + ); + case 7: + _parseAssets( + reader, + composition, + parameters.precomps, + parameters.images, + ); + case 8: + _parseFonts(reader, parameters.fonts); + case 9: + _parseChars(reader, composition, parameters.characters); + case 10: + _parseMarkers(reader, composition, parameters.markers); + default: + reader.skipName(); + reader.skipValue(); + } + } + assert( + parameters.startFrame != parameters.endFrame, + 'startFrame == endFrame (${parameters.startFrame})', + ); + assert( + parameters.frameRate > 0, + 'invalid framerate: ${parameters.frameRate}', + ); + + return composition; + } + + static void _parseLayers( + JsonReader reader, + LottieComposition composition, + List layers, + Map layerMap, + ) { + var imageCount = 0; + reader.beginArray(); + while (reader.hasNext()) { + var layer = LayerParser.parseJson(reader, composition); + if (layer.layerType == LayerType.image) { + imageCount++; + } + layers.add(layer); + layerMap[layer.id] = layer; + } + if (imageCount > 4) { + composition.addWarning( + 'You have $imageCount images. Lottie should primarily be ' + 'used with shapes. If you are using Adobe Illustrator, convert the Illustrator layers' + ' to shape layers.', + ); + } + reader.endArray(); + } + + static final JsonReaderOptions _assetsNames = JsonReaderOptions.of([ + 'id', // 0 + 'layers', // 1 + 'w', // 2 + 'h', // 3 + 'p', // 4 + 'u', // 5 + ]); + + static void _parseAssets( + JsonReader reader, + LottieComposition composition, + Map> precomps, + Map images, + ) { + reader.beginArray(); + while (reader.hasNext()) { + late String id; + // For precomps + var layers = []; + var layerMap = {}; + // For images + var width = 0; + var height = 0; + String? imageFileName; + String? relativeFolder; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_assetsNames)) { + case 0: + id = reader.nextString(); + case 1: + reader.beginArray(); + while (reader.hasNext()) { + var layer = LayerParser.parseJson(reader, composition); + layerMap[layer.id] = layer; + layers.add(layer); + } + reader.endArray(); + case 2: + width = reader.nextInt(); + case 3: + height = reader.nextInt(); + case 4: + imageFileName = reader.nextString(); + case 5: + relativeFolder = reader.nextString(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + if (imageFileName != null) { + var image = LottieImageAsset( + width: width, + height: height, + id: id, + fileName: imageFileName, + dirName: relativeFolder ?? '', + ); + images[image.id] = image; + } else { + precomps[id] = layers; + } + } + reader.endArray(); + } + + static final JsonReaderOptions _fontNames = JsonReaderOptions.of(['list']); + + static void _parseFonts(JsonReader reader, Map fonts) { + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_fontNames)) { + case 0: + reader.beginArray(); + while (reader.hasNext()) { + var font = FontParser.parse(reader); + fonts[font.name] = font; + } + reader.endArray(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + } + + static void _parseChars( + JsonReader reader, + LottieComposition composition, + Map characters, + ) { + reader.beginArray(); + while (reader.hasNext()) { + var character = FontCharacterParser.parse(reader, composition); + characters[character.hashCode] = character; + } + reader.endArray(); + } + + static final JsonReaderOptions _markerNames = JsonReaderOptions.of([ + 'cm', + 'tm', + 'dr', + ]); + + static void _parseMarkers( + JsonReader reader, + LottieComposition composition, + List markers, + ) { + reader.beginArray(); + while (reader.hasNext()) { + String? comment; + var frame = 0.0; + var durationFrames = 0.0; + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_markerNames)) { + case 0: + comment = reader.nextString(); + case 1: + frame = reader.nextDouble(); + case 2: + durationFrames = reader.nextDouble(); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + markers.add( + Marker( + composition, + comment ?? '', + startFrame: frame, + durationFrames: durationFrames, + ), + ); + } + reader.endArray(); + } +} diff --git a/lottie/lib/src/parser/mask_parser.dart b/lottie/lib/src/parser/mask_parser.dart new file mode 100644 index 0000000..0a0782a --- /dev/null +++ b/lottie/lib/src/parser/mask_parser.dart @@ -0,0 +1,60 @@ +import '../composition.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/animatable/animatable_shape_value.dart'; +import '../model/content/mask.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class MaskParser { + MaskParser._(); + + static Mask parse(JsonReader reader, LottieComposition composition) { + late MaskMode maskMode; + late AnimatableShapeValue maskPath; + late AnimatableIntegerValue opacity; + var inverted = false; + + reader.beginObject(); + while (reader.hasNext()) { + var mode = reader.nextName(); + switch (mode) { + case 'mode': + var modeName = reader.nextString(); + switch (modeName) { + case 'a': + maskMode = MaskMode.maskModeAdd; + case 's': + maskMode = MaskMode.maskModeSubstract; + case 'n': + maskMode = MaskMode.maskModeNone; + case 'i': + composition.addWarning( + 'Animation contains intersect masks. They are not supported but will be treated like add masks.', + ); + maskMode = MaskMode.maskModeIntersect; + default: + composition.addWarning( + 'Unknown mask mode $modeName. Defaulting to Add.', + ); + maskMode = MaskMode.maskModeAdd; + } + case 'pt': + maskPath = AnimatableValueParser.parseShapeData(reader, composition); + case 'o': + opacity = AnimatableValueParser.parseInteger(reader, composition); + case 'inv': + inverted = reader.nextBoolean(); + default: + reader.skipValue(); + } + } + reader.endObject(); + + return Mask( + maskMode: maskMode, + maskPath: maskPath, + opacity: opacity, + isInverted: inverted, + ); + } +} diff --git a/lottie/lib/src/parser/merge_paths_parser.dart b/lottie/lib/src/parser/merge_paths_parser.dart new file mode 100644 index 0000000..e7a6955 --- /dev/null +++ b/lottie/lib/src/parser/merge_paths_parser.dart @@ -0,0 +1,34 @@ +import '../model/content/merge_paths.dart'; +import 'moshi/json_reader.dart'; + +class MergePathsParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'mm', + 'hd', + ]); + + MergePathsParser._(); + + static MergePaths parse(JsonReader reader) { + String? name; + late MergePathsMode mode; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + mode = MergePaths.modeForId(reader.nextInt()); + case 2: + hidden = reader.nextBoolean(); + default: + reader.skipName(); + reader.skipValue(); + } + } + + return MergePaths(name: name ?? '', mode: mode, hidden: hidden); + } +} diff --git a/lottie/lib/src/parser/moshi/buffer.dart b/lottie/lib/src/parser/moshi/buffer.dart new file mode 100644 index 0000000..55e5c81 --- /dev/null +++ b/lottie/lib/src/parser/moshi/buffer.dart @@ -0,0 +1,216 @@ +import 'dart:convert'; +import 'dart:math'; + +class Buffer { + Buffer(this.buffer); + + final List buffer; + int _start = 0, _size = 0; + int get size => _size; + + static void _checkOffsetAndCount(int size, int offset, int byteCount) { + if ((offset | byteCount) < 0 || + offset > size || + size - offset < byteCount) { + throw Exception('size=$size offset=$offset byteCount=$byteCount'); + } + } + + /// Removes all bytes from this, decodes them as UTF-8, and returns the string. Returns the empty + /// string if this source is empty.

{@code
+  ///
+  ///   Buffer buffer = new Buffer()
+  ///       .writeUtf8("Uh uh uh!")
+  ///       .writeByte(' ')
+  ///       .writeUtf8("You didn't say the magic word!");
+  ///
+  ///   assertEquals("Uh uh uh! You didn't say the magic word!", buffer.readUtf8());
+  ///   assertEquals(0, buffer.size());
+  ///
+  ///   assertEquals("", buffer.readUtf8());
+  ///   assertEquals(0, buffer.size());
+  /// }
+ String readUtf8(int byteCount) { + if (_size < byteCount) throw Exception('size < $byteCount: $_size'); + + var string = utf8.decoder.convert(buffer, _start, _start + byteCount); + _start += byteCount; + _size -= byteCount; + return string; + } + + /// Removes a byte from this source and returns it. + int readByte() { + if (_size == 0) throw Exception('size == 0'); + + var byte = buffer[_start++]; + --_size; + return byte; + } + + /// Returns true when the buffer contains at least {@code byteCount} bytes, expanding it as + /// necessary. Returns false if the source is exhausted before the requested bytes can be read. + bool request(int byteCount) { + if (_start + byteCount > buffer.length) { + _size = buffer.length - _start; + return false; + } + _size = max(byteCount, _size); + return true; + } + + /// Returns the byte at {@code pos}. */ + int getByte(int pos) { + _checkOffsetAndCount(_size, pos, 1); + return buffer[_start + pos]; + } + + /// Reads and discards {@code byteCount} bytes from this source. Throws an + /// [Exception] if the source is exhausted before the + /// requested bytes can be skipped. + void skip(int byteCount) { + _start += byteCount; + if (_start >= buffer.length) { + _start = buffer.length - 1; + throw Exception('source is exhausted'); + } + + _size -= byteCount; + _size = max(0, _size); + } + + /// Finds the first string in {@code options} that is a prefix of this buffer, consumes it from + /// this buffer, and returns its index. If no byte string in {@code options} is a prefix of this + /// buffer this returns -1 and no bytes are consumed. + /// + ///

This can be used as an alternative to {@link #readByteString} or even {@link #readUtf8} if + /// the set of expected values is known in advance.

{@code
+  ///
+  ///   Options FIELDS = Options.of(
+  ///       ByteString.encodeUtf8("depth="),
+  ///       ByteString.encodeUtf8("height="),
+  ///       ByteString.encodeUtf8("width="));
+  ///
+  ///   Buffer buffer = new Buffer()
+  ///       .writeUtf8("width=640\n")
+  ///       .writeUtf8("height=480\n");
+  ///
+  ///   assertEquals(2, buffer.select(FIELDS));
+  ///   assertEquals(640, buffer.readDecimalLong());
+  ///   assertEquals('\n', buffer.readByte());
+  ///   assertEquals(1, buffer.select(FIELDS));
+  ///   assertEquals(480, buffer.readDecimalLong());
+  ///   assertEquals('\n', buffer.readByte());
+  /// }
+ int select(List> options) { + var index = _selectPrefix(options); + if (index == -1) return -1; + + var size = options[index].length; + skip(size); + return index; + } + + int _selectPrefix(List> options) { + for (var i = 0; i < options.length; i++) { + var option = options[i]; + if (_isPrefix(option, buffer, _start)) { + return i; + } + } + return -1; + } + + static bool _isPrefix(List search, List buffer, int start) { + for (var i = 0; i < search.length; i++) { + if (search[i] != buffer[start + i]) { + return false; + } + } + return true; + } + + /// Returns the first index in this buffer that is at or after {@code fromIndex} and that contains + /// any of the bytes in {@code targetBytes}. This expands the buffer as necessary until a target + /// byte is found. This reads an unbounded number of bytes into the buffer. Returns -1 if the + /// stream is exhausted before the requested byte is found.
{@code
+  ///
+  ///   ByteString ANY_VOWEL = ByteString.encodeUtf8("AEOIUaeoiu");
+  ///
+  ///   Buffer buffer = new Buffer();
+  ///   buffer.writeUtf8("Dr. Alan Grant");
+  ///
+  ///   assertEquals(4,  buffer.indexOfElement(ANY_VOWEL));    // 'A' in 'Alan'.
+  ///   assertEquals(11, buffer.indexOfElement(ANY_VOWEL, 9)); // 'a' in 'Grant'.
+  /// }
+ int indexOfElement(List targetBytes, int fromIndex) { + var i = fromIndex; + while (_start + i < buffer.length) { + _size = max(i + 1, _size); + + var bufferByte = buffer[_start + i]; + for (var targetByte in targetBytes) { + if (targetByte == bufferByte) { + return i; + } + } + ++i; + } + return -1; + } + + /// Returns the index of the first {@code b} in the buffer at or after {@code fromIndex}. This + /// expands the buffer as necessary until {@code b} is found. This reads an unbounded number of + /// bytes into the buffer. Returns -1 if the stream is exhausted before the requested byte is + /// found.
{@code
+  ///
+  ///   Buffer buffer = new Buffer();
+  ///   buffer.writeUtf8("Don't move! He can't see us if we don't move.");
+  ///
+  ///   byte m = 'm';
+  ///   assertEquals(6,  buffer.indexOf(m));
+  ///   assertEquals(40, buffer.indexOf(m, 12));
+  /// }
+ int indexOf(int b, int fromIndex) { + var i = fromIndex; + while (_start + i < buffer.length) { + _size = max(i + 1, _size); + + var bufferByte = buffer[_start + i]; + if (b == bufferByte) { + return i; + } + + ++i; + } + return -1; + } + + /// Returns the index of the first match for {@code bytes} in the buffer at or after {@code + /// fromIndex}. This expands the buffer as necessary until {@code bytes} is found. This reads an + /// unbounded number of bytes into the buffer. Returns -1 if the stream is exhausted before the + /// requested bytes are found.
{@code
+  ///
+  ///   ByteString MOVE = ByteString.encodeUtf8("move");
+  ///
+  ///   Buffer buffer = new Buffer();
+  ///   buffer.writeUtf8("Don't move! He can't see us if we don't move.");
+  ///
+  ///   assertEquals(6,  buffer.indexOf(MOVE));
+  ///   assertEquals(40, buffer.indexOf(MOVE, 12));
+  /// }
+ int indexOfBytes(List bytes, int fromIndex) { + var i = fromIndex; + while (_start + i < buffer.length) { + _size = max(i + 1, _size); + + if (_isPrefix(bytes, buffer, _start + i)) { + return i; + } + ++i; + } + return -1; + } + + void clear() {} +} diff --git a/lottie/lib/src/parser/moshi/charcode.dart b/lottie/lib/src/parser/moshi/charcode.dart new file mode 100644 index 0000000..a395850 --- /dev/null +++ b/lottie/lib/src/parser/moshi/charcode.dart @@ -0,0 +1,465 @@ +// Control characters. + +/// "Null character" control character. +const int $nul = 0x00; + +/// "Start of Header" control character. +const int $soh = 0x01; + +/// "Start of Text" control character. +const int $stx = 0x02; + +/// "End of Text" control character. +const int $etx = 0x03; + +/// "End of Transmission" control character. +const int $eot = 0x04; + +/// "Enquiry" control character. +const int $enq = 0x05; + +/// "Acknowledgment" control character. +const int $ack = 0x06; + +/// "Bell" control character. +const int $bel = 0x07; + +/// "Backspace" control character. +const int $bs = 0x08; + +/// "Horizontal Tab" control character. +const int $ht = 0x09; + +/// "Horizontal Tab" control character, common name. +const int $tab = 0x09; + +/// "Line feed" control character. +const int $lf = 0x0A; + +/// "Vertical Tab" control character. +const int $vt = 0x0B; + +/// "Form feed" control character. +const int $ff = 0x0C; + +/// "Carriage return" control character. +const int $cr = 0x0D; + +/// "Shift Out" control character. +const int $so = 0x0E; + +/// "Shift In" control character. +const int $si = 0x0F; + +/// "Data Link Escape" control character. +const int $dle = 0x10; + +/// "Device Control 1" control character (oft. XON). +const int $dc1 = 0x11; + +/// "Device Control 2" control character. +const int $dc2 = 0x12; + +/// "Device Control 3" control character (oft. XOFF). +const int $dc3 = 0x13; + +/// "Device Control 4" control character. +const int $dc4 = 0x14; + +/// "Negative Acknowledgment" control character. +const int $nak = 0x15; + +/// "Synchronous idle" control character. +const int $syn = 0x16; + +/// "End of Transmission Block" control character. +const int $etb = 0x17; + +/// "Cancel" control character. +const int $can = 0x18; + +/// "End of Medium" control character. +const int $em = 0x19; + +/// "Substitute" control character. +const int $sub = 0x1A; + +/// "Escape" control character. +const int $esc = 0x1B; + +/// "File Separator" control character. +const int $fs = 0x1C; + +/// "Group Separator" control character. +const int $gs = 0x1D; + +/// "Record Separator" control character. +const int $rs = 0x1E; + +/// "Unit Separator" control character. +const int $us = 0x1F; + +/// "Delete" control character. +const int $del = 0x7F; + +// Visible characters. + +/// Space character. +const int $space = 0x20; + +/// Character `!`. +const int $exclamation = 0x21; + +/// Character `"', short nam`. +const int $quot = 0x22; + +/// Character `"`. +const int $quote = 0x22; + +/// Character `"`. +const int $doubleQuote = 0x22; + +/// Character `"`. +const int $quotation = 0x22; + +/// Character `#`. +const int $hash = 0x23; + +/// Character `$`. +const int $$ = 0x24; + +/// Character `$`. +const int $dollar = 0x24; + +/// Character `%`. +const int $percent = 0x25; + +/// Character `&`, short name. +const int $amp = 0x26; + +/// Character `&`. +const int $ampersand = 0x26; + +/// Character `'`. +const int $apos = 0x27; + +/// Character `'`. +const int $apostrophe = 0x27; + +/// Character `'`. +const int $singleQuote = 0x27; + +/// Character `(`. +const int $lparen = 0x28; + +/// Character `(`. +const int $openParen = 0x28; + +/// Character `(`. +const int $openParenthesis = 0x28; + +/// Character `)`. +const int $rparen = 0x29; + +/// Character `)`. +const int $closeParen = 0x29; + +/// Character `)`. +const int $closeParenthesis = 0x29; + +/// Character `*`. +const int $asterisk = 0x2A; + +/// Character `+`. +const int $plus = 0x2B; + +/// Character `,`. +const int $comma = 0x2C; + +/// Character `-`. +const int $minus = 0x2D; + +/// Character `-`. +const int $dash = 0x2D; + +/// Character `.`. +const int $dot = 0x2E; + +/// Character `.`. +const int $fullstop = 0x2E; + +/// Character `/`. +const int $slash = 0x2F; + +/// Character `/`. +const int $solidus = 0x2F; + +/// Character `/`. +const int $division = 0x2F; + +/// Character `0`. +const int $0 = 0x30; + +/// Character `1`. +const int $1 = 0x31; + +/// Character `2`. +const int $2 = 0x32; + +/// Character `3`. +const int $3 = 0x33; + +/// Character `4`. +const int $4 = 0x34; + +/// Character `5`. +const int $5 = 0x35; + +/// Character `6`. +const int $6 = 0x36; + +/// Character `7`. +const int $7 = 0x37; + +/// Character `8`. +const int $8 = 0x38; + +/// Character `9`. +const int $9 = 0x39; + +/// Character `:`. +const int $colon = 0x3A; + +/// Character `;`. +const int $semicolon = 0x3B; + +/// Character `<`. +const int $lt = 0x3C; + +/// Character `<`. +const int $lessThan = 0x3C; + +/// Character `<`. +const int $langle = 0x3C; + +/// Character `<`. +const int $openAngle = 0x3C; + +/// Character `=`. +const int $equal = 0x3D; + +/// Character `>`. +const int $gt = 0x3E; + +/// Character `>`. +const int $greaterThan = 0x3E; + +/// Character `>`. +const int $rangle = 0x3E; + +/// Character `>`. +const int $closeAngle = 0x3E; + +/// Character `?`. +const int $question = 0x3F; + +/// Character `@`. +const int $at = 0x40; + +/// Character `A`. +const int $A = 0x41; + +/// Character `B`. +const int $B = 0x42; + +/// Character `C`. +const int $C = 0x43; + +/// Character `D`. +const int $D = 0x44; + +/// Character `E`. +const int $E = 0x45; + +/// Character `F`. +const int $F = 0x46; + +/// Character `G`. +const int $G = 0x47; + +/// Character `H`. +const int $H = 0x48; + +/// Character `I`. +const int $I = 0x49; + +/// Character `J`. +const int $J = 0x4A; + +/// Character `K`. +const int $K = 0x4B; + +/// Character `L`. +const int $L = 0x4C; + +/// Character `M`. +const int $M = 0x4D; + +/// Character `N`. +const int $N = 0x4E; + +/// Character `O`. +const int $O = 0x4F; + +/// Character `P`. +const int $P = 0x50; + +/// Character `Q`. +const int $Q = 0x51; + +/// Character `R`. +const int $R = 0x52; + +/// Character `S`. +const int $S = 0x53; + +/// Character `T`. +const int $T = 0x54; + +/// Character `U`. +const int $U = 0x55; + +/// Character `V`. +const int $V = 0x56; + +/// Character `W`. +const int $W = 0x57; + +/// Character `X`. +const int $X = 0x58; + +/// Character `Y`. +const int $Y = 0x59; + +/// Character `Z`. +const int $Z = 0x5A; + +/// Character `[`. +const int $lbracket = 0x5B; + +/// Character `[`. +const int $openBracket = 0x5B; + +/// Character `\`. +const int $backslash = 0x5C; + +/// Character `]`. +const int $rbracket = 0x5D; + +/// Character `]`. +const int $closeBracket = 0x5D; + +/// Character `^`. +const int $circumflex = 0x5E; + +/// Character `^`. +const int $caret = 0x5E; + +/// Character `^`. +const int $hat = 0x5E; + +/// Character `_`. +const int $underscore = 0x5F; + +/// Character `_`. +const int $underline = 0x5F; + +/// Character `` ` ``. +const int $backquote = 0x60; + +/// Character `` ` ``. +const int $grave = 0x60; + +/// Character `a`. +const int $a = 0x61; + +/// Character `b`. +const int $b = 0x62; + +/// Character `c`. +const int $c = 0x63; + +/// Character `d`. +const int $d = 0x64; + +/// Character `e`. +const int $e = 0x65; + +/// Character `f`. +const int $f = 0x66; + +/// Character `g`. +const int $g = 0x67; + +/// Character `h`. +const int $h = 0x68; + +/// Character `i`. +const int $i = 0x69; + +/// Character `j`. +const int $j = 0x6A; + +/// Character `k`. +const int $k = 0x6B; + +/// Character `l`. +const int $l = 0x6C; + +/// Character `m`. +const int $m = 0x6D; + +/// Character `n`. +const int $n = 0x6E; + +/// Character `o`. +const int $o = 0x6F; + +/// Character `p`. +const int $p = 0x70; + +/// Character `q`. +const int $q = 0x71; + +/// Character `r`. +const int $r = 0x72; + +/// Character `s`. +const int $s = 0x73; + +/// Character `t`. +const int $t = 0x74; + +/// Character `u`. +const int $u = 0x75; + +/// Character `v`. +const int $v = 0x76; + +/// Character `w`. +const int $w = 0x77; + +/// Character `x`. +const int $x = 0x78; + +/// Character `y`. +const int $y = 0x79; + +/// Character `z`. +const int $z = 0x7A; + +/// Character `{`. +const int $openBrace = 0x7B; + +/// Character `}`. +const int $closeBrace = 0x7D; diff --git a/lottie/lib/src/parser/moshi/json_reader.dart b/lottie/lib/src/parser/moshi/json_reader.dart new file mode 100644 index 0000000..ac31447 --- /dev/null +++ b/lottie/lib/src/parser/moshi/json_reader.dart @@ -0,0 +1,354 @@ +import 'dart:convert'; +import 'buffer.dart'; +import 'json_scope.dart'; +import 'json_utf8_reader.dart'; + +// ignore_for_file: unintended_html_in_doc_comment + +/// Reads a JSON (
RFC 7159) +/// encoded value as a stream of tokens. This stream includes both literal +/// values (strings, numbers, booleans, and nulls) as well as the begin and +/// end delimiters of objects and arrays. The tokens are traversed in +/// depth-first order, the same order that they appear in the JSON document. +/// Within JSON objects, name/value pairs are represented by a single token. +/// +///

Parsing JSON

+/// To create a recursive descent parser for your own JSON streams, first create +/// an entry point method that creates a {@code JsonReader}. +/// +///

Next, create handler methods for each structure in your JSON text. You'll +/// need a method for each object type and for each array type. +///

    +///
  • Within array handling methods, first call {@link +/// #beginArray} to consume the array's opening bracket. Then create a +/// while loop that accumulates values, terminating when {@link #hasNext} +/// is false. Finally, read the array's closing bracket by calling {@link +/// #endArray}. +///
  • Within object handling methods, first call {@link +/// #beginObject} to consume the object's opening brace. Then create a +/// while loop that assigns values to local variables based on their name. +/// This loop should terminate when {@link #hasNext} is false. Finally, +/// read the object's closing brace by calling {@link #endObject}. +///
+///

When a nested object or array is encountered, delegate to the +/// corresponding handler method. +/// +///

When an unknown name is encountered, strict parsers should fail with an +/// exception. Lenient parsers should call {@link #skipValue()} to recursively +/// skip the value's nested tokens, which may otherwise conflict. +/// +///

If a value may be null, you should first check using {@link #peek()}. +/// Null literals can be consumed using either {@link #nextNull()} or {@link +/// #skipValue()}. +/// +///

Example

+/// Suppose we'd like to parse a stream of messages such as the following:
 {@code
+/// [
+///   {
+///     "id": 912345678901,
+///     "text": "How do I read a JSON stream in Java?",
+///     "geo": null,
+///     "user": {
+///       "name": "json_newb",
+///       "followers_count": 41
+///      }
+///   },
+///   {
+///     "id": 912345678902,
+///     "text": "@json_newb just use JsonReader!",
+///     "geo": [50.454722, -104.606667],
+///     "user": {
+///       "name": "jesse",
+///       "followers_count": 2
+///     }
+///   }
+/// ]}
+/// This code implements the parser for the above structure:
   {@code
+///
+///   public List readJsonStream(BufferedSource source) throws IOException {
+///     JsonReader reader = JsonReader.of(source);
+///     try {
+///       return readMessagesArray(reader);
+///     } finally {
+///       reader.close();
+///     }
+///   }
+///
+///   public List readMessagesArray(JsonReader reader) throws IOException {
+///     List messages = new ArrayList();
+///
+///     reader.beginArray();
+///     while (reader.hasNext()) {
+///       messages.add(readMessage(reader));
+///     }
+///     reader.endArray();
+///     return messages;
+///   }
+///
+///   public Message readMessage(JsonReader reader) throws IOException {
+///     long id = -1;
+///     String text = null;
+///     User user = null;
+///     List geo = null;
+///
+///     reader.beginObject();
+///     while (reader.hasNext()) {
+///       String name = reader.nextName();
+///       if (name.equals("id")) {
+///         id = reader.nextLong();
+///       } else if (name.equals("text")) {
+///         text = reader.nextString();
+///       } else if (name.equals("geo") && reader.peek() != Token.NULL) {
+///         geo = readDoublesArray(reader);
+///       } else if (name.equals("user")) {
+///         user = readUser(reader);
+///       } else {
+///         reader.skipValue();
+///       }
+///     }
+///     reader.endObject();
+///     return new Message(id, text, user, geo);
+///   }
+///
+///   public List readDoublesArray(JsonReader reader) throws IOException {
+///     List doubles = new ArrayList();
+///
+///     reader.beginArray();
+///     while (reader.hasNext()) {
+///       doubles.add(reader.nextDouble());
+///     }
+///     reader.endArray();
+///     return doubles;
+///   }
+///
+///   public User readUser(JsonReader reader) throws IOException {
+///     String username = null;
+///     int followersCount = -1;
+///
+///     reader.beginObject();
+///     while (reader.hasNext()) {
+///       String name = reader.nextName();
+///       if (name.equals("name")) {
+///         username = reader.nextString();
+///       } else if (name.equals("followers_count")) {
+///         followersCount = reader.nextInt();
+///       } else {
+///         reader.skipValue();
+///       }
+///     }
+///     reader.endObject();
+///     return new User(username, followersCount);
+///   }}
+/// +///

Number Handling

+/// This reader permits numeric values to be read as strings and string values to +/// be read as numbers. For example, both elements of the JSON array {@code +/// [1, "1"]} may be read using either {@link #nextInt} or {@link #nextString}. +/// This behavior is intended to prevent lossy numeric conversions: double is +/// JavaScript's only numeric type and very large values like {@code +/// 9007199254740993} cannot be represented exactly on that platform. To minimize +/// precision loss, extremely large values should be written and read as strings +/// in JSON. +/// +///

Each {@code JsonReader} may be used to read a single JSON stream. Instances +/// of this class are not thread safe. +abstract class JsonReader { + // The nesting stack. Using a manual array rather than an ArrayList saves 20%. This stack will + // grow itself up to 256 levels of nesting including the top-level document. Deeper nesting is + // prone to trigger StackOverflowErrors. + int stackSize = 0; + List scopes = List.filled(32, 0); + List pathNames = List.filled(32, null); + List pathIndices = List.filled(32, 0); + + /// True to accept non-spec compliant JSON. + bool lenient = false; + + /// True to throw a {@link JsonDataException} on any attempt to call {@link #skipValue()}. + bool failOnUnknown = false; + + /// Returns a new instance that reads UTF-8 encoded JSON from {@code source}. + static JsonReader fromBytes(List source) { + return JsonUtf8Reader(Buffer(source)); + } + + static List _copyOf(List source, int newSize, T fill) { + var newList = List.filled(newSize, fill); + List.copyRange(newList, 0, source); + return newList; + } + + void pushScope(int newTop) { + if (stackSize == scopes.length) { + if (stackSize == 256) { + throw JsonDataException('Nesting too deep at ${getPath()}'); + } + scopes = _copyOf(scopes, scopes.length * 2, 0); + pathNames = _copyOf(pathNames, pathNames.length * 2, null); + pathIndices = _copyOf(pathIndices, pathIndices.length * 2, 0); + } + scopes[stackSize++] = newTop; + } + + /// Throws a new IO exception with the given message and a context snippet + /// with this reader's content. + JsonEncodingException syntaxError(String message) { + throw JsonEncodingException('$message at path ${getPath()}'); + } + + /// Consumes the next token from the JSON stream and asserts that it is the beginning of a new + /// array. + void beginArray(); + + /// Consumes the next token from the JSON stream and asserts that it is the + /// end of the current array. + void endArray(); + + /// Consumes the next token from the JSON stream and asserts that it is the beginning of a new + /// object. + void beginObject(); + + /// Consumes the next token from the JSON stream and asserts that it is the end of the current + /// object. + void endObject(); + + /// Returns true if the current array or object has another element. + bool hasNext(); + + /// Returns the type of the next token without consuming it. + Token peek(); + + /// Returns the next token, a {@linkplain Token#NAME property name}, and consumes it. + /// + /// @throws JsonDataException if the next token in the stream is not a property name. + String nextName(); + + /// If the next token is a {@linkplain Token#NAME property name} that's in {@code options}, this + /// consumes it and returns its index. Otherwise this returns -1 and no name is consumed. + int selectName(JsonReaderOptions options); + + /// Skips the next token, consuming it. This method is intended for use when the JSON token stream + /// contains unrecognized or unhandled names. + /// + ///

This throws a {@link JsonDataException} if this parser has been configured to {@linkplain + /// #failOnUnknown fail on unknown} names. + void skipName(); + + /// Returns the {@linkplain Token#STRING string} value of the next token, consuming it. If the next + /// token is a number, this method will return its string form. + /// + /// @throws JsonDataException if the next token is not a string or if this reader is closed. + String nextString(); + + /// Returns the {@linkplain Token#BOOLEAN boolean} value of the next token, consuming it. + /// + /// @throws JsonDataException if the next token is not a boolean or if this reader is closed. + bool nextBoolean(); + + /// Returns the {@linkplain Token#NUMBER double} value of the next token, consuming it. If the next + /// token is a string, this method will attempt to parse it as a double using {@link + /// Double#parseDouble(String)}. + /// + /// @throws JsonDataException if the next token is not a literal value, or if the next literal + /// value cannot be parsed as a double, or is non-finite. + double nextDouble(); + + /// Returns the {@linkplain Token#NUMBER int} value of the next token, consuming it. If the next + /// token is a string, this method will attempt to parse it as an int. If the next token's numeric + /// value cannot be exactly represented by a Java {@code int}, this method throws. + /// + /// @throws JsonDataException if the next token is not a literal value, if the next literal value + /// cannot be parsed as a number, or exactly represented as an int. + int nextInt(); + + /// Skips the next value recursively. If it is an object or array, all nested elements are skipped. + /// This method is intended for use when the JSON token stream contains unrecognized or unhandled + /// values. + /// + ///

This throws a {@link JsonDataException} if this parser has been configured to {@linkplain + /// #failOnUnknown fail on unknown} values. + void skipValue(); + + /// Returns a JsonPath to + /// the current location in the JSON value. + String getPath() { + return JsonScope.getPath(stackSize, scopes, pathNames, pathIndices); + } + + void close(); +} + +/// A set of strings to be chosen with {@link #selectName} or {@link #selectString}. This prepares +/// the encoded values of the strings so they can be read directly from the input source. +class JsonReaderOptions { + final List strings; + final List> doubleQuoteSuffix; + + JsonReaderOptions(this.strings, this.doubleQuoteSuffix); + + static JsonReaderOptions of(List strings) { + return JsonReaderOptions( + strings, + strings.map((s) => utf8.encode('$s"')).toList(), + ); + } +} + +/// A structure, name, or value type in a JSON-encoded string. +enum Token { + /// The opening of a JSON array. + /// and read using {@link JsonReader#beginArray}. + beginArray, + + /// The closing of a JSON array. + /// and read using {@link JsonReader#endArray}. + endArray, + + /// The opening of a JSON object. + /// and read using {@link JsonReader#beginObject}. + beginObject, + + /// The closing of a JSON object. + /// and read using {@link JsonReader#endObject}. + endObject, + + /// A JSON property name. Within objects, tokens alternate between names and + /// their values. + name, + + /// A JSON string. + string, + + /// A JSON number represented in this API by a Java {@code double}, {@code + /// long}, or {@code int}. + number, + + /// A JSON {@code true} or {@code false}. + boolean, + + /// A JSON {@code null}. + nullToken, + + /// The end of the JSON stream. This sentinel value is returned by {@link + /// JsonReader#peek()} to signal that the JSON-encoded value has no more + /// tokens. + endDocument, +} + +class JsonDataException implements Exception { + final String message; + + JsonDataException(this.message); + + @override + String toString() => message; +} + +class JsonEncodingException implements Exception { + final String message; + + JsonEncodingException(this.message); + + @override + String toString() => message; +} diff --git a/lottie/lib/src/parser/moshi/json_scope.dart b/lottie/lib/src/parser/moshi/json_scope.dart new file mode 100644 index 0000000..e6e9933 --- /dev/null +++ b/lottie/lib/src/parser/moshi/json_scope.dart @@ -0,0 +1,67 @@ +/// Lexical scoping elements within a JSON reader or writer. */ +class JsonScope { + JsonScope._(); + + /// An array with no elements requires no separators or newlines before it is closed. */ + static const int emptyArray = 1; + + /// A array with at least one value requires a comma and newline before the next element. */ + static const int nonEmptyArray = 2; + + /// An object with no name/value pairs requires no separators or newlines before it is closed. */ + static const int emptyObject = 3; + + /// An object whose most recent element is a key. The next element must be a value. */ + static const int danglingName = 4; + + /// An object with at least one name/value pair requires a separator before the next element. */ + static const int nonEmptyObject = 5; + + /// No object or array has been started. */ + static const int emptyDocument = 6; + + /// A document with at an array or object. */ + static const int nonEmptyDocument = 7; + + /// A document that's been closed and cannot be accessed. */ + static const int closed = 8; + + /// Renders the path in a JSON document to a string. The {@code pathNames} and {@code pathIndices} + /// parameters corresponds directly to stack: At indices where the stack contains an object + /// (EMPTY_OBJECT, DANGLING_NAME or NONEMPTY_OBJECT), pathNames contains the name at this scope. + /// Where it contains an array (EMPTY_ARRAY, NONEMPTY_ARRAY) pathIndices contains the current index + /// in that array. Otherwise the value is undefined, and we take advantage of that by incrementing + /// pathIndices when doing so isn't useful. + static String getPath( + int stackSize, + List stack, + List pathNames, + List pathIndices, + ) { + var result = StringBuffer()..write(r'$'); + for (var i = 0; i < stackSize; i++) { + switch (stack[i]) { + case emptyArray: + case nonEmptyArray: + result + ..write('[') + ..write(pathIndices[i]) + ..write(']'); + + case emptyObject: + case danglingName: + case nonEmptyObject: + result.write('.'); + if (pathNames[i] != null) { + result.write(pathNames[i]); + } + + case nonEmptyDocument: + case emptyDocument: + case closed: + break; + } + } + return result.toString(); + } +} diff --git a/lottie/lib/src/parser/moshi/json_utf8_reader.dart b/lottie/lib/src/parser/moshi/json_utf8_reader.dart new file mode 100644 index 0000000..2963283 --- /dev/null +++ b/lottie/lib/src/parser/moshi/json_utf8_reader.dart @@ -0,0 +1,1034 @@ +import 'dart:convert'; +import 'dart:core'; +import 'buffer.dart'; +import 'charcode.dart'; +import 'json_reader.dart'; +import 'json_scope.dart'; + +class JsonUtf8Reader extends JsonReader { + static const int longMinValue = -9007199254740991; + + static const minIncompleteInteger = longMinValue ~/ 10; + + static final List singleQuoteOrSlash = utf8.encode(r"'\"); + static final List doubleQuoteOrSlash = utf8.encode(r'"\'); + static final List unquotedStringTerminals = utf8.encode( + '{}[]:, \n\t\r\f/\\;#=', + ); + static final List lineFeedOrCarriageReturn = utf8.encode('\n\r'); + static final List closingBlockComment = utf8.encode('*/'); + + static const int peekedNone = 0; + static const int peekedBeginObject = 1; + static const int peekedEndObject = 2; + static const int peekedBeginArray = 3; + static const int peekedEndArray = 4; + static const int peekedTrue = 5; + static const int peekedFalse = 6; + static const int peekedNull = 7; + static const int peekedSingleQuote = 8; + static const int peekedDoubleQuote = 9; + static const int peekedUnquoted = 10; + + /// When this is returned, the string value is stored in peekedString. */ + static const int peekedBuffered = 11; + static const int peekedSingleQuotedName = 12; + static const int peekedDoubleQuotedName = 13; + static const int peekedUnquotedName = 14; + static const int peekedBufferedName = 15; + + /// When this is returned, the integer value is stored in peekedLong. */ + static const int peekedLong = 16; + static const int peekedNumber = 17; + static const int peekedEof = 18; + + // State machine when parsing numbers + static const int numberCharNone = 0; + static const int numberCharSign = 1; + static const int numberCharDigit = 2; + static const int numberCharDecimal = 3; + static const int numberCharFractionDigit = 4; + static const int numberCharExpE = 5; + static const int numberCharExpSign = 6; + static const int numberCharExpDigit = 7; + + /// The input JSON. */ + final Buffer buffer; + + int _peeked = peekedNone; + + /// A peeked value that was composed entirely of digits with an optional + /// leading dash. Positive values may not have a leading 0. + late int _peekedLong; + + /// The number of characters in a peeked number literal. + late int _peekedNumberLength; + + /// A peeked string that should be parsed on the next double, long or string. + /// This is populated before a numeric value is parsed and used if that parsing + /// fails. + String? _peekedString; + + JsonUtf8Reader(this.buffer) { + pushScope(JsonScope.emptyDocument); + } + + @override + void beginArray() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p == peekedBeginArray) { + pushScope(JsonScope.emptyArray); + pathIndices[stackSize - 1] = 0; + _peeked = peekedNone; + } else { + throw JsonDataException( + 'Expected BEGIN_ARRAY but was ${peek()} at path ${getPath()}', + ); + } + } + + @override + void endArray() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p == peekedEndArray) { + stackSize--; + pathIndices[stackSize - 1]++; + _peeked = peekedNone; + } else { + throw JsonDataException( + 'Expected END_ARRAY but was ${peek()} at path ${getPath()}', + ); + } + } + + @override + void beginObject() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p == peekedBeginObject) { + pushScope(JsonScope.emptyObject); + _peeked = peekedNone; + } else { + throw JsonDataException( + 'Expected BEGIN_OBJECT but was ${peek()} at path ${getPath()}', + ); + } + } + + @override + void endObject() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p == peekedEndObject) { + stackSize--; + pathNames[stackSize] = + null; // Free the last path name so that it can be garbage collected! + pathIndices[stackSize - 1]++; + _peeked = peekedNone; + } else { + throw JsonDataException( + 'Expected END_OBJECT but was ${peek()} at path ${getPath()}', + ); + } + } + + @override + bool hasNext() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + return p != peekedEndObject && p != peekedEndArray && p != peekedEof; + } + + @override + Token peek() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + + switch (p) { + case peekedBeginObject: + return Token.beginObject; + case peekedEndObject: + return Token.endObject; + case peekedBeginArray: + return Token.beginArray; + case peekedEndArray: + return Token.endArray; + case peekedSingleQuotedName: + case peekedDoubleQuotedName: + case peekedUnquotedName: + case peekedBufferedName: + return Token.name; + case peekedTrue: + case peekedFalse: + return Token.boolean; + case peekedNull: + return Token.nullToken; + case peekedSingleQuote: + case peekedDoubleQuote: + case peekedUnquoted: + case peekedBuffered: + return Token.string; + case peekedLong: + case peekedNumber: + return Token.number; + case peekedEof: + return Token.endDocument; + default: + throw AssertionError(); + } + } + + int _doPeek() { + var peekStack = scopes[stackSize - 1]; + if (peekStack == JsonScope.emptyArray) { + scopes[stackSize - 1] = JsonScope.nonEmptyArray; + } else if (peekStack == JsonScope.nonEmptyArray) { + // Look for a comma before the next element. + var c = _nextNonWhitespace(true); + buffer.readByte(); // consume ']' or ','. + switch (c) { + case $closeBracket: + return _peeked = peekedEndArray; + case $semicolon: + _checkLenient(); + case $comma: + break; + default: + throw syntaxError('Unterminated array'); + } + } else if (peekStack == JsonScope.emptyObject || + peekStack == JsonScope.nonEmptyObject) { + scopes[stackSize - 1] = JsonScope.danglingName; + // Look for a comma before the next element. + if (peekStack == JsonScope.nonEmptyObject) { + var c = _nextNonWhitespace(true); + buffer.readByte(); // Consume '}' or ','. + switch (c) { + case $closeBrace: + return _peeked = peekedEndObject; + case $semicolon: + _checkLenient(); // fall-through + case $comma: + break; + default: + throw syntaxError('Unterminated object'); + } + } + var c = _nextNonWhitespace(true); + switch (c) { + case $doubleQuote: + buffer.readByte(); // consume the '\"'. + return _peeked = peekedDoubleQuotedName; + case $singleQuote: + buffer.readByte(); // consume the '\''. + _checkLenient(); + return _peeked = peekedSingleQuotedName; + case $closeBrace: + if (peekStack != JsonScope.nonEmptyObject) { + buffer.readByte(); // consume the '}'. + return _peeked = peekedEndObject; + } + throw syntaxError('Expected name'); + + default: + _checkLenient(); + if (isLiteral(c)) { + return _peeked = peekedUnquotedName; + } else { + throw syntaxError('Expected name'); + } + } + } else if (peekStack == JsonScope.danglingName) { + scopes[stackSize - 1] = JsonScope.nonEmptyObject; + // Look for a colon before the value. + var c = _nextNonWhitespace(true); + buffer.readByte(); // Consume ':'. + switch (c) { + case $colon: + break; + case $equal: + _checkLenient(); + if (buffer.request(1) && buffer.getByte(0) == $greaterThan) { + buffer.readByte(); // Consume '>'. + } + default: + throw syntaxError("Expected ':'"); + } + } else if (peekStack == JsonScope.emptyDocument) { + scopes[stackSize - 1] = JsonScope.nonEmptyDocument; + } else if (peekStack == JsonScope.nonEmptyDocument) { + var c = _nextNonWhitespace(false); + if (c == -1) { + return _peeked = peekedEof; + } else { + _checkLenient(); + } + } else if (peekStack == JsonScope.closed) { + throw StateError('JsonReader is closed'); + } + + var c = _nextNonWhitespace(true); + switch (c) { + case $closeBracket: + // fall-through to handle ",]" + case $semicolon: + case $comma: + if (c == $closeBracket) { + if (peekStack == JsonScope.emptyArray) { + buffer.readByte(); // Consume ']'. + return _peeked = peekedEndArray; + } + } + // In lenient mode, a 0-length literal in an array means 'null'. + if (peekStack == JsonScope.emptyArray || + peekStack == JsonScope.nonEmptyArray) { + _checkLenient(); + return _peeked = peekedNull; + } else { + throw syntaxError('Unexpected value'); + } + case $singleQuote: + _checkLenient(); + buffer.readByte(); // Consume '\''. + return _peeked = peekedSingleQuote; + case $doubleQuote: + buffer.readByte(); // Consume '\"'. + return _peeked = peekedDoubleQuote; + case $openBracket: + buffer.readByte(); // Consume '['. + return _peeked = peekedBeginArray; + case $openBrace: + buffer.readByte(); // Consume '{'. + return _peeked = peekedBeginObject; + default: + } + + var result = peekKeyword(); + if (result != peekedNone) { + return result; + } + + result = peekNumber(); + if (result != peekedNone) { + return result; + } + + if (!isLiteral(buffer.getByte(0))) { + throw syntaxError('Expected value'); + } + + _checkLenient(); + return _peeked = peekedUnquoted; + } + + int peekKeyword() { + // Figure out which keyword we're matching against by its first character. + var c = buffer.getByte(0); + String keyword; + String keywordUpper; + int peeking; + if (c == $t || c == $T) { + keyword = 'true'; + keywordUpper = 'TRUE'; + peeking = peekedTrue; + } else if (c == $f || c == $F) { + keyword = 'false'; + keywordUpper = 'FALSE'; + peeking = peekedFalse; + } else if (c == $n || c == $N) { + keyword = 'null'; + keywordUpper = 'NULL'; + peeking = peekedNull; + } else { + return peekedNone; + } + + // Confirm that chars [1..length) match the keyword. + var length = keyword.length; + for (var i = 1; i < length; i++) { + if (!buffer.request(i + 1)) { + return peekedNone; + } + c = buffer.getByte(i); + if (c != keyword[i].codeUnitAt(0) && c != keywordUpper[i].codeUnitAt(0)) { + return peekedNone; + } + } + + if (buffer.request(length + 1) && isLiteral(buffer.getByte(length))) { + return peekedNone; // Don't match trues, falsey or nullsoft! + } + + // We've found the keyword followed either by EOF or by a non-literal character. + buffer.skip(length); + return _peeked = peeking; + } + + int peekNumber() { + var value = 0; // Negative to accommodate Long.MIN_VALUE more easily. + var negative = false; + var fitsInLong = true; + var last = numberCharNone; + + var i = 0; + + for (; true; i++) { + if (!buffer.request(i + 1)) { + break; + } + + var c = buffer.getByte(i); + if (c == $dash) { + if (last == numberCharNone) { + negative = true; + last = numberCharSign; + continue; + } else if (last == numberCharExpE) { + last = numberCharExpSign; + continue; + } + return peekedNone; + } else if (c == $plus) { + if (last == numberCharExpE) { + last = numberCharExpSign; + continue; + } + return peekedNone; + } else if (c == $e || c == $E) { + if (last == numberCharDigit || last == numberCharFractionDigit) { + last = numberCharExpE; + continue; + } + return peekedNone; + } else if (c == $dot) { + if (last == numberCharDigit) { + last = numberCharDecimal; + continue; + } + return peekedNone; + } else { + if (c < $0 || c > $9) { + if (!isLiteral(c)) { + break; + } + return peekedNone; + } + if (last == numberCharSign || last == numberCharNone) { + value = -(c - $0); + last = numberCharDigit; + } else if (last == numberCharDigit) { + if (value == 0) { + return peekedNone; // Leading '0' prefix is not allowed (since it could be octal). + } + var newValue = value * 10 - (c - $0); + fitsInLong &= + value > minIncompleteInteger || + (value == minIncompleteInteger && newValue < value); + value = newValue; + } else if (last == numberCharDecimal) { + last = numberCharFractionDigit; + } else if (last == numberCharExpE || last == numberCharExpSign) { + last = numberCharExpDigit; + } + } + } + + // We've read a complete number. Decide if it's a PEEKED_LONG or a PEEKED_NUMBER. + if (last == numberCharDigit && + fitsInLong && + (value != longMinValue || negative) && + (value != 0 || !negative)) { + _peekedLong = negative ? value : -value; + buffer.skip(i); + return _peeked = peekedLong; + } else if (last == numberCharDigit || + last == numberCharFractionDigit || + last == numberCharExpDigit) { + _peekedNumberLength = i; + return _peeked = peekedNumber; + } else { + return peekedNone; + } + } + + bool isLiteral(int c) { + switch (c) { + case $slash: + case $backslash: + case $semicolon: + case $hash: + case $equal: + _checkLenient(); // fall-through + return false; + case $openBrace: + case $closeBrace: + case $openBracket: + case $closeBracket: + case $colon: + case $comma: + case $space: + case $tab: + case $ff: + case $cr: + case $lf: + return false; + default: + return true; + } + } + + @override + String nextName() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + late String result; + if (p == peekedUnquotedName) { + result = nextUnquotedValue(); + } else if (p == peekedDoubleQuotedName) { + result = _nextQuotedValue(doubleQuoteOrSlash); + } else if (p == peekedSingleQuotedName) { + result = _nextQuotedValue(singleQuoteOrSlash); + } else if (p == peekedBufferedName) { + result = _peekedString!; + } else { + throw JsonDataException( + 'Expected a name but was ${peek()} at path ${getPath()}', + ); + } + _peeked = peekedNone; + pathNames[stackSize - 1] = result; + return result; + } + + @override + int selectName(JsonReaderOptions options) { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p < peekedSingleQuotedName || p > peekedBufferedName) { + return -1; + } + if (p == peekedBufferedName) { + return _findName(_peekedString, options); + } + + var result = buffer.select(options.doubleQuoteSuffix); + if (result != -1) { + _peeked = peekedNone; + pathNames[stackSize - 1] = options.strings[result]; + + return result; + } + + // The next name may be unnecessary escaped. Save the last recorded path name, so that we + // can restore the peek state in case we fail to find a match. + var lastPathName = pathNames[stackSize - 1]; + + var nextName = this.nextName(); + result = _findName(nextName, options); + + if (result == -1) { + _peeked = peekedBufferedName; + _peekedString = nextName; + // We can't push the path further, make it seem like nothing happened. + pathNames[stackSize - 1] = lastPathName; + } + + return result; + } + + @override + void skipName() { + if (failOnUnknown) { + throw JsonDataException( + 'Cannot skip unexpected ${peek()} at ${getPath()}', + ); + } + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p == peekedUnquotedName) { + skipUnquotedValue(); + } else if (p == peekedDoubleQuotedName) { + skipQuotedValue(doubleQuoteOrSlash); + } else if (p == peekedSingleQuotedName) { + skipQuotedValue(singleQuoteOrSlash); + } else if (p != peekedBufferedName) { + throw JsonDataException( + 'Expected a name but was ${peek()} at path ${getPath()}', + ); + } + _peeked = peekedNone; + pathNames[stackSize - 1] = 'null'; + } + + /// If {@code name} is in {@code options} this consumes it and returns its index. + /// Otherwise this returns -1 and no name is consumed. + int _findName(String? name, JsonReaderOptions options) { + for (var i = 0, size = options.strings.length; i < size; i++) { + if (name == options.strings[i]) { + _peeked = peekedNone; + pathNames[stackSize - 1] = name; + + return i; + } + } + return -1; + } + + @override + String nextString() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + String? result; + if (p == peekedUnquoted) { + result = nextUnquotedValue(); + } else if (p == peekedDoubleQuote) { + result = _nextQuotedValue(doubleQuoteOrSlash); + } else if (p == peekedSingleQuote) { + result = _nextQuotedValue(singleQuoteOrSlash); + } else if (p == peekedBuffered) { + result = _peekedString; + _peekedString = null; + } else if (p == peekedLong) { + result = _peekedLong.toString(); + } else if (p == peekedNumber) { + result = buffer.readUtf8(_peekedNumberLength); + } else { + throw JsonDataException( + 'Expected a string but was ${peek()} at path ${getPath()}', + ); + } + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return result!; + } + + @override + bool nextBoolean() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + if (p == peekedTrue) { + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return true; + } else if (p == peekedFalse) { + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return false; + } + throw JsonDataException( + 'Expected a boolean but was ${peek()} at path ${getPath()}', + ); + } + + @override + double nextDouble() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + + if (p == peekedLong) { + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return _peekedLong.toDouble(); + } + + if (p == peekedNumber) { + _peekedString = buffer.readUtf8(_peekedNumberLength); + } else if (p == peekedDoubleQuote) { + _peekedString = _nextQuotedValue(doubleQuoteOrSlash); + } else if (p == peekedSingleQuote) { + _peekedString = _nextQuotedValue(singleQuoteOrSlash); + } else if (p == peekedUnquoted) { + _peekedString = nextUnquotedValue(); + } else if (p != peekedBuffered) { + throw JsonDataException( + 'Expected a double but was ${peek()} at path ${getPath()}', + ); + } + + _peeked = peekedBuffered; + double result; + try { + result = double.parse(_peekedString!); + } on FormatException catch (_) { + throw JsonDataException( + 'Expected a double but was $_peekedString at path ${getPath()}', + ); + } + if (!lenient && (result.isNaN || result.isInfinite)) { + throw JsonEncodingException( + 'JSON forbids NaN and infinities: $result at path ${getPath()}', + ); + } + _peekedString = null; + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return result; + } + + /// Returns the string up to but not including {@code quote}, unescaping any character escape + /// sequences encountered along the way. The opening quote should have already been read. This + /// consumes the closing quote, but does not include it in the returned string. + /// + /// @throws IOException if any unicode escape sequences are malformed. + String _nextQuotedValue(List runTerminator) { + StringBuffer? builder; + while (true) { + var index = buffer.indexOfElement(runTerminator, 0); + if (index == -1) throw syntaxError('Unterminated string'); + + // If we've got an escape character, we're going to need a string builder. + if (buffer.getByte(index) == $backslash) { + builder ??= StringBuffer(); + builder.write(buffer.readUtf8(index)); + buffer.readByte(); // '\' + builder.writeCharCode(readEscapeCharacter()); + continue; + } + + // If it isn't the escape character, it's the quote. Return the string. + if (builder == null) { + var result = buffer.readUtf8(index); + buffer.readByte(); // Consume the quote character. + return result; + } else { + builder.write(buffer.readUtf8(index)); + buffer.readByte(); // Consume the quote character. + return builder.toString(); + } + } + } + + /// Returns an unquoted value as a string. */ + String nextUnquotedValue() { + var i = buffer.indexOfElement(unquotedStringTerminals, 0); + return i != -1 ? buffer.readUtf8(i) : buffer.readUtf8(buffer.size); + } + + void skipQuotedValue(List runTerminator) { + while (true) { + var index = buffer.indexOfElement(runTerminator, 0); + if (index == -1) throw syntaxError('Unterminated string'); + + if (buffer.getByte(index) == $backslash) { + buffer.skip(index + 1); + readEscapeCharacter(); + } else { + buffer.skip(index + 1); + return; + } + } + } + + void skipUnquotedValue() { + var i = buffer.indexOfElement(unquotedStringTerminals, 0); + buffer.skip(i != -1 ? i : buffer.size); + } + + @override + int nextInt() { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + + int result; + if (p == peekedLong) { + result = _peekedLong; + if (_peekedLong != result) { + // Make sure no precision was lost casting to 'int'. + throw JsonDataException( + 'Expected an int but was $_peekedLong at path ${getPath()}', + ); + } + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return result; + } + + if (p == peekedNumber) { + _peekedString = buffer.readUtf8(_peekedNumberLength); + } else if (p == peekedDoubleQuote || p == peekedSingleQuote) { + _peekedString = p == peekedDoubleQuote + ? _nextQuotedValue(doubleQuoteOrSlash) + : _nextQuotedValue(singleQuoteOrSlash); + try { + result = int.parse(_peekedString!); + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return result; + } on FormatException catch (_) { + // Fall back to parse as a double below. + } + } else if (p != peekedBuffered) { + throw JsonDataException( + 'Expected an int but was ${peek()} at path ${getPath()}', + ); + } + + _peeked = peekedBuffered; + double asDouble; + try { + asDouble = double.parse(_peekedString!); + } on FormatException catch (_) { + throw JsonDataException( + 'Expected an int but was $_peekedString at path ${getPath()}', + ); + } + result = asDouble.toInt(); + if (result != asDouble) { + // Make sure no precision was lost casting to 'int'. + throw JsonDataException( + 'Expected an int but was $_peekedString at path ${getPath()}', + ); + } + _peekedString = null; + _peeked = peekedNone; + pathIndices[stackSize - 1]++; + return result; + } + + @override + void close() { + _peeked = peekedNone; + scopes[0] = JsonScope.closed; + stackSize = 1; + buffer.clear(); + } + + @override + void skipValue() { + if (failOnUnknown) { + throw JsonDataException( + 'Cannot skip unexpected ${peek()} at ${getPath()}', + ); + } + var count = 0; + do { + var p = _peeked; + if (p == peekedNone) { + p = _doPeek(); + } + + if (p == peekedBeginArray) { + pushScope(JsonScope.emptyArray); + count++; + } else if (p == peekedBeginObject) { + pushScope(JsonScope.emptyObject); + count++; + } else if (p == peekedEndArray) { + count--; + if (count < 0) { + throw JsonDataException( + 'Expected a value but was ${peek()} at path ${getPath()}', + ); + } + stackSize--; + } else if (p == peekedEndObject) { + count--; + if (count < 0) { + throw JsonDataException( + 'Expected a value but was ${peek()} at path ${getPath()}', + ); + } + stackSize--; + } else if (p == peekedUnquotedName || p == peekedUnquoted) { + skipUnquotedValue(); + } else if (p == peekedDoubleQuote || p == peekedDoubleQuotedName) { + skipQuotedValue(doubleQuoteOrSlash); + } else if (p == peekedSingleQuote || p == peekedSingleQuotedName) { + skipQuotedValue(singleQuoteOrSlash); + } else if (p == peekedNumber) { + buffer.skip(_peekedNumberLength); + } else if (p == peekedEof) { + throw JsonDataException( + 'Expected a value but was ${peek()} at path ${getPath()}', + ); + } + _peeked = peekedNone; + } while (count != 0); + + pathIndices[stackSize - 1]++; + pathNames[stackSize - 1] = 'null'; + } + + /// Returns the next character in the stream that is neither whitespace nor a + /// part of a comment. When this returns, the returned character is always at + /// {buffer.getByte(0)}. + int _nextNonWhitespace(bool throwOnEof) { + // This code uses ugly local variables 'p' and 'l' representing the 'pos' + // and 'limit' fields respectively. Using locals rather than fields saves + // a few field reads for each whitespace character in a pretty-printed + // document, resulting in a 5% speedup. We need to flush 'p' to its field + // before any (potentially indirect) call to fillBuffer() and reread both + // 'p' and 'l' after any (potentially indirect) call to the same method. + var p = 0; + while (buffer.request(p + 1)) { + var c = buffer.getByte(p++); + if (c == $lf || c == $space || c == $cr || c == $tab) { + continue; + } + + buffer.skip(p - 1); + if (c == $slash) { + if (!buffer.request(2)) { + return c; + } + + _checkLenient(); + var peek = buffer.getByte(1); + switch (peek) { + case $asterisk: + // skip a /* c-style comment */ + buffer.readByte(); // '/' + buffer.readByte(); // '*' + if (!_skipToEndOfBlockComment()) { + throw syntaxError('Unterminated comment'); + } + p = 0; + continue; + + case $slash: + // skip a // end-of-line comment + buffer.readByte(); // '/' + buffer.readByte(); // '/' + _skipToEndOfLine(); + p = 0; + continue; + + default: + return c; + } + } else if (c == $hash) { + // Skip a # hash end-of-line comment. The JSON RFC doesn't specify this behaviour, but it's + // required to parse existing documents. + _checkLenient(); + _skipToEndOfLine(); + p = 0; + } else { + return c; + } + } + if (throwOnEof) { + throw StateError('End of input'); + } else { + return -1; + } + } + + void _checkLenient() { + if (!lenient) { + throw syntaxError( + 'Use JsonReader.setLenient(true) to accept malformed JSON', + ); + } + } + + /// Advances the position until after the next newline character. If the line + /// is terminated by "\r\n", the '\n' must be consumed as whitespace by the + /// caller. + void _skipToEndOfLine() { + var index = buffer.indexOfElement(lineFeedOrCarriageReturn, 0); + buffer.skip(index != -1 ? index + 1 : buffer.size); + } + + /// Skips through the next closing block comment. + bool _skipToEndOfBlockComment() { + var index = buffer.indexOfBytes(closingBlockComment, 0); + var found = index != -1; + buffer.skip(found ? index + closingBlockComment.length : buffer.size); + return found; + } + + @override + String toString() { + return 'JsonReader($buffer)'; + } + + /// Unescapes the character identified by the character or characters that immediately follow a + /// backslash. The backslash '\' should have already been read. This supports both unicode escapes + /// "u000A" and two-character escapes "\n". + /// + /// @throws IOException if any unicode escape sequences are malformed. + int readEscapeCharacter() { + if (!buffer.request(1)) { + throw syntaxError('Unterminated escape sequence'); + } + + var escaped = buffer.readByte(); + switch (escaped) { + case $u: + if (!buffer.request(4)) { + throw Exception('Unterminated escape sequence at path ${getPath()}'); + } + // Equivalent to Integer.parseInt(stringPool.get(buffer, pos, 4), 16); + var result = 0; + for (var i = 0, end = i + 4; i < end; i++) { + var c = buffer.getByte(i); + result <<= 4; + if (c >= $0 && c <= $9) { + result += c - $0; + } else if (c >= $a && c <= $f) { + result += c - $a + 10; + } else if (c >= $A && c <= $F) { + result += c - $A + 10; + } else { + throw syntaxError('\\u${buffer.readUtf8(4)}'); + } + } + buffer.skip(4); + return result; + + case $t: + return $tab; + + case $b: + return $bs; + + case $n: + return $lf; + + case $r: + return $cr; + + case $f: + return $ff; + + case $lf: + case $singleQuote: + case $doubleQuote: + case $backslash: + case $slash: + return escaped; + + default: + if (!lenient) throw syntaxError('Invalid escape sequence: \\$escaped'); + return escaped; + } + } +} diff --git a/lottie/lib/src/parser/offset_parser.dart b/lottie/lib/src/parser/offset_parser.dart new file mode 100644 index 0000000..bdc72c9 --- /dev/null +++ b/lottie/lib/src/parser/offset_parser.dart @@ -0,0 +1,23 @@ +import 'dart:ui'; +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; + +Offset offsetParser(JsonReader reader) { + var token = reader.peek(); + if (token == Token.beginArray) { + return JsonUtils.jsonToPoint(reader); + } else if (token == Token.beginObject) { + return JsonUtils.jsonToPoint(reader); + } else if (token == Token.number) { + // This is the case where the static value for a property is an array of numbers. + // We begin the array to see if we have an array of keyframes but it's just an array + // of static numbers instead. + var point = Offset(reader.nextDouble(), reader.nextDouble()); + while (reader.hasNext()) { + reader.skipValue(); + } + return point; + } else { + throw Exception('Cannot convert json to point. Next token is $token'); + } +} diff --git a/lottie/lib/src/parser/path_keyframe_parser.dart b/lottie/lib/src/parser/path_keyframe_parser.dart new file mode 100644 index 0000000..a9cba2c --- /dev/null +++ b/lottie/lib/src/parser/path_keyframe_parser.dart @@ -0,0 +1,22 @@ +import 'dart:ui'; +import '../animation/keyframe/path_keyframe.dart'; +import '../composition.dart'; +import 'keyframe_parser.dart'; +import 'moshi/json_reader.dart'; +import 'path_parser.dart'; + +class PathKeyframeParser { + PathKeyframeParser._(); + + static PathKeyframe parse(JsonReader reader, LottieComposition composition) { + var animated = reader.peek() == Token.beginObject; + var keyframe = KeyframeParser.parse( + reader, + composition, + pathParser, + animated: animated, + ); + + return PathKeyframe(composition, keyframe); + } +} diff --git a/lottie/lib/src/parser/path_parser.dart b/lottie/lib/src/parser/path_parser.dart new file mode 100644 index 0000000..dbc6106 --- /dev/null +++ b/lottie/lib/src/parser/path_parser.dart @@ -0,0 +1,7 @@ +import 'dart:ui'; +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; + +Offset pathParser(JsonReader reader) { + return JsonUtils.jsonToPoint(reader); +} diff --git a/lottie/lib/src/parser/polysar_shape_parser.dart b/lottie/lib/src/parser/polysar_shape_parser.dart new file mode 100644 index 0000000..2c360e9 --- /dev/null +++ b/lottie/lib/src/parser/polysar_shape_parser.dart @@ -0,0 +1,98 @@ +import 'dart:ui'; +import '../composition.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_value.dart'; +import '../model/content/polystar_shape.dart'; +import 'animatable_path_value_parser.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class PolystarShapeParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'sy', + 'pt', + 'p', + 'r', + 'or', + 'os', + 'ir', + 'is', + 'hd', + 'd', + ]); + + PolystarShapeParser._(); + + static PolystarShape parse( + JsonReader reader, + LottieComposition composition, { + required int d, + }) { + String? name; + PolystarShapeType? type; + late AnimatableDoubleValue points; + late AnimatableValue position; + late AnimatableDoubleValue rotation; + late AnimatableDoubleValue outerRadius; + late AnimatableDoubleValue outerRoundedness; + AnimatableDoubleValue? innerRadius; + AnimatableDoubleValue? innerRoundedness; + var hidden = false; + var reversed = d == 3; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + type = PolystarShapeType.forValue(reader.nextInt()); + case 2: + points = AnimatableValueParser.parseFloat(reader, composition); + case 3: + position = AnimatablePathValueParser.parseSplitPath( + reader, + composition, + ); + case 4: + rotation = AnimatableValueParser.parseFloat(reader, composition); + case 5: + outerRadius = AnimatableValueParser.parseFloat(reader, composition); + case 6: + outerRoundedness = AnimatableValueParser.parseFloat( + reader, + composition, + ); + case 7: + innerRadius = AnimatableValueParser.parseFloat(reader, composition); + case 8: + innerRoundedness = AnimatableValueParser.parseFloat( + reader, + composition, + ); + case 9: + hidden = reader.nextBoolean(); + case 10: + // "d" is 2 for normal and 3 for reversed. + reversed = reader.nextInt() == 3; + default: + reader.skipName(); + reader.skipValue(); + } + } + + return PolystarShape( + name: name, + type: type, + points: points, + position: position, + rotation: rotation, + innerRadius: innerRadius, + outerRadius: outerRadius, + innerRoundedness: innerRoundedness, + outerRoundedness: outerRoundedness, + hidden: hidden, + isReversed: reversed, + ); + } +} diff --git a/lottie/lib/src/parser/rectangle_shape_parser.dart b/lottie/lib/src/parser/rectangle_shape_parser.dart new file mode 100644 index 0000000..e257aee --- /dev/null +++ b/lottie/lib/src/parser/rectangle_shape_parser.dart @@ -0,0 +1,59 @@ +import 'dart:ui'; +import '../../lottie.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_value.dart'; +import '../model/content/rectangle_shape.dart'; +import 'animatable_path_value_parser.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class RectangleShapeParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'p', + 's', + 'r', + 'hd', + ]); + + RectangleShapeParser._(); + + static RectangleShape parse( + JsonReader reader, + LottieComposition composition, + ) { + String? name; + AnimatableValue? position; + AnimatableValue? size; + AnimatableDoubleValue? roundedness; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + position = AnimatablePathValueParser.parseSplitPath( + reader, + composition, + ); + case 2: + size = AnimatableValueParser.parsePoint(reader, composition); + case 3: + roundedness = AnimatableValueParser.parseFloat(reader, composition); + case 4: + hidden = reader.nextBoolean(); + default: + reader.skipValue(); + } + } + + return RectangleShape( + name: name, + position: position!, + size: size!, + cornerRadius: roundedness!, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/repeat_parser.dart b/lottie/lib/src/parser/repeat_parser.dart new file mode 100644 index 0000000..893c7cd --- /dev/null +++ b/lottie/lib/src/parser/repeat_parser.dart @@ -0,0 +1,52 @@ +import '../../lottie.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_transform.dart'; +import '../model/content/repeater.dart'; +import 'animatable_transform_parser.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class RepeaterParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'c', + 'o', + 'tr', + 'hd', + ]); + + RepeaterParser._(); + + static Repeater parse(JsonReader reader, LottieComposition composition) { + String? name; + AnimatableDoubleValue? copies; + AnimatableDoubleValue? offset; + AnimatableTransform? transform; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + copies = AnimatableValueParser.parseFloat(reader, composition); + case 2: + offset = AnimatableValueParser.parseFloat(reader, composition); + case 3: + transform = AnimatableTransformParser.parse(reader, composition); + case 4: + hidden = reader.nextBoolean(); + default: + reader.skipValue(); + } + } + + return Repeater( + name: name, + copies: copies!, + offset: offset!, + transform: transform!, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/rounded_corners_parser.dart b/lottie/lib/src/parser/rounded_corners_parser.dart new file mode 100644 index 0000000..d5a8291 --- /dev/null +++ b/lottie/lib/src/parser/rounded_corners_parser.dart @@ -0,0 +1,37 @@ +import '../composition.dart'; +import '../model/animatable/animatable_value.dart'; +import '../model/content/rounded_corners.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class RoundedCornersParser { + static final _names = JsonReaderOptions.of([ + 'nm', // 0 + 'r', // 1 + 'hd', // 1 + ]); + + static RoundedCorners? parse( + JsonReader reader, + LottieComposition composition, + ) { + String? name; + AnimatableValue? cornerRadius; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: //nm + name = reader.nextString(); + case 1: // r + cornerRadius = AnimatableValueParser.parseFloat(reader, composition); + case 2: // hd + hidden = reader.nextBoolean(); + default: + reader.skipValue(); + } + } + + return hidden ? null : RoundedCorners(name ?? '', cornerRadius!); + } +} diff --git a/lottie/lib/src/parser/scale_xy_parser.dart b/lottie/lib/src/parser/scale_xy_parser.dart new file mode 100644 index 0000000..2957bc0 --- /dev/null +++ b/lottie/lib/src/parser/scale_xy_parser.dart @@ -0,0 +1,18 @@ +import 'dart:ui'; +import 'moshi/json_reader.dart'; + +Offset scaleXYParser(JsonReader reader) { + var isArray = reader.peek() == Token.beginArray; + if (isArray) { + reader.beginArray(); + } + var sx = reader.nextDouble(); + var sy = reader.nextDouble(); + while (reader.hasNext()) { + reader.skipValue(); + } + if (isArray) { + reader.endArray(); + } + return Offset(sx / 100.0, sy / 100.0); +} diff --git a/lottie/lib/src/parser/shape_data_parser.dart b/lottie/lib/src/parser/shape_data_parser.dart new file mode 100644 index 0000000..4254a5c --- /dev/null +++ b/lottie/lib/src/parser/shape_data_parser.dart @@ -0,0 +1,93 @@ +import 'dart:ui'; +import '../model/content/shape_data.dart'; +import '../model/cubic_curve_data.dart'; +import 'json_utils.dart'; +import 'moshi/json_reader.dart'; + +final JsonReaderOptions _names = JsonReaderOptions.of(['c', 'v', 'i', 'o']); + +ShapeData shapeDataParser(JsonReader reader) { + // Sometimes the points data is in a array of length 1. Sometimes the data is at the top + // level. + if (reader.peek() == Token.beginArray) { + reader.beginArray(); + } + + var closed = false; + List? pointsArray; + List? inTangents; + List? outTangents; + reader.beginObject(); + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + closed = reader.nextBoolean(); + case 1: + pointsArray = JsonUtils.jsonToPoints(reader); + case 2: + inTangents = JsonUtils.jsonToPoints(reader); + case 3: + outTangents = JsonUtils.jsonToPoints(reader); + default: + reader.skipName(); + reader.skipValue(); + } + } + + reader.endObject(); + + if (reader.peek() == Token.endArray) { + reader.endArray(); + } + + if (pointsArray == null || inTangents == null || outTangents == null) { + throw Exception('Shape data was missing information.'); + } + + if (pointsArray.isEmpty) { + return ShapeData( + [], + initialPoint: Offset.zero, + closed: false, + ); + } + + var length = pointsArray.length; + var vertex = pointsArray[0]; + var initialPoint = vertex; + var curves = []; + + for (var i = 1; i < length; i++) { + vertex = pointsArray[i]; + var previousVertex = pointsArray[i - 1]; + var cp1 = outTangents[i - 1]; + var cp2 = inTangents[i]; + var shapeCp1 = previousVertex + cp1; + var shapeCp2 = vertex + cp2; + curves.add( + CubicCurveData() + ..controlPoint1 = shapeCp1 + ..controlPoint2 = shapeCp2 + ..vertex = vertex, + ); + } + + if (closed) { + vertex = pointsArray[0]; + var previousVertex = pointsArray[length - 1]; + var cp1 = outTangents[length - 1]; + var cp2 = inTangents[0]; + + var shapeCp1 = previousVertex + cp1; + var shapeCp2 = vertex + cp2; + + curves.add( + CubicCurveData() + ..controlPoint1 = shapeCp1 + ..controlPoint2 = shapeCp2 + ..vertex = vertex, + ); + } + return ShapeData(curves, initialPoint: initialPoint, closed: closed); +} diff --git a/lottie/lib/src/parser/shape_fill_parser.dart b/lottie/lib/src/parser/shape_fill_parser.dart new file mode 100644 index 0000000..74a10c2 --- /dev/null +++ b/lottie/lib/src/parser/shape_fill_parser.dart @@ -0,0 +1,67 @@ +import 'dart:ui'; +import '../../lottie.dart'; +import '../model/animatable/animatable_color_value.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/content/shape_fill.dart'; +import '../value/keyframe.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class ShapeFillParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'c', + 'o', + 'fillEnabled', + 'r', + 'hd', + ]); + + ShapeFillParser._(); + + static ShapeFill parse(JsonReader reader, LottieComposition composition) { + AnimatableColorValue? color; + var fillEnabled = false; + AnimatableIntegerValue? opacity; + String? name; + var fillTypeInt = 1; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + color = AnimatableValueParser.parseColor(reader, composition); + case 2: + opacity = AnimatableValueParser.parseInteger(reader, composition); + case 3: + fillEnabled = reader.nextBoolean(); + case 4: + fillTypeInt = reader.nextInt(); + case 5: + hidden = reader.nextBoolean(); + default: + reader.skipName(); + reader.skipValue(); + } + } + + var fillType = fillTypeInt == 1 + ? PathFillType.nonZero + : PathFillType.evenOdd; + // Telegram sometimes omits opacity. + // https://github.com/airbnb/lottie-android/issues/1600 + opacity ??= AnimatableIntegerValue.fromKeyframes([ + Keyframe.nonAnimated(100), + ]); + return ShapeFill( + name: name, + fillEnabled: fillEnabled, + fillType: fillType, + color: color, + opacity: opacity, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/shape_group_parser.dart b/lottie/lib/src/parser/shape_group_parser.dart new file mode 100644 index 0000000..c65c8e2 --- /dev/null +++ b/lottie/lib/src/parser/shape_group_parser.dart @@ -0,0 +1,42 @@ +import '../composition.dart'; +import '../model/content/content_model.dart'; +import '../model/content/shape_group.dart'; +import 'content_model_parser.dart'; +import 'moshi/json_reader.dart'; + +class ShapeGroupParser { + ShapeGroupParser._(); + + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'hd', + 'it', + ]); + static ShapeGroup parse(JsonReader reader, LottieComposition composition) { + String? name; + var hidden = false; + var items = []; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + hidden = reader.nextBoolean(); + case 2: + reader.beginArray(); + while (reader.hasNext()) { + var newItem = ContentModelParser.parse(reader, composition); + if (newItem != null) { + items.add(newItem); + } + } + reader.endArray(); + default: + reader.skipValue(); + } + } + + return ShapeGroup(name, items, hidden: hidden); + } +} diff --git a/lottie/lib/src/parser/shape_path_parser.dart b/lottie/lib/src/parser/shape_path_parser.dart new file mode 100644 index 0000000..14915bf --- /dev/null +++ b/lottie/lib/src/parser/shape_path_parser.dart @@ -0,0 +1,40 @@ +import '../../lottie.dart'; +import '../model/animatable/animatable_shape_value.dart'; +import '../model/content/shape_path.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class ShapePathParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'ind', + 'ks', + 'hd', + ]); + + ShapePathParser._(); + + static ShapePath parse(JsonReader reader, LottieComposition composition) { + String? name; + var ind = 0; + AnimatableShapeValue? shape; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + ind = reader.nextInt(); + case 2: + shape = AnimatableValueParser.parseShapeData(reader, composition); + case 3: + hidden = reader.nextBoolean(); + default: + reader.skipValue(); + } + } + + return ShapePath(name: name, index: ind, shapePath: shape!, hidden: hidden); + } +} diff --git a/lottie/lib/src/parser/shape_stroke_parser.dart b/lottie/lib/src/parser/shape_stroke_parser.dart new file mode 100644 index 0000000..27938e0 --- /dev/null +++ b/lottie/lib/src/parser/shape_stroke_parser.dart @@ -0,0 +1,118 @@ +import '../composition.dart'; +import '../model/animatable/animatable_color_value.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/animatable/animatable_integer_value.dart'; +import '../model/content/shape_stroke.dart'; +import '../value/keyframe.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class ShapeStrokeParser { + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 'nm', + 'c', + 'w', + 'o', + 'lc', + 'lj', + 'ml', + 'hd', + 'd', + ]); + static final JsonReaderOptions _dashPatternNames = JsonReaderOptions.of([ + 'n', + 'v', + ]); + + ShapeStrokeParser._(); + + static ShapeStroke parse(JsonReader reader, LottieComposition composition) { + String? name; + AnimatableColorValue? color; + AnimatableDoubleValue? width; + AnimatableIntegerValue? opacity; + LineCapType? capType; + LineJoinType? joinType; + AnimatableDoubleValue? offset; + var miterLimit = 0.0; + var hidden = false; + + var lineDashPattern = []; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + name = reader.nextString(); + case 1: + color = AnimatableValueParser.parseColor(reader, composition); + case 2: + width = AnimatableValueParser.parseFloat(reader, composition); + case 3: + opacity = AnimatableValueParser.parseInteger(reader, composition); + case 4: + capType = LineCapType.values[reader.nextInt() - 1]; + case 5: + joinType = LineJoinType.values[reader.nextInt() - 1]; + case 6: + miterLimit = reader.nextDouble(); + case 7: + hidden = reader.nextBoolean(); + case 8: + reader.beginArray(); + while (reader.hasNext()) { + String? n; + AnimatableDoubleValue? val; + + reader.beginObject(); + while (reader.hasNext()) { + switch (reader.selectName(_dashPatternNames)) { + case 0: + n = reader.nextString(); + case 1: + val = AnimatableValueParser.parseFloat(reader, composition); + default: + reader.skipName(); + reader.skipValue(); + } + } + reader.endObject(); + + switch (n) { + case 'o': + offset = val; + case 'd': + case 'g': + composition.hasDashPattern = true; + lineDashPattern.add(val!); + } + } + reader.endArray(); + + if (lineDashPattern.length == 1) { + // If there is only 1 value then it is assumed to be equal parts on and off. + lineDashPattern.add(lineDashPattern.first); + } + default: + reader.skipValue(); + } + } + + // Telegram sometimes omits opacity. + // https://github.com/airbnb/lottie-android/issues/1600 + opacity ??= AnimatableIntegerValue.fromKeyframes([ + Keyframe.nonAnimated(100), + ]); + return ShapeStroke( + name: name, + dashOffset: offset, + lineDashPattern: lineDashPattern, + color: color!, + opacity: opacity, + width: width!, + capType: capType, + joinType: joinType, + miterLimit: miterLimit, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/shape_trim_path_parser.dart b/lottie/lib/src/parser/shape_trim_path_parser.dart new file mode 100644 index 0000000..1cf4b92 --- /dev/null +++ b/lottie/lib/src/parser/shape_trim_path_parser.dart @@ -0,0 +1,53 @@ +import '../../lottie.dart'; +import '../model/animatable/animatable_double_value.dart'; +import '../model/content/shape_trim_path.dart'; +import 'animatable_value_parser.dart'; +import 'moshi/json_reader.dart'; + +class ShapeTrimPathParser { + ShapeTrimPathParser._(); + static final JsonReaderOptions _names = JsonReaderOptions.of([ + 's', + 'e', + 'o', + 'nm', + 'm', + 'hd', + ]); + static ShapeTrimPath parse(JsonReader reader, LottieComposition composition) { + String? name; + ShapeTrimPathType? type; + AnimatableDoubleValue? start; + AnimatableDoubleValue? end; + AnimatableDoubleValue? offset; + var hidden = false; + + while (reader.hasNext()) { + switch (reader.selectName(_names)) { + case 0: + start = AnimatableValueParser.parseFloat(reader, composition); + case 1: + end = AnimatableValueParser.parseFloat(reader, composition); + case 2: + offset = AnimatableValueParser.parseFloat(reader, composition); + case 3: + name = reader.nextString(); + case 4: + type = ShapeTrimPath.typeForId(reader.nextInt()); + case 5: + hidden = reader.nextBoolean(); + default: + reader.skipValue(); + } + } + + return ShapeTrimPath( + name: name, + type: type ?? ShapeTrimPathType.simultaneously, + start: start!, + end: end!, + offset: offset!, + hidden: hidden, + ); + } +} diff --git a/lottie/lib/src/parser/value_parser.dart b/lottie/lib/src/parser/value_parser.dart new file mode 100644 index 0000000..6761d0d --- /dev/null +++ b/lottie/lib/src/parser/value_parser.dart @@ -0,0 +1,3 @@ +import 'moshi/json_reader.dart'; + +typedef ValueParser = V Function(JsonReader reader); diff --git a/lottie/lib/src/performance_tracker.dart b/lottie/lib/src/performance_tracker.dart new file mode 100644 index 0000000..f8b1211 --- /dev/null +++ b/lottie/lib/src/performance_tracker.dart @@ -0,0 +1,67 @@ +import 'package:flutter/foundation.dart'; +import 'utils/mean_calculator.dart'; +import 'utils/pair.dart'; + +class PerformanceTracker { + final _frameListeners = {}; + final _layerRenderTimes = {}; + + bool enabled = false; + + void recordRenderTime(String layerName, double millis) { + if (!enabled) return; + + if (!_layerRenderTimes.containsKey(layerName)) { + _layerRenderTimes[layerName] = MeanCalculator(); + } + + final calculator = _layerRenderTimes[layerName]!; + + calculator.add(millis); + + if (layerName == '__container') { + for (var listener in _frameListeners) { + listener.onFrameRendered(millis); + } + } + } + + void addFrameListener(FrameListener listener) { + _frameListeners.add(listener); + } + + void removeFrameListener(FrameListener listener) { + _frameListeners.remove(listener); + } + + void clearRenderTimes() { + _layerRenderTimes.clear(); + } + + void logRenderTimes() { + if (!enabled) return; + + final sortedRenderTimes = getSortedRenderTimes(); + + debugPrint('[Lottie] Render Times:'); + for (var layer in sortedRenderTimes) { + debugPrint('[Lottie]\t\t${layer.first}: ${layer.second}ms'); + } + } + + List> getSortedRenderTimes() { + if (!enabled) return []; + + final sortedRenderTimes = _layerRenderTimes.entries + .map((e) => Pair(e.key, e.value.mean)) + .toList(); + + sortedRenderTimes.sort((p1, p2) => p1.second.compareTo(p2.second)); + + return sortedRenderTimes; + } +} + +abstract class FrameListener { + void onFrameRendered(double renderTimeMs); +} diff --git a/lottie/lib/src/providers/asset_provider.dart b/lottie/lib/src/providers/asset_provider.dart new file mode 100644 index 0000000..cd043da --- /dev/null +++ b/lottie/lib/src/providers/asset_provider.dart @@ -0,0 +1,103 @@ +import 'dart:async'; +import 'dart:ui' as ui; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:path/path.dart' as p; +import '../composition.dart'; +import '../lottie_image_asset.dart'; +import 'load_fonts.dart'; +import 'load_image.dart'; +import 'lottie_provider.dart'; + +@immutable +class AssetLottie extends LottieProvider { + AssetLottie( + this.assetName, { + this.bundle, + this.package, + super.imageProviderFactory, + super.decoder, + super.backgroundLoading, + }); + + final String assetName; + String get keyName => + package == null ? assetName : 'packages/$package/$assetName'; + + final AssetBundle? bundle; + + final String? package; + + @override + Future load({BuildContext? context}) { + return sharedLottieCache.putIfAbsent(this, () async { + final finalContext = context; + final chosenBundle = + bundle ?? + (finalContext != null + ? DefaultAssetBundle.of(finalContext) + : rootBundle); + + var data = await chosenBundle.load(keyName); + + LottieComposition composition; + if (backgroundLoading) { + composition = await compute(parseJsonBytes, ( + data.buffer.asUint8List(), + decoder, + )); + } else { + composition = await LottieComposition.fromByteData( + data, + decoder: decoder, + ); + } + + for (var image in composition.images.values) { + image.loadedImage ??= await _loadImage(composition, image); + } + + await ensureLoadedFonts(composition); + + return composition; + }); + } + + Future _loadImage( + LottieComposition composition, + LottieImageAsset lottieImage, + ) { + var imageProvider = getImageProvider(lottieImage); + + if (imageProvider == null) { + var imageAssetPath = p.url.join( + p.dirname(assetName), + lottieImage.dirName, + lottieImage.fileName, + ); + imageProvider = AssetImage( + imageAssetPath, + bundle: bundle, + package: package, + ); + } + + return loadImage(composition, lottieImage, imageProvider); + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) return false; + return other is AssetLottie && + other.keyName == keyName && + other.bundle == bundle && + other.decoder == decoder; + } + + @override + int get hashCode => Object.hash(keyName, bundle); + + @override + String toString() => '$runtimeType(bundle: $bundle, name: "$keyName")'; +} diff --git a/lottie/lib/src/providers/file_provider.dart b/lottie/lib/src/providers/file_provider.dart new file mode 100644 index 0000000..addc778 --- /dev/null +++ b/lottie/lib/src/providers/file_provider.dart @@ -0,0 +1 @@ +export 'file_provider_no_io.dart' if (dart.library.io) 'file_provider_io.dart'; diff --git a/lottie/lib/src/providers/file_provider_io.dart b/lottie/lib/src/providers/file_provider_io.dart new file mode 100644 index 0000000..706213c --- /dev/null +++ b/lottie/lib/src/providers/file_provider_io.dart @@ -0,0 +1,83 @@ +import 'dart:io' as io; +import 'dart:ui' as ui; +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:path/path.dart' as p; +import '../composition.dart'; +import '../lottie_image_asset.dart'; +import 'load_fonts.dart'; +import 'load_image.dart'; +import 'lottie_provider.dart'; + +@immutable +class FileLottie extends LottieProvider { + FileLottie( + Object file, { + super.imageProviderFactory, + super.decoder, + super.backgroundLoading, + }) : file = file as io.File, + assert( + !kIsWeb, + 'Lottie.file is not supported on Flutter Web. ' + 'Consider using either Lottie.asset or Lottie.network instead.', + ); + + final io.File file; + + @override + Future load({BuildContext? context}) { + return sharedLottieCache.putIfAbsent(this, () async { + LottieComposition composition; + var args = (file, decoder); + if (backgroundLoading) { + composition = await compute(_loadFileAndParse, args); + } else { + composition = await _loadFileAndParse(args); + } + + for (var image in composition.images.values) { + image.loadedImage ??= await _loadImage(composition, image); + } + + await ensureLoadedFonts(composition); + + return composition; + }); + } + + Future _loadImage( + LottieComposition composition, + LottieImageAsset lottieImage, + ) { + var imageProvider = getImageProvider(lottieImage); + + var imagePath = p.url.join( + p.dirname(file.path), + lottieImage.dirName, + lottieImage.fileName, + ); + imageProvider ??= FileImage(io.File(imagePath)); + + return loadImage(composition, lottieImage, imageProvider); + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) return false; + return other is FileLottie && file.path == other.file.path; + } + + @override + int get hashCode => file.hashCode; + + @override + String toString() => '$runtimeType(file: ${file.path})'; +} + +Future _loadFileAndParse( + (io.File, LottieDecoder?) args, +) async { + var bytes = await args.$1.readAsBytes(); + return await LottieComposition.fromBytes(bytes, decoder: args.$2); +} diff --git a/lottie/lib/src/providers/file_provider_no_io.dart b/lottie/lib/src/providers/file_provider_no_io.dart new file mode 100644 index 0000000..0efae54 --- /dev/null +++ b/lottie/lib/src/providers/file_provider_no_io.dart @@ -0,0 +1,27 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import '../composition.dart'; +import 'lottie_provider.dart'; + +@immutable +class FileLottie extends LottieProvider { + FileLottie( + this.file, { + super.imageProviderFactory, + super.decoder, + super.backgroundLoading, + }) : assert( + !kIsWeb, + 'Lottie.file is not supported on Flutter Web. ' + 'Consider using either Lottie.asset or Lottie.network instead.', + ); + + final Object file; + + @override + Future load({BuildContext? context}) { + throw UnimplementedError( + 'FileLottie provider is not supported on Web platform', + ); + } +} diff --git a/lottie/lib/src/providers/load_fonts.dart b/lottie/lib/src/providers/load_fonts.dart new file mode 100644 index 0000000..9a717c8 --- /dev/null +++ b/lottie/lib/src/providers/load_fonts.dart @@ -0,0 +1,11 @@ +import 'dart:ui'; +import '../composition.dart'; + +Future ensureLoadedFonts(LottieComposition composition) async { + var fonts = FontToLoad.getAndClear(composition); + if (fonts != null) { + for (var font in fonts) { + await loadFontFromList(font.bytes, fontFamily: font.family); + } + } +} diff --git a/lottie/lib/src/providers/load_image.dart b/lottie/lib/src/providers/load_image.dart new file mode 100644 index 0000000..dbd6039 --- /dev/null +++ b/lottie/lib/src/providers/load_image.dart @@ -0,0 +1,40 @@ +import 'dart:async'; +import 'dart:ui' as ui; +import 'package:flutter/widgets.dart'; +import '../composition.dart'; +import '../lottie_image_asset.dart'; + +typedef LottieImageProviderFactory = ImageProvider? Function(LottieImageAsset); + +Future loadImage( + LottieComposition composition, + LottieImageAsset lottieImage, + ImageProvider provider, +) { + var completer = Completer(); + var imageStream = provider.resolve(ImageConfiguration.empty); + late ImageStreamListener listener; + listener = ImageStreamListener( + (image, synchronousLoaded) { + imageStream.removeListener(listener); + + completer.complete(image.image); + }, + onError: (dynamic e, _) { + imageStream.removeListener(listener); + + composition.addWarning('Failed to load image ${lottieImage.id}: $e'); + completer.complete(); + }, + ); + imageStream.addListener(listener); + + return completer.future; +} + +ImageProvider? fromDataUri(String filePath) { + if (filePath.startsWith('data:')) { + return MemoryImage(Uri.parse(filePath).data!.contentAsBytes()); + } + return null; +} diff --git a/lottie/lib/src/providers/lottie_provider.dart b/lottie/lib/src/providers/lottie_provider.dart new file mode 100644 index 0000000..451cdab --- /dev/null +++ b/lottie/lib/src/providers/lottie_provider.dart @@ -0,0 +1,138 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import '../../lottie.dart'; +import 'load_image.dart'; + +abstract class LottieProvider { + LottieProvider({ + this.imageProviderFactory, + this.decoder, + bool? backgroundLoading, + }) : backgroundLoading = backgroundLoading ?? false; + + final LottieImageProviderFactory? imageProviderFactory; + + final LottieDecoder? decoder; + + final bool backgroundLoading; + + ImageProvider? getImageProvider(LottieImageAsset lottieImage) { + var imageProvider = fromDataUri(lottieImage.fileName); + if (imageProvider == null && imageProviderFactory != null) { + imageProvider = imageProviderFactory!(lottieImage); + } + return imageProvider; + } + + Future load({BuildContext? context}); +} + +Future parseJsonBytes( + (Uint8List, LottieDecoder?) args, +) async { + return LottieComposition.fromBytes(args.$1, decoder: args.$2); +} + +class LottieCache { + final Map> _pending = + >{}; + final Map _cache = {}; + + /// Maximum number of entries to store in the cache. + /// + /// Once this many entries have been cached, the least-recently-used entry is + /// evicted when adding a new entry. + int get maximumSize => _maximumSize; + int _maximumSize = 1000; + + /// Changes the maximum cache size. + /// + /// If the new size is smaller than the current number of elements, the + /// extraneous elements are evicted immediately. Setting this to zero and then + /// returning it to its original value will therefore immediately clear the + /// cache. + set maximumSize(int value) { + assert(value >= 0); + if (value == maximumSize) { + return; + } + _maximumSize = value; + if (maximumSize == 0) { + clear(); + } else { + while (_cache.length > maximumSize) { + _cache.remove(_cache.keys.first); + } + } + } + + /// Evicts all entries from the cache. + /// + /// This is useful if, for instance, the root asset bundle has been updated + /// and therefore new images must be obtained. + void clear() { + _cache.clear(); + } + + /// Evicts a single entry from the cache, returning true if successful. + bool evict(Object key) { + return _cache.remove(key) != null; + } + + /// Returns the previously cached [LottieComposition] for the given key, if available; + /// if not, calls the given callback to obtain it first. In either case, the + /// key is moved to the "most recently used" position. + /// + /// The arguments must not be null. The `loader` cannot return null. + Future putIfAbsent( + Object key, + Future Function() loader, + ) { + var pendingResult = _pending[key]; + if (pendingResult != null) { + return pendingResult; + } + + var result = _cache[key]; + if (result != null) { + // Remove the provider from the list so that we can put it back in below + // and thus move it to the end of the list. + _cache.remove(key); + } else { + if (_cache.length == maximumSize && maximumSize > 0) { + _cache.remove(_cache.keys.first); + } + pendingResult = loader(); + _pending[key] = pendingResult; + pendingResult + .then((LottieComposition data) { + _pending.remove(key); + _add(key, data); + + result = data; // in case it was a synchronous future. + }) + .catchError((Object? e) { + _pending.remove(key); + }); + } + if (result != null) { + _add(key, result!); + return SynchronousFuture(result!); + } + assert(_cache.length <= maximumSize); + return pendingResult!; + } + + void _add(Object key, LottieComposition result) { + if (maximumSize > 0) { + assert(_cache.length < maximumSize); + _cache[key] = result; + } + assert(_cache.length <= maximumSize); + } + + /// The number of entries in the cache. + int get count => _cache.length; +} + +final sharedLottieCache = LottieCache(); diff --git a/lottie/lib/src/providers/memory_provider.dart b/lottie/lib/src/providers/memory_provider.dart new file mode 100644 index 0000000..eb23fac --- /dev/null +++ b/lottie/lib/src/providers/memory_provider.dart @@ -0,0 +1,70 @@ +import 'dart:ui' as ui; +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:path/path.dart' as p; +import '../composition.dart'; +import '../lottie_image_asset.dart'; +import 'load_fonts.dart'; +import 'load_image.dart'; +import 'lottie_provider.dart'; + +@immutable +class MemoryLottie extends LottieProvider { + MemoryLottie( + this.bytes, { + super.imageProviderFactory, + super.decoder, + super.backgroundLoading, + }); + + final Uint8List bytes; + + @override + Future load({BuildContext? context}) { + return sharedLottieCache.putIfAbsent(this, () async { + LottieComposition composition; + if (backgroundLoading) { + composition = await compute(parseJsonBytes, (bytes, decoder)); + } else { + composition = await LottieComposition.fromBytes( + bytes, + decoder: decoder, + ); + } + for (var image in composition.images.values) { + image.loadedImage ??= await _loadImage(composition, image); + } + + await ensureLoadedFonts(composition); + + return composition; + }); + } + + Future _loadImage( + LottieComposition composition, + LottieImageAsset lottieImage, + ) { + var imageProvider = getImageProvider(lottieImage); + + imageProvider ??= AssetImage( + p.join(lottieImage.dirName, lottieImage.fileName), + ); + + return loadImage(composition, lottieImage, imageProvider); + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) return false; + + //TODO(xha): compare bytes content + return other is MemoryLottie && other.bytes == bytes; + } + + @override + int get hashCode => bytes.hashCode; + + @override + String toString() => '$runtimeType(bytes: ${bytes.length})'; +} diff --git a/lottie/lib/src/providers/network_provider.dart b/lottie/lib/src/providers/network_provider.dart new file mode 100644 index 0000000..0d6321a --- /dev/null +++ b/lottie/lib/src/providers/network_provider.dart @@ -0,0 +1,92 @@ +import 'dart:async'; +import 'dart:ui' as ui; +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import 'package:path/path.dart' as p; +import '../composition.dart'; +import '../lottie_image_asset.dart'; +import 'load_fonts.dart'; +import 'load_image.dart'; +import 'lottie_provider.dart'; + +@immutable +class NetworkLottie extends LottieProvider { + NetworkLottie( + this.url, { + this.client, + this.headers, + super.imageProviderFactory, + super.decoder, + super.backgroundLoading, + }); + + final http.Client? client; + final String url; + final Map? headers; + + @override + Future load({BuildContext? context}) { + return sharedLottieCache.putIfAbsent(this, () async { + var resolved = Uri.base.resolve(url); + + var client = this.client ?? http.Client(); + try { + var bytes = await client.readBytes(resolved, headers: headers); + + LottieComposition composition; + if (backgroundLoading) { + composition = await compute(parseJsonBytes, (bytes, decoder)); + } else { + composition = await LottieComposition.fromBytes( + bytes, + decoder: decoder, + ); + } + + for (var image in composition.images.values) { + image.loadedImage ??= await _loadImage(resolved, composition, image); + } + + await ensureLoadedFonts(composition); + + return composition; + } finally { + if (this.client == null) { + client.close(); + } + } + }); + } + + Future _loadImage( + Uri jsonUri, + LottieComposition composition, + LottieImageAsset lottieImage, + ) { + var imageProvider = getImageProvider(lottieImage); + + if (imageProvider == null) { + var imageUrl = jsonUri.resolve( + p.url.join(lottieImage.dirName, lottieImage.fileName), + ); + imageProvider = NetworkImage(imageUrl.toString()); + } + + return loadImage(composition, lottieImage, imageProvider); + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) return false; + return other is NetworkLottie && + other.url == url && + other.decoder == decoder; + } + + @override + int get hashCode => url.hashCode; + + @override + String toString() => '$runtimeType(url: $url)'; +} diff --git a/lottie/lib/src/raw_lottie.dart b/lottie/lib/src/raw_lottie.dart new file mode 100644 index 0000000..3e96644 --- /dev/null +++ b/lottie/lib/src/raw_lottie.dart @@ -0,0 +1,144 @@ +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; +import 'composition.dart'; +import 'frame_rate.dart'; +import 'lottie_delegates.dart'; +import 'lottie_drawable.dart'; +import 'options.dart'; +import 'render_cache.dart'; +import 'render_lottie.dart'; + +/// A widget that displays a [LottieDrawable] directly. +/// +/// This widget is rarely used directly. Instead, consider using [Lottie]. +class RawLottie extends LeafRenderObjectWidget { + /// Creates a widget that displays a Lottie composition. + const RawLottie({ + super.key, + this.composition, + this.delegates, + this.options, + double? progress, + this.frameRate, + this.width, + this.height, + this.fit, + AlignmentGeometry? alignment, + this.filterQuality, + this.renderCache, + }) : progress = progress ?? 0.0, + alignment = alignment ?? Alignment.center; + + /// The Lottie composition to display. + final LottieComposition? composition; + + /// Allows to modify the Lottie animation at runtime + final LottieDelegates? delegates; + + final LottieOptions? options; + + /// The progress of the Lottie animation (between 0.0 and 1.0). + final double progress; + + /// The number of frames per second to render. + /// Use `FrameRate.composition` to use the original frame rate of the Lottie composition (default) + /// Use `FrameRate.max` to advance the animation progression at every frame. + final FrameRate? frameRate; + + /// If non-null, require the Lottie composition to have this width. + /// + /// If null, the composition will pick a size that best preserves its intrinsic + /// aspect ratio. + final double? width; + + /// If non-null, require the Lottie composition to have this height. + /// + /// If null, the composition will pick a size that best preserves its intrinsic + /// aspect ratio. + final double? height; + + /// How to inscribe the Lottie composition into the space allocated during layout. + final BoxFit? fit; + + /// How to align the composition within its bounds. + /// + /// The alignment aligns the given position in the image to the given position + /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, + /// -1.0) aligns the image to the top-left corner of its layout bounds, while a + /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the + /// image with the bottom right corner of its layout bounds. Similarly, an + /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the + /// middle of the bottom edge of its layout bounds. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final AlignmentGeometry alignment; + + /// {@macro lottie.renderCache} + final RenderCache? renderCache; + + final FilterQuality? filterQuality; + + @override + RenderLottie createRenderObject(BuildContext context) { + return RenderLottie( + composition: composition, + delegates: delegates, + enableMergePaths: options?.enableMergePaths, + enableApplyingOpacityToLayers: options?.enableApplyingOpacityToLayers, + progress: progress, + frameRate: frameRate, + width: width, + height: height, + fit: fit, + alignment: alignment, + filterQuality: filterQuality, + renderCache: renderCache, + devicePixelRatio: MediaQuery.devicePixelRatioOf(context), + ); + } + + @override + void updateRenderObject(BuildContext context, RenderLottie renderObject) { + renderObject + ..setComposition( + composition, + progress: progress, + frameRate: frameRate, + delegates: delegates, + enableMergePaths: options?.enableMergePaths, + enableApplyingOpacityToLayers: options?.enableApplyingOpacityToLayers, + filterQuality: filterQuality, + ) + ..width = width + ..height = height + ..alignment = alignment + ..fit = fit + ..renderCache = renderCache + ..devicePixelRatio = MediaQuery.devicePixelRatioOf(context); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add( + DiagnosticsProperty('composition', composition), + ); + properties.add(DoubleProperty('width', width, defaultValue: null)); + properties.add(DoubleProperty('height', height, defaultValue: null)); + properties.add(EnumProperty('fit', fit, defaultValue: null)); + properties.add( + DiagnosticsProperty( + 'alignment', + alignment, + defaultValue: null, + ), + ); + } +} diff --git a/lottie/lib/src/render_cache.dart b/lottie/lib/src/render_cache.dart new file mode 100644 index 0000000..ad58895 --- /dev/null +++ b/lottie/lib/src/render_cache.dart @@ -0,0 +1,34 @@ +import 'dart:ui'; +import 'package:flutter/material.dart' show RenderBox; +import '../lottie.dart'; +import 'render_cache/store_drawing.dart'; +import 'render_cache/store_raster.dart'; + +abstract class RenderCache { + /// The frames stored in the cache are fully rasterized. This is the most efficient + /// to render but will use the most memory. + /// This should only be used for very short and very small animations (final size on the screen). + static const raster = RenderCacheRaster(maxMemory: 50000000); + + /// The frames are stored as [dart:ui.Picture] in the cache. + /// It will will spare the CPU work for each frame. The GPU work will be the same as without cache. + static const drawingCommands = RenderCacheDrawing(); + + AnimationCache acquire(Object user); + + void release(Object user); +} + +abstract class AnimationCache { + bool draw( + LottieDrawable drawable, + double progress, + Canvas canvas, { + required Offset destinationPosition, + required Rect destinationRect, + required Rect sourceRect, + required Size sourceSize, + required RenderBox renderBox, + required double devicePixelRatio, + }); +} diff --git a/lottie/lib/src/render_cache/key.dart b/lottie/lib/src/render_cache/key.dart new file mode 100644 index 0000000..79c773b --- /dev/null +++ b/lottie/lib/src/render_cache/key.dart @@ -0,0 +1,37 @@ +import 'dart:ui'; +import 'package:flutter/foundation.dart'; +import '../composition.dart'; +import '../utils.dart'; + +@immutable +class CacheKey { + final LottieComposition composition; + final Size size; + final List config; + final int delegates; + + CacheKey({ + required this.composition, + required this.size, + required this.config, + required this.delegates, + }) : assert( + size.width == size.width.toInt() && size.height == size.height.toInt(), + ); + + @override + int get hashCode => + Object.hash(composition, size, Object.hashAll(config), delegates); + + @override + bool operator ==(other) => + other is CacheKey && + other.composition == composition && + other.size == size && + const ListEquality().equals(other.config, config) && + other.delegates == delegates; + + @override + String toString() => + 'CacheKey(${composition.hashCode}, $size, $config, $delegates)'; +} diff --git a/lottie/lib/src/render_cache/store.dart b/lottie/lib/src/render_cache/store.dart new file mode 100644 index 0000000..8f06b7c --- /dev/null +++ b/lottie/lib/src/render_cache/store.dart @@ -0,0 +1,63 @@ +abstract class Store, TCacheKey> { + final entries = {}; + final handles = >{}; + + bool shouldRemove(TEntry entry) => entry.handles.isEmpty; + + TEntry createEntry(TCacheKey key); + + void _clearUnused() { + for (var entry in entries.entries.toList()) { + var key = entry.key; + var cache = entry.value; + + if (shouldRemove(cache)) { + cache.dispose(); + var found = entries.remove(key); + assert(found == cache); + } + } + } + + Handle acquire(Object user) { + var handle = handles[user] ??= Handle(this); + return handle; + } + + void release(Object user) { + var handle = handles.remove(user); + if (handle?._currentEntry case var currentEntry?) { + var removed = currentEntry.handles.remove(handle); + assert(removed); + _clearUnused(); + } + } +} + +class Handle, TCacheKey> { + final Store _cache; + TEntry? _currentEntry; + + Handle(this._cache); + + TEntry withKey(TCacheKey key) { + if (_currentEntry case var currentEntry? when currentEntry.key != key) { + _currentEntry = null; + currentEntry.handles.remove(this); + _cache._clearUnused(); + } + var entry = _cache.entries[key] ??= _cache.createEntry(key); + entry.handles.add(this); + _currentEntry = entry; + return entry; + } +} + +abstract base class CacheEntry { + final TCacheKey key; + final handles = {}; + + CacheEntry(this.key); + + void dispose(); +} diff --git a/lottie/lib/src/render_cache/store_drawing.dart b/lottie/lib/src/render_cache/store_drawing.dart new file mode 100644 index 0000000..ffebce9 --- /dev/null +++ b/lottie/lib/src/render_cache/store_drawing.dart @@ -0,0 +1,134 @@ +import 'dart:ui'; +import 'package:flutter/rendering.dart'; +import '../lottie_drawable.dart'; +import '../render_cache.dart'; +import 'key.dart'; +import 'store.dart'; + +final _stores = Expando(); + +class RenderCacheDrawing implements RenderCache { + const RenderCacheDrawing(); + + @override + AnimationCache acquire(Object user) { + var handle = store.acquire(user); + return DrawingAnimationCache(handle); + } + + @override + void release(Object user) { + store.release(user); + } + + DrawingStore get store => _stores[this] ??= DrawingStore(); +} + +class DrawingAnimationCache extends AnimationCache { + final Handle handle; + + DrawingAnimationCache(this.handle); + + @override + bool draw( + LottieDrawable drawable, + double progress, + Canvas canvas, { + required Offset destinationPosition, + required Rect destinationRect, + required Rect sourceRect, + required Size sourceSize, + required RenderBox renderBox, + required double devicePixelRatio, + }) { + var key = CacheKey( + composition: drawable.composition, + size: Size.zero, + config: drawable.configHash(), + delegates: drawable.delegatesHash(), + ); + var entry = handle.withKey(key); + + return entry.draw( + drawable, + progress, + canvas, + destinationPosition: destinationPosition, + destinationRect: destinationRect, + sourceRect: sourceRect, + sourceSize: sourceSize, + ); + } +} + +class DrawingStore extends Store { + @override + DrawingEntry createEntry(CacheKey key) { + return DrawingEntry(this, key); + } +} + +base class DrawingEntry extends CacheEntry { + final DrawingStore store; + final pictures = {}; + + DrawingEntry(this.store, super.key); + + Picture _record(void Function(Canvas) draw) { + var recorder = PictureRecorder(); + var canvas = Canvas(recorder); + draw(canvas); + return recorder.endRecording(); + } + + Picture? _pictureForProgress(double progress, void Function(Canvas) draw) { + var existing = pictures[progress]; + if (existing != null) { + return existing; + } + + var picture = _record(draw); + pictures[progress] = picture; + return picture; + } + + final _matrix = Matrix4.identity(); + + bool draw( + LottieDrawable drawable, + double progress, + Canvas canvas, { + required Offset destinationPosition, + required Rect destinationRect, + required Rect sourceRect, + required Size sourceSize, + }) { + var cachedImage = _pictureForProgress(progress, (cacheCanvas) { + drawable.compositionLayer.draw(cacheCanvas, _matrix, parentAlpha: 255); + }); + if (cachedImage != null) { + var destinationSize = destinationRect.size; + + canvas.save(); + canvas.translate(destinationRect.left, destinationRect.top); + canvas.scale( + destinationSize.width / sourceRect.width, + destinationSize.height / sourceRect.height, + ); + canvas.drawPicture(cachedImage); + canvas.restore(); + + return true; + } + + return false; + } + + @override + void dispose() { + for (var picture in pictures.values) { + picture.dispose(); + } + pictures.clear(); + } +} diff --git a/lottie/lib/src/render_cache/store_raster.dart b/lottie/lib/src/render_cache/store_raster.dart new file mode 100644 index 0000000..2ddf8a3 --- /dev/null +++ b/lottie/lib/src/render_cache/store_raster.dart @@ -0,0 +1,183 @@ +import 'dart:ui'; +import 'package:flutter/rendering.dart'; +import '../lottie_drawable.dart'; +import '../render_cache.dart'; +import 'key.dart'; +import 'store.dart'; + +final _stores = Expando(); + +class RenderCacheRaster implements RenderCache { + final int maxMemory; + + const RenderCacheRaster({required this.maxMemory}); + + @override + AnimationCache acquire(Object user) { + var handle = store.acquire(user); + return RasterAnimationCache(handle); + } + + @override + void release(Object user) { + store.release(user); + } + + RasterStore get store => _stores[this] ??= RasterStore(maxMemory); +} + +class RasterAnimationCache extends AnimationCache { + final Handle handle; + + RasterAnimationCache(this.handle); + + @override + bool draw( + LottieDrawable drawable, + double progress, + Canvas canvas, { + required Offset destinationPosition, + required Rect destinationRect, + required Rect sourceRect, + required Size sourceSize, + required RenderBox renderBox, + required double devicePixelRatio, + }) { + var rect = Rect.fromPoints( + renderBox.localToGlobal(destinationPosition), + renderBox.localToGlobal(destinationRect.bottomRight), + ); + var cacheImageSize = Size( + (rect.size.width * devicePixelRatio).roundToDouble(), + (rect.size.height * devicePixelRatio).roundToDouble(), + ); + + var key = CacheKey( + composition: drawable.composition, + size: cacheImageSize, + config: drawable.configHash(), + delegates: drawable.delegatesHash(), + ); + var entry = handle.withKey(key); + + return entry.draw( + drawable, + progress, + canvas, + destinationPosition: destinationPosition, + destinationRect: destinationRect, + sourceSize: sourceSize, + sourceRect: sourceRect, + ); + } +} + +class RasterStore extends Store { + final int maxMemory; + + RasterStore(this.maxMemory); + + int get totalMemory => entries.values.fold(0, (a, b) => a + b.currentMemory); + + int get imageCount => entries.values.expand((e) => e.images.values).length; + + void clear() { + for (var entry in entries.values) { + entry.clear(); + } + } + + @override + RasterEntry createEntry(CacheKey key) { + return RasterEntry(this, key); + } + + bool canUseMemory(int newMemory) { + return totalMemory + newMemory <= maxMemory; + } +} + +base class RasterEntry extends CacheEntry { + final RasterStore store; + final images = {}; + int currentMemory = 0; + + RasterEntry(this.store, super.key); + + Picture _record(void Function(Canvas) draw) { + var recorder = PictureRecorder(); + var canvas = Canvas(recorder); + draw(canvas); + return recorder.endRecording(); + } + + Image? imageForProgress(double progress, void Function(Canvas) draw) { + var existing = images[progress]; + if (existing != null) { + return existing; + } + + var size = key.size; + var newImageSize = size.width.round() * size.height.round(); + if (!store.canUseMemory(newImageSize)) { + return null; + } + + var picture = _record(draw); + var image = picture.toImageSync(size.width.round(), size.height.round()); + picture.dispose(); + images[progress] = image; + currentMemory += size.width.round() * size.height.round(); + return image; + } + + final _normalPaint = Paint(); + final _matrix = Matrix4.identity(); + + bool draw( + LottieDrawable drawable, + double progress, + Canvas canvas, { + required Offset destinationPosition, + required Rect destinationRect, + required Size sourceSize, + required Rect sourceRect, + }) { + var cacheImageSize = key.size; + + var cachedImage = imageForProgress(progress, (cacheCanvas) { + _matrix.setIdentity(); + _matrix.scaleByDouble( + cacheImageSize.width / sourceSize.width, + cacheImageSize.height / sourceSize.height, + cacheImageSize.width / sourceSize.width, + 1, + ); + drawable.compositionLayer.draw(cacheCanvas, _matrix, parentAlpha: 255); + }); + if (cachedImage != null) { + canvas.drawImageRect( + cachedImage, + Offset.zero & cacheImageSize, + destinationRect, + _normalPaint, + ); + return true; + } + + return false; + } + + void clear() { + for (var image in images.values) { + image.dispose(); + } + images.clear(); + currentMemory = 0; + } + + @override + void dispose() { + clear(); + } +} diff --git a/lottie/lib/src/render_lottie.dart b/lottie/lib/src/render_lottie.dart new file mode 100644 index 0000000..f23f655 --- /dev/null +++ b/lottie/lib/src/render_lottie.dart @@ -0,0 +1,310 @@ +import 'package:flutter/rendering.dart'; +import 'composition.dart'; +import 'frame_rate.dart'; +import 'lottie_delegates.dart'; +import 'lottie_drawable.dart'; +import 'render_cache.dart'; + +/// A Lottie animation in the render tree. +/// +/// The RenderLottie attempts to find a size for itself that fits in the given +/// constraints and preserves the composition's intrinsic aspect ratio. +class RenderLottie extends RenderBox { + RenderLottie({ + required LottieComposition? composition, + LottieDelegates? delegates, + bool? enableMergePaths, + bool? enableApplyingOpacityToLayers, + double progress = 0.0, + FrameRate? frameRate, + double? width, + double? height, + BoxFit? fit, + AlignmentGeometry alignment = Alignment.center, + FilterQuality? filterQuality, + RenderCache? renderCache, + required double devicePixelRatio, + }) : assert(progress >= 0.0 && progress <= 1.0), + assert( + renderCache == null || frameRate != FrameRate.max, + 'FrameRate.max cannot be used with a RenderCache ' + 'Use a specific frame rate. e.g. FrameRate(60)', + ), + _drawable = composition != null + ? (LottieDrawable(composition, frameRate: frameRate) + ..setProgress(progress) + ..delegates = delegates + ..enableMergePaths = enableMergePaths ?? false + ..isApplyingOpacityToLayersEnabled = + enableApplyingOpacityToLayers ?? false + ..filterQuality = filterQuality) + : null, + _width = width, + _height = height, + _fit = fit, + _alignment = alignment, + _renderCache = renderCache, + _devicePixelRatio = devicePixelRatio; + + /// The lottie composition to display. + LottieComposition? get composition => _drawable?.composition; + LottieDrawable? _drawable; + + void setComposition( + LottieComposition? composition, { + required double progress, + required FrameRate? frameRate, + required LottieDelegates? delegates, + bool? enableMergePaths, + bool? enableApplyingOpacityToLayers, + FilterQuality? filterQuality, + }) { + var drawable = _drawable; + enableMergePaths ??= false; + enableApplyingOpacityToLayers ??= false; + + var needsLayout = false; + var needsPaint = false; + if (composition == null) { + if (drawable != null) { + drawable = _drawable = null; + needsPaint = true; + needsLayout = true; + } + } else { + if (drawable == null || + drawable.composition != composition || + drawable.frameRate != frameRate) { + drawable = _drawable = LottieDrawable( + composition, + frameRate: frameRate, + ); + needsLayout = true; + needsPaint = true; + } + + needsPaint |= drawable.setProgress(progress); + + if (drawable.delegates != delegates) { + drawable.delegates = delegates; + needsPaint = true; + } + if (enableMergePaths != drawable.enableMergePaths) { + drawable.enableMergePaths = enableMergePaths; + needsPaint = true; + } + if (enableApplyingOpacityToLayers != + drawable.isApplyingOpacityToLayersEnabled) { + drawable.isApplyingOpacityToLayersEnabled = + enableApplyingOpacityToLayers; + needsPaint = true; + } + if (filterQuality != drawable.filterQuality) { + drawable.filterQuality = filterQuality; + needsPaint = true; + } + } + + if (needsPaint) { + markNeedsPaint(); + } + if (needsLayout && (_width == null || _height == null)) { + markNeedsLayout(); + } + } + + /// If non-null, requires the composition to have this width. + /// + /// If null, the composition will pick a size that best preserves its intrinsic + /// aspect ratio. + double? get width => _width; + double? _width; + + set width(double? value) { + if (value == _width) { + return; + } + _width = value; + markNeedsLayout(); + } + + /// If non-null, require the composition to have this height. + /// + /// If null, the composition will pick a size that best preserves its intrinsic + /// aspect ratio. + double? get height => _height; + double? _height; + + set height(double? value) { + if (value == _height) { + return; + } + _height = value; + markNeedsLayout(); + } + + /// How to inscribe the composition into the space allocated during layout. + BoxFit? get fit => _fit; + BoxFit? _fit; + set fit(BoxFit? value) { + if (value == _fit) { + return; + } + _fit = value; + markNeedsPaint(); + } + + /// How to align the composition within its bounds. + AlignmentGeometry get alignment => _alignment; + AlignmentGeometry _alignment; + + set alignment(AlignmentGeometry value) { + if (value == _alignment) { + return; + } + _alignment = value; + markNeedsPaint(); + } + + RenderCache? get renderCache => _renderCache; + RenderCache? _renderCache; + set renderCache(RenderCache? value) { + if (value == _renderCache) { + return; + } + _renderCache?.release(this); + _renderCache = value; + markNeedsPaint(); + } + + double get devicePixelRatio => _devicePixelRatio; + double _devicePixelRatio; + set devicePixelRatio(double value) { + if (value == _devicePixelRatio) { + return; + } + _devicePixelRatio = value; + markNeedsPaint(); + } + + /// Find a size for the render composition within the given constraints. + /// + /// - The dimensions of the RenderLottie must fit within the constraints. + /// - The aspect ratio of the RenderLottie matches the intrinsic aspect + /// ratio of the Lottie animation. + /// - The RenderLottie's dimension are maximal subject to being smaller than + /// the intrinsic size of the composition. + Size _sizeForConstraints(BoxConstraints constraints) { + // Folds the given |width| and |height| into |constraints| so they can all + // be treated uniformly. + constraints = BoxConstraints.tightFor( + width: _width, + height: _height, + ).enforce(constraints); + + if (_drawable == null) { + return constraints.smallest; + } + + return constraints.constrainSizeAndAttemptToPreserveAspectRatio( + _drawable!.size, + ); + } + + @override + double computeMinIntrinsicWidth(double height) { + assert(height >= 0.0); + if (_width == null && _height == null) { + return 0.0; + } + return _sizeForConstraints( + BoxConstraints.tightForFinite(height: height), + ).width; + } + + @override + double computeMaxIntrinsicWidth(double height) { + assert(height >= 0.0); + return _sizeForConstraints( + BoxConstraints.tightForFinite(height: height), + ).width; + } + + @override + double computeMinIntrinsicHeight(double width) { + assert(width >= 0.0); + if (_width == null && _height == null) { + return 0.0; + } + return _sizeForConstraints( + BoxConstraints.tightForFinite(width: width), + ).height; + } + + @override + double computeMaxIntrinsicHeight(double width) { + assert(width >= 0.0); + return _sizeForConstraints( + BoxConstraints.tightForFinite(width: width), + ).height; + } + + @override + bool hitTestSelf(Offset position) => true; + + @override + Size computeDryLayout(BoxConstraints constraints) { + return _sizeForConstraints(constraints); + } + + @override + void performLayout() { + size = _sizeForConstraints(constraints); + } + + @override + void paint(PaintingContext context, Offset offset) { + if (_drawable == null) return; + + RenderCacheContext? cacheContext; + if (_renderCache case var renderCache?) { + cacheContext = RenderCacheContext( + cache: renderCache.acquire(this), + devicePixelRatio: _devicePixelRatio, + renderBox: this, + ); + } + + _drawable!.draw( + context.canvas, + offset & size, + fit: _fit, + alignment: _alignment.resolve(TextDirection.ltr), + renderCache: cacheContext, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add( + DiagnosticsProperty('composition', composition), + ); + properties.add(DoubleProperty('width', width, defaultValue: null)); + properties.add(DoubleProperty('height', height, defaultValue: null)); + properties.add(EnumProperty('fit', fit, defaultValue: null)); + properties.add( + DiagnosticsProperty( + 'alignment', + alignment, + defaultValue: null, + ), + ); + } + + @override + void dispose() { + _renderCache?.release(this); + super.dispose(); + } +} diff --git a/lottie/lib/src/utils.dart b/lottie/lib/src/utils.dart new file mode 100644 index 0000000..c4f0884 --- /dev/null +++ b/lottie/lib/src/utils.dart @@ -0,0 +1,104 @@ +import 'dart:math'; +import 'package:flutter/rendering.dart'; +import 'package:vector_math/vector_math_64.dart'; + +extension PaintExtension on Paint { + void setAlpha(int alpha) { + color = color.withAlpha(alpha); + } +} + +extension PathExtension on Path { + void set(Path path) { + reset(); + addPath(path, Offset.zero); + } + + void offset(Offset offset) { + set(shift(offset)); + } +} + +extension Matrix4Extension on Matrix4 { + void preConcat(Matrix4 matrix) { + multiply(matrix); + } + + void reset() { + setIdentity(); + } + + void set(Matrix4 matrix) { + matrix.copyInto(this); + } + + Rect mapRect(Rect rect) { + return MatrixUtils.transformRect(this, rect); + } + + /// Apply this matrix to the array of 2D points, and write the transformed points back into the + /// array + /// + /// @param pts The array [x0, y0, x1, y1, ...] of points to transform. + void mapPoints(List array) { + for (var i = 0; i < array.length; i += 2) { + final v = MatrixUtils.transformPoint( + this, + Offset(array[i], array[i + 1]), + ); + + array[i] = v.dx; + array[i + 1] = v.dy; + } + } + + double getScale() { + var p0 = Vector3(0, 0, 0)..applyMatrix4(this); + var p1 = Vector3(1 / sqrt(2), 1 / sqrt(2), 0)..applyMatrix4(this); + + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + + return hypot(dx, dy).toDouble(); + } + + bool get hasZeroScaleAxis { + var p0 = Vector3(0, 0, 0)..applyMatrix4(this); + // Random numbers. The only way these should map to the same thing as 0,0 is if the scale is 0. + var p1 = Vector3(37394.729378, 39575.2343807, 0)..applyMatrix4(this); + + return p0.x == p1.x || p0.y == p1.y; + } +} + +extension OffsetExtension on Offset { + bool get isZero => dx == 0 && dy == 0; +} + +num hypot(num x, num y) { + return sqrt(x * x + y * y); +} + +extension IterableExtension on Iterable { + T? firstWhereOrNull(bool Function(T element) test) { + for (var element in this) { + if (test(element)) return element; + } + return null; + } +} + +class ListEquality { + const ListEquality(); + + bool equals(List? list1, List? list2) { + if (identical(list1, list2)) return true; + if (list1 == null || list2 == null) return false; + var length = list1.length; + if (length != list2.length) return false; + for (var i = 0; i < length; i++) { + if (list1[i] != list2[i]) return false; + } + return true; + } +} diff --git a/lottie/lib/src/utils/characters.dart b/lottie/lib/src/utils/characters.dart new file mode 100644 index 0000000..95fa02f --- /dev/null +++ b/lottie/lib/src/utils/characters.dart @@ -0,0 +1,27 @@ +import 'package:flutter/widgets.dart'; + +extension CharactersExtension on Characters { + Characters trimTrailing(Characters pattern) { + if (pattern.isEmpty) return this; + + var i = length; + while (i >= pattern.length && getRange(i - pattern.length, i) == pattern) { + i -= pattern.length; + } + return getRange(0, i); + } + + Characters trimLeading(Characters pattern) { + if (pattern.isEmpty) return this; + var i = 0; + while (i <= length - pattern.length && + getRange(i, i + pattern.length) == pattern) { + i += pattern.length; + } + return getRange(i); + } + + Characters trim(Characters pattern) { + return trimLeading(pattern).trimTrailing(pattern); + } +} diff --git a/lottie/lib/src/utils/collection.dart b/lottie/lib/src/utils/collection.dart new file mode 100644 index 0000000..f344d2b --- /dev/null +++ b/lottie/lib/src/utils/collection.dart @@ -0,0 +1,69 @@ +/// Returns a position of the [value] in [sortedList], if it is there. +/// +/// If the list isn't sorted according to the [compare] function, the result +/// is unpredictable. +/// +/// If [compare] is omitted, this defaults to calling [Comparable.compareTo] on +/// the objects. In this case, the objects must be [Comparable]. +/// +/// Returns -1 if [value] is not in the list. +int binarySearch( + List sortedList, + E value, { + int Function(E, E)? compare, +}) { + compare ??= defaultCompare; + return binarySearchBy(sortedList, identity, compare, value); +} + +/// Returns a position of the [value] in [sortedList], if it is there. +/// +/// If the list isn't sorted according to the [compare] function on the [keyOf] +/// property of the elements, the result is unpredictable. +/// +/// Returns -1 if [value] is not in the list by default. +/// +/// If [start] and [end] are supplied, only that range is searched, +/// and only that range need to be sorted. +int binarySearchBy( + List sortedList, + K Function(E element) keyOf, + int Function(K, K) compare, + E value, [ + int start = 0, + int? end, +]) { + end = RangeError.checkValidRange(start, end, sortedList.length); + var min = start; + var max = end; + var key = keyOf(value); + while (min < max) { + var mid = min + ((max - min) >> 1); + var element = sortedList[mid]; + var comp = compare(keyOf(element), key); + if (comp == 0) return mid; + if (comp < 0) { + min = mid + 1; + } else { + max = mid; + } + } + return -1; +} + +/// A [Comparator] that asserts that its first argument is comparable. +/// +/// The function behaves just like [List.sort]'s +/// default comparison function. It is entirely dynamic in its testing. +/// +/// Should be used when optimistically comparing object that are assumed +/// to be comparable. +/// If the elements are known to be comparable, use [compareComparable]. +int defaultCompare(Object? value1, Object? value2) => + (value1! as Comparable).compareTo(value2); + +/// A reusable identity function at any type. +T identity(T value) => value; + +/// A reusable typed comparable comparator. +int compareComparable>(T a, T b) => a.compareTo(b); diff --git a/lottie/lib/src/utils/dash_path.dart b/lottie/lib/src/utils/dash_path.dart new file mode 100644 index 0000000..4b59ed4 --- /dev/null +++ b/lottie/lib/src/utils/dash_path.dart @@ -0,0 +1,43 @@ +import 'dart:math'; +import 'dart:ui'; + +Path dashPath(Path source, {required List intervals, double? phase}) { + assert(intervals.length >= 2); + phase ??= 0; + + var dest = Path(); + for (final metric in source.computeMetrics()) { + for (var dash in _dashes(metric.length, intervals, phase)) { + dest.addPath(metric.extractPath(dash.left, dash.right), Offset.zero); + } + } + + return dest; +} + +Iterable _dashes( + double length, + List intervals, + double phase, +) sync* { + var intervalLength = intervals.fold(0, (a, b) => a + b); + + var distance = 0.0; + while (distance < length) { + var position = (distance + phase) % intervalLength; + var end = 0.0; + for (var i = 0; i < intervals.length; i++) { + end += intervals[i]; + if (end > position || i == intervals.length - 1) { + var offset = max(0.1, end - position); + + if (i.isEven) { + yield Rect.fromLTRB(distance, 0, min(length, distance + offset), 0); + } + + distance += offset; + break; + } + } + } +} diff --git a/lottie/lib/src/utils/gamma_evaluator.dart b/lottie/lib/src/utils/gamma_evaluator.dart new file mode 100644 index 0000000..45ce95f --- /dev/null +++ b/lottie/lib/src/utils/gamma_evaluator.dart @@ -0,0 +1,72 @@ +import 'dart:math'; +import 'dart:ui'; + +/// Use this instead of {@link android.animation.ArgbEvaluator} because it interpolates through the gamma color +/// space which looks better to us humans. +///

+/// Written by Romain Guy and Francois Blavoet. +/// https://androidstudygroup.slack.com/archives/animation/p1476461064000335 +class GammaEvaluator { + // Opto-electronic conversion function for the sRGB color space + // Takes a gamma-encoded sRGB value and converts it to a linear sRGB value + static double _oecfSRgb(double linear) { + // IEC 61966-2-1:1999 + return linear <= 0.0031308 + ? linear * 12.92 + : ((pow(linear, 1.0 / 2.4) * 1.055) - 0.055); + } + + // Electro-optical conversion function for the sRGB color space + // Takes a linear sRGB value and converts it to a gamma-encoded sRGB value + static double _eocfSRgb(double srgb) { + // IEC 61966-2-1:1999 + return srgb <= 0.04045 + ? srgb / 12.92 + : pow((srgb + 0.055) / 1.055, 2.4).toDouble(); + } + + static Color evaluate(double fraction, Color startColor, Color endColor) { + // Fast return in case start and end is the same + // or if fraction is at start/end or out of [0,1] bounds + if (startColor == endColor) { + return startColor; + } else if (fraction <= 0) { + return startColor; + } else if (fraction >= 1) { + return endColor; + } + + var startA = startColor.a; + var startR = startColor.r; + var startG = startColor.g; + var startB = startColor.b; + + var endA = endColor.a; + var endR = endColor.r; + var endG = endColor.g; + var endB = endColor.b; + + // convert from sRGB to linear + startR = _eocfSRgb(startR); + startG = _eocfSRgb(startG); + startB = _eocfSRgb(startB); + + endR = _eocfSRgb(endR); + endG = _eocfSRgb(endG); + endB = _eocfSRgb(endB); + + // compute the interpolated color in linear space + var a = startA + fraction * (endA - startA); + var r = startR + fraction * (endR - startR); + var g = startG + fraction * (endG - startG); + var b = startB + fraction * (endB - startB); + + // convert back to sRGB in the [0..255] range + a = a * 255.0; + r = _oecfSRgb(r) * 255.0; + g = _oecfSRgb(g) * 255.0; + b = _oecfSRgb(b) * 255.0; + + return Color.fromARGB(a.round(), r.round(), g.round(), b.round()); + } +} diff --git a/lottie/lib/src/utils/mean_calculator.dart b/lottie/lib/src/utils/mean_calculator.dart new file mode 100644 index 0000000..aac44bc --- /dev/null +++ b/lottie/lib/src/utils/mean_calculator.dart @@ -0,0 +1,11 @@ +class MeanCalculator { + double _sum = 0; + int _n = 0; + + double get mean => _n == 0 ? 0 : _sum / _n; + + void add(double number) { + _sum += number; + _n++; + } +} diff --git a/lottie/lib/src/utils/misc.dart b/lottie/lib/src/utils/misc.dart new file mode 100644 index 0000000..328b009 --- /dev/null +++ b/lottie/lib/src/utils/misc.dart @@ -0,0 +1,121 @@ +import 'dart:ui'; +import '../animation/content/key_path_element_content.dart'; +import '../model/content/shape_data.dart'; +import '../model/key_path.dart'; + +class MiscUtils { + static void getPathFromData(ShapeData shapeData, Path outPath) { + outPath.reset(); + var initialPoint = shapeData.initialPoint; + outPath.moveTo(initialPoint.dx, initialPoint.dy); + var currentPoint = initialPoint; + + for (var i = 0; i < shapeData.curves.length; i++) { + var curveData = shapeData.curves[i]; + var cp1 = curveData.controlPoint1; + var cp2 = curveData.controlPoint2; + var vertex = curveData.vertex; + + if (cp1 == currentPoint && cp2 == vertex) { + // On some phones like Samsung phones, zero valued control points can cause artifacting. + // https://github.com/airbnb/lottie-android/issues/275 + // + // This does its best to add a tiny value to the vertex without affecting the final + // animation as much as possible. + // outPath.rMoveTo(0.01f, 0.01f); + outPath.lineTo(vertex.dx, vertex.dy); + } else { + outPath.cubicTo(cp1.dx, cp1.dy, cp2.dx, cp2.dy, vertex.dx, vertex.dy); + } + currentPoint = vertex; + } + if (shapeData.isClosed) { + outPath.close(); + } + } + + static bool isAtLeastVersion( + int major, + int minor, + int patch, + int minMajor, + int minMinor, + int minPatch, + ) { + if (major < minMajor) { + return false; + } else if (major > minMajor) { + return true; + } + + if (minor < minMinor) { + return false; + } else if (minor > minMinor) { + return true; + } + + return patch >= minPatch; + } + + static Color parseColor( + String colorString, { + required void Function(String) warningCallback, + }) { + if (colorString.isNotEmpty && colorString[0] == '#') { + // Use a long to avoid rollovers on #ffXXXXXX + var color = int.parse(colorString.substring(1), radix: 16); + if (colorString.length == 7) { + // Set the alpha value + color |= 0x00000000ff000000; + } else if (colorString.length != 9) { + warningCallback('Unknown color colorString: $colorString'); + return const Color(0xffffffff); + } + return Color(color); + } + warningCallback( + 'Unknown colorString is empty or format incorrect: $colorString', + ); + return const Color(0xffffffff); + } + + static int floorMod(double x, double y) { + var xInt = x.toInt(); + var yInt = y.toInt(); + return xInt - yInt * _floorDiv(xInt, yInt); + } + + static int floorModInt(int x, int y) { + return x - y * _floorDiv(x, y); + } + + static int _floorDiv(int x, int y) { + var r = x ~/ y; + var sameSign = x.sign == y.sign; + + var mod = x % y; + if (!sameSign && mod != 0) { + r--; + } + return r; + } + + /// Helper method for any {@link KeyPathElementContent} that will check if the content + /// fully matches the keypath then will add itself as the final key, resolve it, and add + /// it to the accumulator list. + /// + /// Any {@link KeyPathElementContent} should call through to this as its implementation of + /// {KeyPathElementContent#resolveKeyPath(KeyPath, int, List, KeyPath)}. + static void resolveKeyPath( + KeyPath keyPath, + int depth, + List accumulator, + KeyPath currentPartialKeyPath, + KeyPathElementContent content, + ) { + if (keyPath.fullyResolvesTo(content.name, depth)) { + currentPartialKeyPath = currentPartialKeyPath.addKey(content.name!); + accumulator.add(currentPartialKeyPath.resolve(content)); + } + } +} diff --git a/lottie/lib/src/utils/pair.dart b/lottie/lib/src/utils/pair.dart new file mode 100644 index 0000000..a77529a --- /dev/null +++ b/lottie/lib/src/utils/pair.dart @@ -0,0 +1,6 @@ +class Pair { + final T first; + final U second; + + Pair(this.first, this.second); +} diff --git a/lottie/lib/src/utils/path_interpolator.dart b/lottie/lib/src/utils/path_interpolator.dart new file mode 100644 index 0000000..038afa6 --- /dev/null +++ b/lottie/lib/src/utils/path_interpolator.dart @@ -0,0 +1,88 @@ +import 'dart:ui'; +import 'package:flutter/animation.dart'; + +// ignore: must_be_immutable +class PathInterpolator extends Curve { + /// Governs the accuracy of the approximation of the {@link Path}. + static const double _precision = 0.002; + + late final List _mX; + late final List _mY; + bool _isInitialized = false; + + final double controlX1, controlY1, controlX2, controlY2; + + PathInterpolator.cubic( + this.controlX1, + this.controlY1, + this.controlX2, + this.controlY2, + ); + + void _ensureInitialized() { + if (_isInitialized) { + return; + } + _initialize(); + _isInitialized = true; + } + + void _initialize() { + final path = Path(); + path.moveTo(0.0, 0.0); + path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0, 1.0); + + final pathMeasure = path.computeMetrics().toList().first; + + final pathLength = pathMeasure.length; + final numPoints = (pathLength / _precision).round() + 1; + + var mX = List.filled(numPoints, 0.0); + var mY = List.filled(numPoints, 0.0); + + for (var i = 0; i < numPoints; ++i) { + final distance = (i * pathLength) / (numPoints - 1); + var tangent = pathMeasure.getTangentForOffset(distance)!; + + mX[i] = tangent.position.dx; + mY[i] = tangent.position.dy; + } + _mX = mX; + _mY = mY; + } + + @override + double transform(double t) { + _ensureInitialized(); + if (t <= 0.0) { + return 0.0; + } else if (t >= 1.0) { + return 1.0; + } + + // Do a binary search for the correct x to interpolate between. + var startIndex = 0; + var endIndex = _mX.length - 1; + while (endIndex - startIndex > 1) { + var midIndex = ((startIndex + endIndex) / 2).round(); + if (t < _mX[midIndex]) { + endIndex = midIndex; + } else { + startIndex = midIndex; + } + } + + final xRange = _mX[endIndex] - _mX[startIndex]; + if (xRange == 0) { + return _mY[startIndex]; + } + + final tInRange = t - _mX[startIndex]; + final fraction = tInRange / xRange; + + final startY = _mY[startIndex]; + final endY = _mY[endIndex]; + + return startY + (fraction * (endY - startY)); + } +} diff --git a/lottie/lib/src/utils/utils.dart b/lottie/lib/src/utils/utils.dart new file mode 100644 index 0000000..f13a023 --- /dev/null +++ b/lottie/lib/src/utils/utils.dart @@ -0,0 +1,134 @@ +import 'dart:math'; +import 'dart:ui'; +import '../animation/content/trim_path_content.dart'; +import '../l.dart'; +import '../utils.dart'; +import 'misc.dart'; + +class Utils { + static Path createPath( + Offset startPoint, + Offset endPoint, + Offset? cp1, + Offset? cp2, + ) { + var path = Path(); + path.moveTo(startPoint.dx, startPoint.dy); + + if (cp1 != null && + cp2 != null && + (cp1.distance != 0 || cp2.distance != 0)) { + path.cubicTo( + startPoint.dx + cp1.dx, + startPoint.dy + cp1.dy, + endPoint.dx + cp2.dx, + endPoint.dy + cp2.dy, + endPoint.dx, + endPoint.dy, + ); + } else { + path.lineTo(endPoint.dx, endPoint.dy); + } + return path; + } + + static int hashFor(double a, double b, double c, double d) { + var result = 17; + if (a != 0) { + result = (31 * result * a).round(); + } + if (b != 0) { + result = (31 * result * b).round(); + } + if (c != 0) { + result = (31 * result * c).round(); + } + if (d != 0) { + result = (31 * result * d).round(); + } + return result; + } + + static void applyTrimPathContentIfNeeded( + Path path, + TrimPathContent? trimPath, + ) { + if (trimPath == null || trimPath.hidden) { + return; + } + var start = trimPath.start.value; + var end = trimPath.end.value; + var offset = trimPath.offset.value; + applyTrimPathIfNeeded(path, start / 100.0, end / 100.0, offset / 360.0); + } + + static void applyTrimPathIfNeeded( + Path path, + double startValue, + double endValue, + double offsetValue, + ) { + L.beginSection('applyTrimPathIfNeeded'); + var metrics = path.computeMetrics().toList(); + if (metrics.isEmpty) { + L.endSection('applyTrimPathIfNeeded'); + return; + } + + var pathMeasure = metrics.first; + + if (startValue == 1.0 && endValue == 0.0) { + L.endSection('applyTrimPathIfNeeded'); + return; + } + var length = pathMeasure.length; + if (length < 1.0 || (endValue - startValue - 1).abs() < .01) { + L.endSection('applyTrimPathIfNeeded'); + return; + } + var start = length * startValue; + var end = length * endValue; + var newStart = min(start, end); + var newEnd = max(start, end); + + var offset = offsetValue * length; + newStart += offset; + newEnd += offset; + + // If the trim path has rotated around the path, we need to shift it back. + if (newStart >= length && newEnd >= length) { + newStart = MiscUtils.floorMod(newStart, length).toDouble(); + newEnd = MiscUtils.floorMod(newEnd, length).toDouble(); + } + + if (newStart < 0) { + newStart = MiscUtils.floorMod(newStart, length).toDouble(); + } + if (newEnd < 0) { + newEnd = MiscUtils.floorMod(newEnd, length).toDouble(); + } + + // If the start and end are equals, return an empty path. + if (newStart == newEnd) { + path.reset(); + L.endSection('applyTrimPathIfNeeded'); + return; + } + + if (newStart >= newEnd) { + newStart -= length; + } + + var tempPath = pathMeasure.extractPath(newStart, newEnd); + + if (newEnd > length) { + var tempPath2 = pathMeasure.extractPath(0, newEnd % length); + tempPath.addPath(tempPath2, Offset.zero); + } else if (newStart < 0) { + var tempPath2 = pathMeasure.extractPath(length + newStart, length); + tempPath.addPath(tempPath2, Offset.zero); + } + path.set(tempPath); + L.endSection('applyTrimPathIfNeeded'); + } +} diff --git a/lottie/lib/src/value/drop_shadow.dart b/lottie/lib/src/value/drop_shadow.dart new file mode 100644 index 0000000..4a1c302 --- /dev/null +++ b/lottie/lib/src/value/drop_shadow.dart @@ -0,0 +1,48 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/painting.dart'; + +@immutable +class DropShadow { + final Color color; + final double direction; + final double distance; + final double radius; + + const DropShadow({ + required this.color, + required this.direction, + required this.distance, + required this.radius, + }); + + DropShadow copyWith({ + Color? color, + double? direction, + double? distance, + double? radius, + }) { + return DropShadow( + color: color ?? this.color, + direction: direction ?? this.direction, + distance: distance ?? this.distance, + radius: radius ?? this.radius, + ); + } + + @override + bool operator ==(other) { + return other is DropShadow && + other.color == color && + other.direction == direction && + other.distance == distance && + other.radius == radius; + } + + @override + int get hashCode => Object.hash(color, direction, distance, radius); + + @override + String toString() => + 'DropShadow(color: $color, direction: $direction, ' + 'distance: $distance, radius: $radius)'; +} diff --git a/lottie/lib/src/value/keyframe.dart b/lottie/lib/src/value/keyframe.dart new file mode 100644 index 0000000..b219aef --- /dev/null +++ b/lottie/lib/src/value/keyframe.dart @@ -0,0 +1,103 @@ +import 'package:flutter/animation.dart'; +import '../composition.dart'; + +class Keyframe { + final LottieComposition? _composition; + final T? startValue; + T? endValue; + final Curve? interpolator; + final Curve? xInterpolator; + final Curve? yInterpolator; + final double startFrame; + double? endFrame; + + double _startProgress = double.minPositive; + double _endProgress = double.minPositive; + + // Used by PathKeyframe but it has to be parsed by KeyFrame because we use a JsonReader to + // deserialzie the data so we have to parse everything in order + Offset? pathCp1; + Offset? pathCp2; + + Keyframe( + this._composition, { + required this.startValue, + this.endValue, + this.interpolator, + this.xInterpolator, + this.yInterpolator, + double? startFrame, + this.endFrame, + }) : startFrame = startFrame ?? 0.0; + + /// Non-animated value. + Keyframe.nonAnimated(T value) + : _composition = null, + startValue = value, + endValue = value, + interpolator = null, + startFrame = double.minPositive, + endFrame = double.maxFinite, + xInterpolator = null, + yInterpolator = null; + + Keyframe._(this.startValue, this.endValue) + : _composition = null, + interpolator = null, + xInterpolator = null, + yInterpolator = null, + startFrame = double.minPositive, + endFrame = double.maxFinite; + + Keyframe copyWith(T startValue, T endValue) { + return Keyframe._(startValue, endValue); + } + + double get startProgress { + if (_composition == null) { + return 0.0; + } + if (_startProgress == double.minPositive) { + _startProgress = + (startFrame - _composition.startFrame) / _composition.durationFrames; + } + return _startProgress; + } + + double get endProgress { + if (_composition == null) { + return 1.0; + } + if (_endProgress == double.minPositive) { + if (endFrame == null) { + _endProgress = 1.0; + } else { + var durationFrames = endFrame! - startFrame; + var durationProgress = durationFrames / _composition.durationFrames; + _endProgress = startProgress + durationProgress; + } + } + return _endProgress; + } + + bool get isStatic { + return interpolator == null && + xInterpolator == null && + yInterpolator == null; + } + + bool containsProgress(double progress) { + return progress >= startProgress && progress < endProgress; + } + + @override + String toString() { + return 'Keyframe{' + 'startValue=$startValue' + ', endValue=$endValue' + ', startFrame=$startFrame' + ', endFrame=$endFrame' + ', interpolator=$interpolator' + '}'; + } +} diff --git a/lottie/lib/src/value/lottie_frame_info.dart b/lottie/lib/src/value/lottie_frame_info.dart new file mode 100644 index 0000000..fde77ac --- /dev/null +++ b/lottie/lib/src/value/lottie_frame_info.dart @@ -0,0 +1,20 @@ +/// Data class for use with {@link LottieValueCallback}. +class LottieFrameInfo { + final double startFrame; + final double? endFrame; + final T? startValue; + final T? endValue; + final double linearKeyframeProgress; + final double interpolatedKeyframeProgress; + final double overallProgress; + + LottieFrameInfo( + this.startFrame, + this.endFrame, + this.startValue, + this.endValue, + this.linearKeyframeProgress, + this.interpolatedKeyframeProgress, + this.overallProgress, + ); +} diff --git a/lottie/lib/src/value/lottie_relative_double_value_callback.dart b/lottie/lib/src/value/lottie_relative_double_value_callback.dart new file mode 100644 index 0000000..58d0f47 --- /dev/null +++ b/lottie/lib/src/value/lottie_relative_double_value_callback.dart @@ -0,0 +1,16 @@ +import 'dart:ui'; +import 'lottie_frame_info.dart'; + +double Function(LottieFrameInfo) relativeDoubleValueCallback( + double offset, +) { + return (LottieFrameInfo frameInfo) { + var originalValue = lerpDouble( + frameInfo.startValue, + frameInfo.endValue, + frameInfo.interpolatedKeyframeProgress, + )!; + + return originalValue + offset; + }; +} diff --git a/lottie/lib/src/value/lottie_relative_integer_value_callback.dart b/lottie/lib/src/value/lottie_relative_integer_value_callback.dart new file mode 100644 index 0000000..f1c7097 --- /dev/null +++ b/lottie/lib/src/value/lottie_relative_integer_value_callback.dart @@ -0,0 +1,14 @@ +import 'dart:ui'; +import 'lottie_frame_info.dart'; + +int Function(LottieFrameInfo) relativeIntegerValueCallback(int offset) { + return (LottieFrameInfo frameInfo) { + var originalValue = lerpDouble( + frameInfo.startValue, + frameInfo.endValue, + frameInfo.interpolatedKeyframeProgress, + )!; + + return (originalValue + offset).round(); + }; +} diff --git a/lottie/lib/src/value/lottie_relative_point_value_callback.dart b/lottie/lib/src/value/lottie_relative_point_value_callback.dart new file mode 100644 index 0000000..71b9b40 --- /dev/null +++ b/lottie/lib/src/value/lottie_relative_point_value_callback.dart @@ -0,0 +1,16 @@ +import 'dart:ui'; +import 'lottie_frame_info.dart'; + +Offset Function(LottieFrameInfo) relativeOffsetValueCallback( + Offset offset, +) { + return (LottieFrameInfo frameInfo) { + var point = Offset.lerp( + frameInfo.startValue, + frameInfo.endValue, + frameInfo.interpolatedKeyframeProgress, + )!; + + return point.translate(offset.dx, offset.dy); + }; +} diff --git a/lottie/lib/src/value/lottie_value_callback.dart b/lottie/lib/src/value/lottie_value_callback.dart new file mode 100644 index 0000000..842c3f2 --- /dev/null +++ b/lottie/lib/src/value/lottie_value_callback.dart @@ -0,0 +1,63 @@ +import '../animation/keyframe/base_keyframe_animation.dart'; +import 'lottie_frame_info.dart'; + +/// Allows you to set a callback on a resolved {@link com.airbnb.lottie.model.KeyPath} to modify +/// its animation values at runtime. +class LottieValueCallback { + LottieValueCallback(this._value); + + BaseKeyframeAnimation? _animation; + BaseKeyframeAnimation? get animation => _animation; + + /// This can be set with {@link #setValue(Object)} to use a value instead of deferring + /// to the callback. + ///*/ + T? _value; + T? get value => _value; + + T Function(LottieFrameInfo)? callback; + + /// Override this if you haven't set a static value in the constructor or with setValue. + /// + /// Return null to resort to the default value. + T? getValue(LottieFrameInfo frameInfo) { + if (callback != null) { + return callback!(frameInfo); + } + + return value; + } + + void setValue(T? value) { + _value = value; + if (_animation != null) { + _animation!.notifyListeners(); + } + } + + T? getValueInternal( + double startFrame, + double? endFrame, + T? startValue, + T? endValue, + double linearKeyframeProgress, + double interpolatedKeyframeProgress, + double overallProgress, + ) { + return getValue( + LottieFrameInfo( + startFrame, + endFrame, + startValue, + endValue, + linearKeyframeProgress, + interpolatedKeyframeProgress, + overallProgress, + ), + ); + } + + void setAnimation(BaseKeyframeAnimation? animation) { + _animation = animation; + } +} diff --git a/lottie/lib/src/value_delegate.dart b/lottie/lib/src/value_delegate.dart new file mode 100644 index 0000000..7bd6e53 --- /dev/null +++ b/lottie/lib/src/value_delegate.dart @@ -0,0 +1,471 @@ +import 'package:flutter/widgets.dart'; +import 'lottie_drawable.dart'; +import 'lottie_property.dart'; +import 'model/key_path.dart'; +import 'utils.dart'; +import 'value/drop_shadow.dart'; +import 'value/lottie_frame_info.dart'; +import 'value/lottie_relative_double_value_callback.dart'; +import 'value/lottie_relative_integer_value_callback.dart'; +import 'value/lottie_relative_point_value_callback.dart'; +import 'value/lottie_value_callback.dart'; + +class ValueDelegate { + final List keyPath; + final T property; + final T? value; + final T Function(LottieFrameInfo)? callback; + + ValueDelegate._(this.keyPath, this.property, this.value, this.callback) + : assert( + value == null || callback == null, + "Value and callback can't be both specified.", + ); + + int get callbackHash => callback.hashCode; + + static ValueDelegate _offset( + List keyPath, + Offset property, + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + ) { + if (relative != null) { + assert(callback == null); + callback = relativeOffsetValueCallback(relative); + } + return ValueDelegate._(keyPath, property, value, callback); + } + + static ValueDelegate _double( + List keyPath, + double property, + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + ) { + if (relative != null) { + assert(callback == null); + callback = relativeDoubleValueCallback(relative); + } + return ValueDelegate._(keyPath, property, value, callback); + } + + static ValueDelegate _int( + List keyPath, + int property, + int? value, + int Function(LottieFrameInfo)? callback, + int? relative, + ) { + if (relative != null) { + assert(callback == null); + callback = relativeIntegerValueCallback(relative); + } + return ValueDelegate._(keyPath, property, value, callback); + } + + static ValueDelegate color( + List keyPath, { + Color? value, + Color Function(LottieFrameInfo)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.color, value, callback); + + static ValueDelegate strokeColor( + List keyPath, { + Color? value, + Color Function(LottieFrameInfo)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.strokeColor, value, callback); + + /// Opacity value are 0-100 to match after effects + static ValueDelegate transformOpacity( + List keyPath, { + int? value, + int Function(LottieFrameInfo)? callback, + int? relative, + }) => + _int(keyPath, LottieProperty.transformOpacity, value, callback, relative); + + /// Opacity value are 0-100 to match after effects + static ValueDelegate opacity( + List keyPath, { + int? value, + int Function(LottieFrameInfo)? callback, + int? relative, + }) => _int(keyPath, LottieProperty.opacity, value, callback, relative); + + static ValueDelegate transformAnchorPoint( + List keyPath, { + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + }) { + return _offset( + keyPath, + LottieProperty.transformAnchorPoint, + value, + callback, + relative, + ); + } + + static ValueDelegate transformPosition( + List keyPath, { + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + }) => _offset( + keyPath, + LottieProperty.transformPosition, + value, + callback, + relative, + ); + + static ValueDelegate ellipseSize( + List keyPath, { + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + }) => _offset(keyPath, LottieProperty.ellipseSize, value, callback, relative); + + static ValueDelegate rectangleSize( + List keyPath, { + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + }) => + _offset(keyPath, LottieProperty.rectangleSize, value, callback, relative); + + static ValueDelegate cornerRadius( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => + _double(keyPath, LottieProperty.cornerRadius, value, callback, relative); + + static ValueDelegate position( + List keyPath, { + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + }) => _offset(keyPath, LottieProperty.position, value, callback, relative); + + static ValueDelegate transformScale( + List keyPath, { + Offset? value, + Offset Function(LottieFrameInfo)? callback, + Offset? relative, + }) => _offset( + keyPath, + LottieProperty.transformScale, + value, + callback, + relative, + ); + + /// In degrees + static ValueDelegate transformRotation( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.transformRotation, + value, + callback, + relative, + ); + + static ValueDelegate transformSkew( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => + _double(keyPath, LottieProperty.transformSkew, value, callback, relative); + + static ValueDelegate transformSkewAngle( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.transformSkewAngle, + value, + callback, + relative, + ); + + static ValueDelegate strokeWidth( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double(keyPath, LottieProperty.strokeWidth, value, callback, relative); + + static ValueDelegate textTracking( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => + _double(keyPath, LottieProperty.textTracking, value, callback, relative); + + static ValueDelegate repeaterCopies( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.repeaterCopies, + value, + callback, + relative, + ); + + static ValueDelegate repeaterOffset( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.repeaterOffset, + value, + callback, + relative, + ); + + static ValueDelegate polystarPoints( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.polystarPoints, + value, + callback, + relative, + ); + + /// In degrees + static ValueDelegate polystarRotation( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.polystarRotation, + value, + callback, + relative, + ); + + static ValueDelegate polystarInnerRadius( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.polystarInnerRadius, + value, + callback, + relative, + ); + + static ValueDelegate polystarOuterRadius( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.polystarOuterRadius, + value, + callback, + relative, + ); + + static ValueDelegate polystarInnerRoundedness( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.polystarInnerRoundedness, + value, + callback, + relative, + ); + + static ValueDelegate polystarOuterRoundedness( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.polystarOuterRoundedness, + value, + callback, + relative, + ); + + /// Opacity value are 0-100 to match after effects + static ValueDelegate transformStartOpacity( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.transformStartOpacity, + value, + callback, + relative, + ); + + /// Opacity value are 0-100 to match after effects + static ValueDelegate transformEndOpacity( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double( + keyPath, + LottieProperty.transformEndOpacity, + value, + callback, + relative, + ); + + /// The time value in seconds + static ValueDelegate timeRemap( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double(keyPath, LottieProperty.timeRemap, value, callback, relative); + + static ValueDelegate textSize( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + double? relative, + }) => _double(keyPath, LottieProperty.textSize, value, callback, relative); + + static ValueDelegate text( + List keyPath, { + String? value, + String Function(LottieFrameInfo)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.text, value, callback); + + static ValueDelegate colorFilter( + List keyPath, { + ColorFilter? value, + ColorFilter Function(LottieFrameInfo)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.colorFilter, value, callback); + + static ValueDelegate> gradientColor( + List keyPath, { + List? value, + List Function(LottieFrameInfo>)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.gradientColor, value, callback); + + static ValueDelegate blurRadius( + List keyPath, { + double? value, + double Function(LottieFrameInfo)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.blurRadius, value, callback); + + static ValueDelegate dropShadow( + List keyPath, { + DropShadow? value, + DropShadow Function(LottieFrameInfo)? callback, + }) => ValueDelegate._(keyPath, LottieProperty.dropShadow, value, callback); + + ResolvedValueDelegate? _resolved; + ResolvedValueDelegate _resolve(List resolvedPaths) { + _resolved = ResolvedValueDelegate(this, resolvedPaths); + return _resolved!; + } + + bool isSameProperty(ValueDelegate other) { + if (identical(this, other)) return true; + return other is ValueDelegate && + const ListEquality().equals(other.keyPath, keyPath) && + other.property == property; + } +} + +ResolvedValueDelegate internalResolved(ValueDelegate valueDelegate) { + return valueDelegate._resolved!; +} + +ResolvedValueDelegate internalResolve( + ValueDelegate delegate, + List resolvedPaths, +) { + return delegate._resolve(resolvedPaths); +} + +class ResolvedValueDelegate { + final ValueDelegate valueDelegate; + final List keyPaths; + final LottieValueCallback valueCallback; + + ResolvedValueDelegate(this.valueDelegate, this.keyPaths) + : valueCallback = LottieValueCallback(valueDelegate.value) + ..callback = valueDelegate.callback; + + T get property => valueDelegate.property; + + void updateDelegate(ValueDelegate delegate) { + valueCallback + ..setValue(delegate.value) + ..callback = delegate.callback; + } + + void clear() { + valueCallback + ..setValue(null) + ..callback = null; + } + + /// Add a property callback for the specified {@link KeyPath}. This {@link KeyPath} can resolve + /// to multiple contents. In that case, the callbacks's value will apply to all of them. + ///

+ /// Internally, this will check if the {@link KeyPath} has already been resolved with + /// {#resolveKeyPath(KeyPath)} and will resolve it if it hasn't. + void addValueCallback(LottieDrawable drawable) { + var invalidate = false; + if (valueDelegate.keyPath.isEmpty) { + drawable.compositionLayer.addValueCallback(property, valueCallback); + invalidate = true; + } else { + for (var keyPath in keyPaths) { + keyPath.resolvedElement!.addValueCallback(property, valueCallback); + invalidate = true; + } + } + if (invalidate) { + drawable.invalidateSelf(); + if (property == LottieProperty.timeRemap) { + // Time remapping values are read in setProgress. In order for the new value + // to apply, we have to re-set the progress with the current progress so that the + // time remapping can be reapplied. + drawable.setProgress(drawable.progress); + } + } + } +} diff --git a/lottie/pubspec.yaml b/lottie/pubspec.yaml new file mode 100644 index 0000000..e234f91 --- /dev/null +++ b/lottie/pubspec.yaml @@ -0,0 +1,29 @@ +name: lottie +description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player. +version: 3.3.2 +repository: https://github.com/xvrh/lottie-flutter + +funding: + - https://www.buymeacoffee.com/xvrh + - https://github.com/sponsors/xvrh + +environment: + sdk: '^3.9.0' + flutter: '>=3.35.0' + +dependencies: + archive: ^4.0.0 + flutter: + sdk: flutter + http: ^1.0.0 + path: ^1.8.0 + vector_math: ^2.1.0 + +dev_dependencies: + analyzer: + dart_style: + flutter_lints: + flutter_test: + sdk: flutter + pub_semver: + yaml: diff --git a/lottie/test/characters_test.dart b/lottie/test/characters_test.dart new file mode 100644 index 0000000..c8fade0 --- /dev/null +++ b/lottie/test/characters_test.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/src/utils/characters.dart'; + +void main() { + test('TrimTrailing characters', () { + expect( + 'ab c d '.characters.trimTrailing(' '.characters), + 'ab c d'.characters, + ); + expect(' '.characters.trimTrailing(' '.characters), ''.characters); + expect(' a '.characters.trimTrailing(' '.characters), ' a'.characters); + expect(' aa'.characters.trimTrailing('a'.characters), ' '.characters); + expect('aabcbc'.characters.trimTrailing('bc'.characters), 'aa'.characters); + expect('bcbc'.characters.trimTrailing('bc'.characters), ''.characters); + expect(''.characters.trimTrailing(' '.characters), ''.characters); + expect(''.characters.trimTrailing('bc'.characters), ''.characters); + expect(' '.characters.trimTrailing('bc'.characters), ' '.characters); + expect(' bc'.characters.trimTrailing('bc'.characters), ' '.characters); + }); + + test('TrimLeading characters', () { + expect(' ab '.characters.trimLeading(' '.characters), 'ab '.characters); + expect(' '.characters.trimLeading(' '.characters), ''.characters); + expect(' '.characters.trimLeading(' '.characters), ''.characters); + expect(' a'.characters.trimLeading(' '.characters), 'a'.characters); + expect('abc'.characters.trimLeading('ab'.characters), 'c'.characters); + expect('ababc'.characters.trimLeading('ab'.characters), 'c'.characters); + expect('abab'.characters.trimLeading('ab'.characters), ''.characters); + expect('ababcd'.characters.trimLeading('ab'.characters), 'cd'.characters); + expect(''.characters.trimLeading(''.characters), ''.characters); + }); + + test('Trim characters', () { + expect(' ab '.characters.trim(' '.characters), 'ab'.characters); + }); +} diff --git a/lottie/test/compositions_test.dart b/lottie/test/compositions_test.dart new file mode 100644 index 0000000..ca9c4ef --- /dev/null +++ b/lottie/test/compositions_test.dart @@ -0,0 +1,32 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/src/composition.dart'; +import 'package:lottie/src/lottie_drawable.dart'; +import 'package:path/path.dart' as p; + +void main() { + var assetsPath = 'example/assets'; + for (var file + in Directory(assetsPath) + .listSync(recursive: true) + .whereType() + .where((f) => f.path.endsWith('.json'))) { + test('Parse and draw ${p.relative(file.path, from: assetsPath)}', () async { + var composition = await LottieComposition.fromBytes( + file.readAsBytesSync(), + ); + expect(composition, isNotNull); + + var drawable = LottieDrawable(composition); + + var recorder = PictureRecorder(); + var canvas = Canvas(recorder); + for (var progress = 0; progress <= 100; progress += 20) { + drawable + ..setProgress(progress / 100) + ..draw(canvas, const Rect.fromLTWH(0, 0, 200, 200)); + } + }); + } +} diff --git a/lottie/test/data/loading_indicator.json b/lottie/test/data/loading_indicator.json new file mode 100644 index 0000000..f44b919 --- /dev/null +++ b/lottie/test/data/loading_indicator.json @@ -0,0 +1 @@ +{"v":"5.5.7","fr":29.9700012207031,"ip":35.0000014255792,"op":129.000005254278,"w":300,"h":300,"nm":"Box Icon_Test","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Kontur4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[95,95,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":3,"s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":45,"ix":4},"nm":"Rechteckpfad: 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666666667,0.839215746113,0.172549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16.5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Kontur 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Rechteck 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.801],"y":[0.742]},"o":{"x":[0.324],"y":[0]},"t":88,"s":[0]},{"t":127.000005172816,"s":[55]}],"ix":1},"e":{"a":0,"k":0,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.661]},"o":{"x":[0.175],"y":[0]},"t":90,"s":[-124]},{"i":{"x":[0.839],"y":[1]},"o":{"x":[0.167],"y":[0.125]},"t":103,"s":[-100]},{"t":123.000005009893,"s":[0]}],"ix":3},"m":1,"ix":2,"nm":"Pfade trimmen 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":55.0000022401959,"op":129.000005254278,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Kontur3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[95,95,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":3,"s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":45,"ix":4},"nm":"Rechteckpfad: 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666666667,0.839215746113,0.172549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16.5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Kontur 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Rechteck 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.801],"y":[0.742]},"o":{"x":[0.324],"y":[0]},"t":88,"s":[0]},{"t":127.000005172816,"s":[55]}],"ix":1},"e":{"a":0,"k":0,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.661]},"o":{"x":[0.175],"y":[0]},"t":90,"s":[-124]},{"i":{"x":[0.839],"y":[1]},"o":{"x":[0.167],"y":[0.125]},"t":103,"s":[-100]},{"t":123.000005009893,"s":[0]}],"ix":3},"m":1,"ix":2,"nm":"Pfade trimmen 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":55.0000022401959,"op":129.000005254278,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Kontur2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[95,95,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":3,"s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":45,"ix":4},"nm":"Rechteckpfad: 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666666667,0.839215746113,0.172549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16.5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Kontur 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Rechteck 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.531],"y":[1]},"o":{"x":[0.467],"y":[0]},"t":38,"s":[50]},{"t":89.0000036250443,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.607],"y":[0.813]},"o":{"x":[0.293],"y":[1.11]},"t":44,"s":[130]},{"t":90.0000036657751,"s":[237]}],"ix":3},"m":1,"ix":2,"nm":"Pfade trimmen 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":35.0000014255792,"op":93.0000037879676,"st":-3.00000012219251,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Kontur1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[95,95,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":3,"s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":45,"ix":4},"nm":"Rechteckpfad: 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666666667,0.839215746113,0.172549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16.5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Kontur 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Rechteck 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.531],"y":[1]},"o":{"x":[0.467],"y":[0]},"t":38,"s":[50]},{"t":89.0000036250443,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.614],"y":[0.854]},"o":{"x":[0.297],"y":[1.125]},"t":44,"s":[130]},{"t":90.0000036657751,"s":[237]}],"ix":3},"m":1,"ix":2,"nm":"Pfade trimmen 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":35.0000014255792,"op":93.0000037879676,"st":-3.00000012219251,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/lottie/test/data/static_lottie.json b/lottie/test/data/static_lottie.json new file mode 100644 index 0000000..cb8efcb --- /dev/null +++ b/lottie/test/data/static_lottie.json @@ -0,0 +1,689 @@ +{ + "v": "5.6.6", + "ip": 0, + "op": 1, + "fr": 60, + "w": 953, + "h": 272, + "layers": [ + { + "ind": 2345, + "nm": "surface13687", + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "ty": 4, + "ks": { + "ty": "tr", + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [0, 0] }, + "a": { "k": [0, 0] }, + "s": { "k": [133.33, 133.33] }, + "sk": { "k": 0 }, + "sa": { "k": 0 } + }, + "shapes": [ + { + "ty": "gr", + "hd": false, + "nm": "surface13687", + "it": [ + { + "ty": "gr", + "hd": false, + "it": [ + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [20, -0.05], + [0.73, 0.64], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [-20.01, 0.05], + [-1.14, 0.25], + [0, 0], + [0, 0] + ], + "v": [ + [79.56, 177.9], + [110.31, 147.43], + [163.43, 200.61], + [103.41, 200.64], + [100.84, 199.21], + [79.55, 177.9] + ], + "c": true + } + } + }, + { + "ty": "fl", + "o": { "k": 100 }, + "c": { "k": [0.03, 0.35, 0.61, 1] } + }, + { + "ty": "tr", + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [0, 0] }, + "a": { "k": [0, 0] }, + "s": { "k": [100, 100] }, + "sk": { "k": 0 }, + "sa": { "k": 0 }, + "hd": false + } + ] + }, + { + "ty": "gr", + "hd": false, + "it": [ + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "v": [ + [49.02, 147.35], + [79.55, 116.86], + [110.18, 147.3], + [110.31, 147.43], + [79.56, 177.9] + ], + "c": true + } + } + }, + { + "ty": "fl", + "o": { "k": 100 }, + "c": { "k": [0.12, 0.74, 0.99, 1] } + }, + { + "ty": "tr", + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [0, 0] }, + "a": { "k": [0, 0] }, + "s": { "k": [100, 100] }, + "sk": { "k": 0 }, + "sa": { "k": 0 }, + "hd": false + } + ] + }, + { + "ty": "gr", + "hd": false, + "it": [ + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [17.48, -0.07], + [0.15, -1.03], + [0, 0], + [-1.04, -0.16], + [0, 0], + [0, 0], + [13.93, -0.01], + [2.05, -0.36], + [0, 0], + [4.49, 0.1], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [-17.47, 0], + [-1.34, 0.44], + [0, 0], + [0.44, 1.33], + [0, 0], + [0, 0], + [-13.93, -0.01], + [-2.07, -0.01], + [0, 0], + [-4.49, -0.18], + [0, 0], + [0, 0], + [0, 0] + ], + "v": [ + [249.55, 45.91], + [316.33, 45.93], + [316.32, 59.08], + [263.9, 59.1], + [263.05, 62.24], + [263.1, 97.61], + [266.25, 98.46], + [311.07, 98.44], + [311.07, 111.57], + [269.28, 111.57], + [263.07, 111.79], + [262.91, 161.71], + [249.44, 161.6], + [249.43, 48.03], + [249.55, 45.91] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [4.45, -0.12], + [0, 1.84], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [0, 0], + [-4.46, -0.08], + [-0.34, -1.83], + [0, 0], + [0, 0] + ], + "v": [ + [332.52, 45.93], + [346.23, 45.93], + [346.24, 124.5], + [346.09, 161.5], + [332.71, 161.51], + [332.51, 155.98], + [332.52, 45.93] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [-6.71, -0.54], + [0.07, -4.17], + [6.68, 0.1], + [0, 0], + [-4.17, -2.21], + [-4.51, 2.61], + [0, 0], + [5.33, 0.73], + [2.27, 7.45], + [0.03, 4.26], + [0, 0], + [0, 0], + [4.75, 0.17], + [-0.27, 4.24], + [-4.82, 0.37] + ], + "o": [ + [0, 0], + [0, 0], + [6.73, 0.16], + [-0.19, 4.17], + [-6.69, 0.02], + [0, 0], + [0.14, 4.29], + [4.76, 2.71], + [0, 0], + [-4.96, 2.25], + [-7.52, -1.15], + [-1.51, -4.08], + [0, 0], + [0, 0], + [-4.75, -0.25], + [0.03, -4.25], + [4.83, -0.08], + [0, 0] + ], + "v": [ + [466.71, 55.67], + [480.46, 55.68], + [480.49, 78.93], + [500.69, 79.16], + [500.59, 91.68], + [480.53, 91.64], + [480.48, 137.95], + [485.71, 149.63], + [500.83, 148.46], + [500.83, 161.93], + [484.87, 163.72], + [467.88, 150], + [466.69, 137.26], + [466.66, 92.16], + [466.32, 91.78], + [452.05, 91.65], + [452.16, 78.92], + [466.66, 78.77] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [-4.57, -0.16], + [0, 0], + [-0.41, -7.62], + [-6.51, 0.04], + [0, 0], + [6.55, 0.04], + [0, 0], + [-3.97, -2.02], + [-4.52, 2.71], + [0, 0], + [5.2, 0.6], + [3.18, 6.19], + [0.14, 3.58], + [0, 0], + [4.74, 0.02], + [0, 0], + [-4.67, -0.16], + [-0.29, 7.79] + ], + "o": [ + [4.57, 0.16], + [0, 0], + [0.17, 7.64], + [6.52, -0.12], + [0, 0], + [-6.55, 0.25], + [0, 0], + [-0.01, 4.1], + [4.87, 2.66], + [0, 0], + [-4.82, 2.18], + [-6.76, -0.9], + [-1.53, -3.24], + [0, 0], + [-4.75, -0.01], + [0, 0], + [4.67, 0.13], + [0.5, -7.77], + [0, 0] + ], + "v": [ + [524.82, 55.62], + [538.54, 55.73], + [538.86, 56.07], + [539.04, 78.99], + [558.58, 78.93], + [558.63, 91.57], + [538.94, 91.63], + [538.87, 138.74], + [544.01, 149.71], + [559.3, 148.29], + [559.29, 161.84], + [543.82, 163.83], + [527.28, 152.93], + [524.75, 142.52], + [524.75, 91.69], + [510.52, 91.69], + [510.55, 78.89], + [524.57, 79.01], + [524.82, 55.63] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [-9.7, -3.3], + [-3.15, -11.24], + [0.29, -6.48], + [0, 0], + [-4.83, -5.22], + [-9.97, 3.14], + [-3.59, 6.19], + [-3.96, -1.82], + [11.57, -2.22], + [8.71, 4.7], + [2.22, 12.3], + [-3.55, 8.97], + [-9.7, 4.25] + ], + "o": [ + [9.5, -3.94], + [11.11, 3.83], + [2.06, 6.23], + [0, 0], + [0.54, 6.95], + [6.86, 8], + [7, -2.06], + [3.98, 1.78], + [-5.41, 10.32], + [-9.5, 1.78], + [-11.31, -5.62], + [-1.61, -9.45], + [3.73, -9.85], + [0, 0] + ], + "v": [ + [591.59, 79.36], + [621.73, 78.65], + [644.59, 103.42], + [646.27, 122.75], + [580.98, 122.82], + [588.43, 142.08], + [617.08, 149.91], + [633.13, 136.27], + [644.93, 141.9], + [618.09, 162.64], + [589.48, 159.77], + [568.16, 130.41], + [570.61, 101.99], + [591.58, 79.36] + ], + "c": false + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [1.61, -8.46], + [0, 0], + [4.05, 4], + [9.3, -4.04] + ], + "o": [ + [-7.99, 3.69], + [0, 0], + [-0.8, -5.53], + [-7.09, -7.61], + [0, 0] + ], + "v": [ + [596.75, 91.22], + [582.01, 111.57], + [632.08, 111.41], + [625.27, 96.27], + [596.75, 91.23] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [-12.7, -5.32], + [0, 0], + [5.63, -1.66], + [2.18, -7.55], + [-0.06, -5.23], + [0.44, -6.76], + [-0.5, -5.85], + [4.66, -0.16], + [0.07, 17.64], + [0, 0], + [-4.38, -0.11], + [-0.73, -4.37] + ], + "o": [ + [5.23, -12.7], + [0, 0], + [-5.33, -2.1], + [-7.7, 2.29], + [-1.5, 5.1], + [-0.59, 6.77], + [0.36, 5.84], + [-4.66, 0.23], + [-0.27, -17.63], + [0, 0], + [4.37, 0.12], + [0.4, 4.38], + [0, 0] + ], + "v": [ + [675.99, 92.31], + [709.98, 78.26], + [709.98, 93.08], + [693.04, 91.34], + [677.46, 108.05], + [676.59, 123.7], + [676.44, 144], + [676.62, 161.54], + [662.63, 161.68], + [662.52, 108.76], + [662.62, 79.07], + [675.75, 79.16], + [675.99, 92.31] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [-4.63, -0.52], + [0, 0], + [-4.16, -4.66], + [-7.34, 2.35], + [0.39, 10.38], + [0, 0], + [0, 0], + [0, 0], + [4.43, 0.05], + [0, 0], + [4.12, -2.27], + [9.44, 2.72], + [3.05, 5.58], + [0.21, 6.99], + [0, 0] + ], + "o": [ + [4.65, 0.2], + [0, 0], + [-0.05, 6.01], + [5.36, 5.94], + [9.8, -3.51], + [0, 0], + [0, 0], + [0, 0], + [-4.44, -0.07], + [0, 0], + [-2.87, 3.61], + [-8.43, 5.32], + [-6.09, -1.84], + [-3.62, -6.14], + [0, 0], + [0, 0] + ], + "v": [ + [365.89, 78.91], + [379.86, 79.15], + [379.79, 128.31], + [384.75, 145.54], + [406.54, 150.22], + [422.78, 125.95], + [422.93, 78.91], + [436.93, 78.94], + [436.85, 161.48], + [423.55, 161.43], + [423.5, 149.68], + [413.49, 159.21], + [384.93, 162.51], + [370.48, 150.83], + [365.73, 130.45], + [365.9, 78.91] + ], + "c": true + } + } + }, + { "ty": "fl", "o": { "k": 54 }, "c": { "k": [0, 0, 0, 1] } }, + { + "ty": "tr", + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [0, 0] }, + "a": { "k": [0, 0] }, + "s": { "k": [100, 100] }, + "sk": { "k": 0 }, + "sa": { "k": 0 }, + "hd": false + } + ] + }, + { + "ty": "gr", + "hd": false, + "it": [ + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "v": [ + [102.21, 3.07], + [163.46, 3], + [60.7, 105.71], + [33.92, 132.34], + [3.45, 101.83] + ], + "c": true + } + } + }, + { + "ty": "sh", + "ks": { + "k": { + "i": [ + [0, 0], + [-1.11, 0.14], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "o": [ + [0.8, -1.05], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [0, 0] + ], + "v": [ + [101.64, 94.78], + [105.01, 94.11], + [163.41, 94.12], + [110.18, 147.3], + [79.55, 116.86], + [101.64, 94.78] + ], + "c": true + } + } + }, + { + "ty": "fl", + "o": { "k": 100 }, + "c": { "k": [0.27, 0.82, 0.99, 1] } + }, + { + "ty": "tr", + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [0, 0] }, + "a": { "k": [0, 0] }, + "s": { "k": [100, 100] }, + "sk": { "k": 0 }, + "sa": { "k": 0 }, + "hd": false + } + ] + }, + { + "ty": "tr", + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [0, 0] }, + "a": { "k": [0, 0] }, + "s": { "k": [100, 100] }, + "sk": { "k": 0 }, + "sa": { "k": 0 }, + "hd": false + } + ] + } + ] + } + ], + "meta": { "g": "LF SVG to Lottie" } +} diff --git a/lottie/test/data/warningShimmer.json b/lottie/test/data/warningShimmer.json new file mode 100644 index 0000000..9991b2e --- /dev/null +++ b/lottie/test/data/warningShimmer.json @@ -0,0 +1,1850 @@ +{ + "v": "5.5.9", + "fr": 29.9700012207031, + "ip": 0, + "op": 38.0000015477717, + "w": 114, + "h": 114, + "nm": "Warning", + "ddd": 0, + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Layer 5 Outlines", + "sr": 1, + "ks": { + "o": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 26, + "s": [ + 0 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 32, + "s": [ + 100 + ] + }, + { + "t": 38.0000015477717, + "s": [ + 0 + ] + } + ], + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 56.853, + 56.618, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 56.897, + 56.897, + 0 + ], + "ix": 1 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 26, + "s": [ + 83, + 83, + 100 + ] + }, + { + "t": 38.0000015477717, + "s": [ + 100, + 100, + 100 + ] + } + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 28.397, + 0 + ], + [ + 0, + -28.397 + ], + [ + -28.397, + 0 + ], + [ + 0, + 28.397 + ] + ], + "o": [ + [ + -28.397, + 0 + ], + [ + 0, + 28.397 + ], + [ + 28.397, + 0 + ], + [ + 0, + -28.397 + ] + ], + "v": [ + [ + 0.001, + -51.497 + ], + [ + -51.498, + 0.001 + ], + [ + 0.001, + 51.497 + ], + [ + 51.498, + 0.001 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 31.234, + 0 + ], + [ + 0, + 31.233 + ], + [ + -31.236, + 0 + ], + [ + 0, + -31.237 + ] + ], + "o": [ + [ + -31.236, + 0 + ], + [ + 0, + -31.237 + ], + [ + 31.234, + 0 + ], + [ + 0, + 31.233 + ] + ], + "v": [ + [ + 0.001, + 56.647 + ], + [ + -56.647, + 0.001 + ], + [ + 0.001, + -56.647 + ], + [ + 56.647, + 0.001 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 1, + 0.419999994016, + 0, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 56.897, + 56.898 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 4.00000016292334, + "op": 320.000013033867, + "st": 4.00000016292334, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 4, + "nm": "Layer 2 Outlines", + "sr": 1, + "ks": { + "o": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 20, + "s": [ + 0 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 26, + "s": [ + 100 + ] + }, + { + "t": 32.0000013033867, + "s": [ + 0 + ] + } + ], + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 56.853, + 56.618, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 56.897, + 56.897, + 0 + ], + "ix": 1 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 20, + "s": [ + 83, + 83, + 100 + ] + }, + { + "t": 32.0000013033867, + "s": [ + 100, + 100, + 100 + ] + } + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 28.397, + 0 + ], + [ + 0, + -28.397 + ], + [ + -28.397, + 0 + ], + [ + 0, + 28.397 + ] + ], + "o": [ + [ + -28.397, + 0 + ], + [ + 0, + 28.397 + ], + [ + 28.397, + 0 + ], + [ + 0, + -28.397 + ] + ], + "v": [ + [ + 0.001, + -51.497 + ], + [ + -51.498, + 0.001 + ], + [ + 0.001, + 51.497 + ], + [ + 51.498, + 0.001 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 31.234, + 0 + ], + [ + 0, + 31.233 + ], + [ + -31.236, + 0 + ], + [ + 0, + -31.237 + ] + ], + "o": [ + [ + -31.236, + 0 + ], + [ + 0, + -31.237 + ], + [ + 31.234, + 0 + ], + [ + 0, + 31.233 + ] + ], + "v": [ + [ + 0.001, + 56.647 + ], + [ + -56.647, + 0.001 + ], + [ + 0.001, + -56.647 + ], + [ + 56.647, + 0.001 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 1, + 0.419999994016, + 0, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 56.897, + 56.898 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 316.000012870944, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 3, + "ty": 4, + "nm": "Layer 4 Outlines", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 0, + "s": [ + 57.387, + 65.377, + 0 + ], + "to": [ + 0, + -0.35, + 0 + ], + "ti": [ + 0, + 0.835, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 4, + "s": [ + 57.387, + 65.46, + 0 + ], + "to": [ + 0, + -1.455, + 0 + ], + "ti": [ + 0, + 0.609, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 11, + "s": [ + 57.387, + 56.377, + 0 + ], + "to": [ + 0, + -0.958, + 0 + ], + "ti": [ + 0, + 0.609, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 13, + "s": [ + 57.387, + 50.877, + 0 + ], + "to": [ + 0, + -0.958, + 0 + ], + "ti": [ + 0, + 0.609, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 15, + "s": [ + 57.387, + 56.377, + 0 + ], + "to": [ + 0, + -0.958, + 0 + ], + "ti": [ + 0, + -0.417, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 19, + "s": [ + 57.387, + 65.627, + 0 + ], + "to": [ + 0, + 0.417, + 0 + ], + "ti": [ + 0, + 0.958, + 0 + ] + }, + { + "t": 22.0000008960784, + "s": [ + 57.387, + 65.377, + 0 + ] + } + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 5.434, + 31.682, + 0 + ], + "ix": 1 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 0, + "s": [ + 100, + 100, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 4, + "s": [ + 115, + 90, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 8, + "s": [ + 100, + 112, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 11, + "s": [ + 100, + 112, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 13, + "s": [ + 113.333, + 94.333, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 15, + "s": [ + 100, + 112, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 20, + "s": [ + 113, + 95, + 100 + ] + }, + { + "t": 22.0000008960784, + "s": [ + 100, + 100, + 100 + ] + } + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 2.878, + 0 + ], + [ + 0, + -2.487 + ], + [ + 0, + 0 + ], + [ + -2.951, + 0 + ], + [ + 0, + 2.426 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -2.951, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 2.49 + ], + [ + 2.878, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -2.428 + ] + ], + "v": [ + [ + 0.001, + -15.433 + ], + [ + -5.184, + -11.406 + ], + [ + -5.184, + 11.409 + ], + [ + 0.001, + 15.433 + ], + [ + 5.184, + 11.409 + ], + [ + 5.184, + -11.406 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 1, + 1, + 1, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 5.433, + 15.682 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 316.000012870944, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 4, + "ty": 4, + "nm": "Layer 3 Outlines", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 57.011, + 80.341, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 5.516, + 11.142, + 0 + ], + "ix": 1 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 20, + "s": [ + 100, + 100, + 100 + ] + }, + { + "i": { + "x": [ + 0.833, + 0.833, + 0.833 + ], + "y": [ + 0.833, + 0.833, + 0.833 + ] + }, + "o": { + "x": [ + 0.167, + 0.167, + 0.167 + ], + "y": [ + 0.167, + 0.167, + 0.167 + ] + }, + "t": 22, + "s": [ + 100, + 79, + 100 + ] + }, + { + "t": 24.00000097754, + "s": [ + 100, + 100, + 100 + ] + } + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 2.834, + 0 + ], + [ + 0, + -2.837 + ], + [ + -2.835, + 0 + ], + [ + 0, + 2.833 + ] + ], + "o": [ + [ + -2.835, + 0 + ], + [ + 0, + 2.833 + ], + [ + 2.834, + 0 + ], + [ + 0, + -2.837 + ] + ], + "v": [ + [ + 0.002, + -5.142 + ], + [ + -5.141, + 0.003 + ], + [ + 0.002, + 5.142 + ], + [ + 5.141, + 0.003 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 1, + 1, + 1, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 5.391, + 5.392 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 316.000012870944, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 5, + "ty": 4, + "nm": "Layer 1 Outlines", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 56.854, + 56.618, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 41.449, + 41.449, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -22.753, + 0 + ], + [ + 0, + -22.753 + ], + [ + 22.754, + 0 + ], + [ + 0, + 22.754 + ] + ], + "o": [ + [ + 22.754, + 0 + ], + [ + 0, + 22.754 + ], + [ + -22.753, + 0 + ], + [ + 0, + -22.753 + ] + ], + "v": [ + [ + 0, + -41.199 + ], + [ + 41.199, + 0 + ], + [ + 0, + 41.199 + ], + [ + -41.199, + 0 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 1, + 0.419999994016, + 0, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 41.449, + 41.449 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 316.000012870944, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} \ No newline at end of file diff --git a/lottie/test/dotlottie.dart b/lottie/test/dotlottie.dart new file mode 100644 index 0000000..4d06ed9 --- /dev/null +++ b/lottie/test/dotlottie.dart @@ -0,0 +1,39 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'package:lottie/src/utils.dart'; +import 'package:path/path.dart' as p; + +void main() { + testWidgets('Dotlottie', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + + var provider = FileLottie( + File('example/assets/cat.lottie'), + decoder: customDecoder, + ); + await tester.runAsync(() => provider.load()); + + await tester.pumpWidget(LottieBuilder(lottie: provider)); + + await expectLater( + find.byType(Lottie), + matchesGoldenFile(p.join('goldens/dotlottie.png')), + ); + }); +} + +Future customDecoder(List bytes) { + return LottieComposition.decodeZip( + bytes, + filePicker: (files) { + return files.firstWhereOrNull( + (f) => f.name.startsWith('animations/') && f.name.endsWith('.json'), + ); + }, + ); +} diff --git a/lottie/test/dynamic_image_test.dart b/lottie/test/dynamic_image_test.dart new file mode 100644 index 0000000..6d66722 --- /dev/null +++ b/lottie/test/dynamic_image_test.dart @@ -0,0 +1,96 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:ui' as ui; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'utils.dart'; + +void main() { + testWidgets('Can specify ImageProvider with zip file ', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + + var callCount = 0; + ImageProvider imageProviderFactory(LottieImageAsset image) { + ++callCount; + return FileImage(File('example/assets/Images/WeAccept/img_0.png')); + } + + Future decoder(List bytes) { + return LottieComposition.decodeZip( + bytes, + imageProviderFactory: imageProviderFactory, + ); + } + + var composition = (await tester.runAsync( + () => FileLottie( + File('example/assets/spinning_carrousel.zip'), + imageProviderFactory: imageProviderFactory, + decoder: decoder, + ).load(), + ))!; + + await tester.pumpWidget(FilmStrip(composition, size: size)); + + expect(callCount, 2); + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile('goldens/dynamic_image/zip_with_provider.png'), + ); + }); + + testWidgets('Can specify image delegate', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + + var image = await tester.runAsync( + () async => loadImage( + FileImage(File('example/assets/Images/WeAccept/img_0.png')), + ), + ); + + var composition = (await tester.runAsync( + () async => + FileLottie(File('example/assets/spinning_carrousel.zip')).load(), + ))!; + + var delegates = LottieDelegates( + image: (composition, asset) { + return image; + }, + ); + await tester.pumpWidget( + FilmStrip(composition, size: size, delegates: delegates), + ); + + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile('goldens/dynamic_image/delegate.png'), + ); + }); +} + +Future loadImage(ImageProvider provider) { + var completer = Completer(); + var imageStream = provider.resolve(ImageConfiguration.empty); + late ImageStreamListener listener; + listener = ImageStreamListener( + (image, synchronousLoaded) { + imageStream.removeListener(listener); + + completer.complete(image.image); + }, + onError: (dynamic e, _) { + imageStream.removeListener(listener); + + completer.complete(); + }, + ); + imageStream.addListener(listener); + + return completer.future; +} diff --git a/lottie/test/dynamic_properties_test.dart b/lottie/test/dynamic_properties_test.dart new file mode 100644 index 0000000..ece7d18 --- /dev/null +++ b/lottie/test/dynamic_properties_test.dart @@ -0,0 +1,478 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'utils.dart'; + +void main() { + void testGolden( + String description, + ValueDelegate delegate, { + double? progress, + String? filePath, + }) { + filePath ??= 'Tests/Shapes.json'; + + var screenshotName = description + .toLowerCase() + .replaceAll(RegExp('[^a-z0-9 ]'), '') + .replaceAll(' ', '_'); + + testWidgets(description, (tester) async { + var composition = await LottieComposition.fromBytes( + File('example/assets/$filePath').readAsBytesSync(), + ); + + var animation = AnimationController( + vsync: tester, + duration: composition.duration, + ); + if (progress != null) { + animation.value = progress; + } + + await tester.pumpWidget( + Lottie( + composition: composition, + controller: animation, + delegates: LottieDelegates(values: [delegate]), + addRepaintBoundary: false, + ), + ); + await tester.pump(); + await expectLater( + find.byType(Lottie), + matchesGoldenFile('goldens/dynamic/$screenshotName.png'), + ); + + if (progress == null || progress == 0) { + await tester.pumpWidget( + Lottie( + composition: composition, + controller: animation, + delegates: const LottieDelegates(values: []), + addRepaintBoundary: false, + ), + ); + await tester.pump(); + } + }); + } + + testGolden( + 'Fill color (Green)', + ValueDelegate.color([ + 'Shape Layer 1', + 'Rectangle', + 'Fill 1', + ], value: Colors.green), + ); + + testGolden( + 'Fill color (Yellow)', + ValueDelegate.color([ + 'Shape Layer 1', + 'Rectangle', + 'Fill 1', + ], value: Colors.yellow), + ); + + testGolden( + 'Fill opacity', + ValueDelegate.opacity(['Shape Layer 1', 'Rectangle', 'Fill 1'], value: 50), + ); + + testGolden( + 'Stroke color', + ValueDelegate.strokeColor([ + 'Shape Layer 1', + 'Rectangle', + 'Stroke 1', + ], value: Colors.green), + ); + + testGolden( + 'Stroke width', + ValueDelegate.strokeWidth([ + 'Shape Layer 1', + 'Rectangle', + 'Stroke 1', + ], value: 50), + ); + + testGolden( + 'Stroke opacity', + ValueDelegate.opacity([ + 'Shape Layer 1', + 'Rectangle', + 'Stroke 1', + ], value: 50), + ); + + testGolden( + 'Transform anchor point', + ValueDelegate.transformAnchorPoint([ + 'Shape Layer 1', + 'Rectangle', + ], value: const Offset(20, 20)), + ); + + testGolden( + 'Transform position', + ValueDelegate.transformPosition([ + 'Shape Layer 1', + 'Rectangle', + ], value: const Offset(20, 20)), + ); + + testGolden( + 'Transform position (relative)', + ValueDelegate.transformPosition([ + 'Shape Layer 1', + 'Rectangle', + ], relative: const Offset(20, 20)), + ); + + testGolden( + 'Transform opacity', + ValueDelegate.transformOpacity(['Shape Layer 1', 'Rectangle'], value: 50), + ); + + testGolden( + 'Transform rotation', + ValueDelegate.transformRotation(['Shape Layer 1', 'Rectangle'], value: 45), + ); + + testGolden( + 'Transform scale', + ValueDelegate.transformScale([ + 'Shape Layer 1', + 'Rectangle', + ], value: const Offset(0.5, 0.5)), + ); + + testGolden( + 'Rectangle corner roundedness', + ValueDelegate.cornerRadius([ + 'Shape Layer 1', + 'Rectangle', + 'Rectangle Path 1', + ], value: 7), + ); + + testGolden( + 'Rectangle position', + ValueDelegate.position([ + 'Shape Layer 1', + 'Rectangle', + 'Rectangle Path 1', + ], relative: const Offset(20, 20)), + ); + + testGolden( + 'Rectangle size', + ValueDelegate.rectangleSize([ + 'Shape Layer 1', + 'Rectangle', + 'Rectangle Path 1', + ], relative: const Offset(30, 40)), + ); + + testGolden( + 'Ellipse position', + ValueDelegate.position([ + 'Shape Layer 1', + 'Ellipse', + 'Ellipse Path 1', + ], relative: const Offset(20, 20)), + ); + + testGolden( + 'Ellipse size', + ValueDelegate.ellipseSize([ + 'Shape Layer 1', + 'Ellipse', + 'Ellipse Path 1', + ], relative: const Offset(40, 60)), + ); + + testGolden( + 'Star points', + ValueDelegate.polystarPoints([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 8), + ); + + testGolden( + 'Star rotation', + ValueDelegate.polystarRotation([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 10), + ); + + testGolden( + 'Star position', + ValueDelegate.position([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], relative: const Offset(20, 20)), + ); + + testGolden( + 'Star inner radius', + ValueDelegate.polystarInnerRadius([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 10), + ); + + testGolden( + 'Star inner roundedness', + ValueDelegate.polystarInnerRoundedness([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 100), + ); + + testGolden( + 'Star outer radius', + ValueDelegate.polystarOuterRadius([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 60), + ); + + testGolden( + 'Star outer roundedness', + ValueDelegate.polystarOuterRoundedness([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 100), + ); + + testGolden( + 'Polygon points', + ValueDelegate.polystarPoints([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 8), + ); + + testGolden( + 'Polygon rotation', + ValueDelegate.polystarRotation([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 10), + ); + + testGolden( + 'Polygon position', + ValueDelegate.position([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], relative: const Offset(20, 20)), + ); + + testGolden( + 'Polygon radius', + ValueDelegate.polystarOuterRadius([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], relative: 60), + ); + + testGolden( + 'Polygon roundedness', + ValueDelegate.polystarOuterRoundedness([ + 'Shape Layer 1', + 'Star', + 'Polystar Path 1', + ], value: 100), + ); + + testGolden( + 'Repeater transform position', + ValueDelegate.transformPosition([ + 'Shape Layer 1', + 'Repeater Shape', + 'Repeater 1', + ], relative: const Offset(100, 100)), + ); + + testGolden( + 'Repeater transform start opacity', + ValueDelegate.transformStartOpacity([ + 'Shape Layer 1', + 'Repeater Shape', + 'Repeater 1', + ], value: 25), + ); + + testGolden( + 'Repeater transform end opacity', + ValueDelegate.transformEndOpacity([ + 'Shape Layer 1', + 'Repeater Shape', + 'Repeater 1', + ], value: 25), + ); + + testGolden( + 'Repeater transform rotation', + ValueDelegate.transformRotation([ + 'Shape Layer 1', + 'Repeater Shape', + 'Repeater 1', + ], value: 45), + ); + + testGolden( + 'Repeater transform scale', + ValueDelegate.transformScale([ + 'Shape Layer 1', + 'Repeater Shape', + 'Repeater 1', + ], value: const Offset(2, 2)), + ); + + testGolden( + 'Time remapping', + ValueDelegate.timeRemap(['Circle 1'], value: 1), + progress: 0.1, + ); + + testGolden( + 'Color Filter', + ValueDelegate.colorFilter([ + '**', + ], value: const ColorFilter.mode(Colors.green, BlendMode.srcATop)), + ); + + testGolden('Null Color Filter', ValueDelegate.colorFilter(['**'])); + + testGolden( + 'Matte property', + ValueDelegate.rectangleSize([ + 'Shape Layer 1', + 'Rectangle 1', + 'Rectangle Path 1', + ], value: const Offset(50, 50)), + filePath: 'Tests/TrackMattes.json', + ); + + testGolden('Blur', ValueDelegate.blurRadius(['**'], value: 10)); + + testGolden( + 'Drop shadow', + ValueDelegate.dropShadow( + ['Shape Layer 1', '**'], + value: const DropShadow( + color: Colors.green, + direction: 150, + distance: 20, + radius: 10, + ), + ), + ); + + testGolden( + 'Solid Color', + ValueDelegate.color(['Cyan Solid 1', '**'], value: Colors.yellow), + filePath: 'Tests/SolidLayerTransform.json', + ); + + for (var progress in [0.0, 0.5, 1.0]) { + testGolden( + 'Opacity interpolation ($progress)', + ValueDelegate.transformOpacity( + ['Shape Layer 1', 'Rectangle'], + callback: (frameInfo) => lerpDouble( + 10, + 100, + Curves.linear.transform(frameInfo.overallProgress), + )!.round(), + ), + progress: progress, + ); + } + + testWidgets('warningShimmer', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + + var composition = await LottieComposition.fromBytes( + File('test/data/warningShimmer.json').readAsBytesSync(), + ); + + var delegates = >{ + '1': [ + for (var i in ['1', '2', '5']) + ValueDelegate.color(['Layer $i Outlines', '**'], value: Colors.red), + for (var i in ['3', '4']) + ValueDelegate.color([ + 'Layer $i Outlines', + '**', + ], value: Colors.greenAccent), + ], + '2': [ + for (var i in ['1', '2', '5']) + ValueDelegate.color([ + 'Layer $i Outlines', + 'Group 1', + '*', + ], value: Colors.red), + for (var i in ['3', '4']) + ValueDelegate.color([ + 'Layer $i Outlines', + 'Group 1', + '*', + ], value: Colors.greenAccent), + ], + '3': [ + for (var i in ['1', '2', '5']) + ValueDelegate.color([ + 'Layer $i Outlines', + 'Group 1', + 'Fill 1', + ], value: Colors.red), + for (var i in ['3', '4']) + ValueDelegate.color([ + 'Layer $i Outlines', + 'Group 1', + 'Fill 1', + ], value: Colors.greenAccent), + ], + }; + + for (var variant in delegates.entries) { + await tester.pumpWidget( + FilmStrip( + composition, + size: size, + delegates: LottieDelegates(values: variant.value), + ), + ); + + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile('goldens/warningShimmer_${variant.key}.png'), + ); + } + }); +} diff --git a/lottie/test/dynamic_test.dart b/lottie/test/dynamic_test.dart new file mode 100644 index 0000000..5fed2fe --- /dev/null +++ b/lottie/test/dynamic_test.dart @@ -0,0 +1,40 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'utils.dart'; + +void main() { + var root = 'example/assets'; + + testWidgets('Mirror animation', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + + var composition = (await tester.runAsync( + () => FileLottie(File('$root/Tests/MatteTimeStretchScan.json')).load(), + ))!; + await tester.pumpWidget( + FilmStrip( + composition, + size: size, + delegates: LottieDelegates( + values: [ + ValueDelegate.transformAnchorPoint( + [], + value: Offset(composition.bounds.width.toDouble(), 0), + ), + ValueDelegate.transformScale([], value: const Offset(-1, 1)), + ], + ), + ), + ); + + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile('goldens/mirror.png'), + ); + }); +} diff --git a/lottie/test/dynamic_text_properties_test.dart b/lottie/test/dynamic_text_properties_test.dart new file mode 100644 index 0000000..db4982f --- /dev/null +++ b/lottie/test/dynamic_text_properties_test.dart @@ -0,0 +1,61 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; + +void main() { + late LottieComposition composition; + + setUpAll(() async { + composition = await LottieComposition.fromBytes( + File('example/assets/Tests/Text.json').readAsBytesSync(), + ); + }); + + void testGolden(String description, ValueDelegate delegate) async { + var screenshotName = description + .toLowerCase() + .replaceAll(RegExp('[^a-z0-9 ]'), '') + .replaceAll(' ', '_'); + + testWidgets(description, (tester) async { + await tester.pumpWidget( + Lottie( + composition: composition, + delegates: LottieDelegates(values: [delegate]), + addRepaintBoundary: false, + ), + ); + await tester.pump(); + await expectLater( + find.byType(Lottie), + matchesGoldenFile('goldens/dynamic_text/$screenshotName.png'), + ); + }); + } + + testGolden( + 'Text Fill (Blue -> Green)', + ValueDelegate.color(['Text'], callback: (_) => Colors.green), + ); + + testGolden( + 'Text Stroke (Red -> Yellow)', + ValueDelegate.strokeColor(['Text'], callback: (_) => Colors.yellow), + ); + + testGolden( + 'Text Stroke Width', + ValueDelegate.strokeWidth(['Text'], callback: (_) => 200), + ); + + testGolden( + 'Text Tracking 1', + ValueDelegate.textTracking(['Text'], callback: (_) => 20), + ); + + testGolden( + 'Text Tracking 2', + ValueDelegate.textSize(['Text'], callback: (_) => 60), + ); +} diff --git a/lottie/test/dynamic_text_test.dart b/lottie/test/dynamic_text_test.dart new file mode 100644 index 0000000..78df34a --- /dev/null +++ b/lottie/test/dynamic_text_test.dart @@ -0,0 +1,103 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'utils.dart'; + +void main() { + late LottieComposition composition; + + setUpAll(() async { + composition = await LottieComposition.fromBytes( + File('example/assets/Tests/DynamicText.json').readAsBytesSync(), + ); + }); + + void testGolden(String description, LottieDelegates delegates) async { + var screenshotName = description + .toLowerCase() + .replaceAll(RegExp('[^a-z0-9 ]'), '') + .replaceAll(' ', '_'); + + var size = const Size(500, 400); + testWidgets(description, (tester) async { + await tester.pumpWidget( + MaterialApp( + home: FilmStrip(composition, delegates: delegates, size: size), + ), + ); + await tester.pump(); + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile('goldens/dynamic_text/$screenshotName.png'), + ); + }); + } + + testGolden( + 'Dynamic text delegate', + LottieDelegates( + text: (input) => '🔥c️🔥👮🏿‍🔥', + textStyle: (font) => const TextStyle( + fontFamily: 'Roboto', + fontFamilyFallback: ['Noto Emoji'], + ), + values: const [], + ), + ); + + testGolden( + 'Dynamic Text ValueDelegate', + LottieDelegates( + values: [ + ValueDelegate.text(['NAME'], value: 'Text with ValueDelegate'), + ], + ), + ); + + testGolden( + 'Dynamic Text ValueDelegate overallProgress', + LottieDelegates( + values: [ + ValueDelegate.text([ + 'NAME', + ], callback: (frame) => '${frame.overallProgress}'), + ], + ), + ); + + testGolden( + 'Dynamic Text ValueDelegate startValue', + LottieDelegates( + values: [ + ValueDelegate.text([ + 'NAME', + ], callback: (frame) => '${frame.startValue}!!'), + ], + ), + ); + + testGolden( + 'Dynamic Text ValueDelegate endValue', + LottieDelegates( + values: [ + ValueDelegate.text([ + 'NAME', + ], callback: (frame) => '${frame.endValue}!!'), + ], + ), + ); + + testGolden( + 'Dynamic Text Emoji', + LottieDelegates( + textStyle: (font) => const TextStyle( + fontFamily: 'Roboto', + fontFamilyFallback: ['Noto Emoji'], + ), + values: [ + ValueDelegate.text(['NAME'], value: '🔥💪💯'), + ], + ), + ); +} diff --git a/lottie/test/fireworks_test.dart b/lottie/test/fireworks_test.dart new file mode 100644 index 0000000..e744859 --- /dev/null +++ b/lottie/test/fireworks_test.dart @@ -0,0 +1,26 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'package:path/path.dart' as p; +import 'utils.dart'; + +void main() { + testWidgets('Animations with stroke', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + + var composition = await LottieComposition.fromBytes( + File('example/assets/17297-fireworks.json').readAsBytesSync(), + ); + + await tester.pumpWidget(FilmStrip(composition, size: size)); + + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile(p.join('goldens/fireworks.png')), + ); + }); +} diff --git a/lottie/test/flutter_test_config.dart b/lottie/test/flutter_test_config.dart new file mode 100644 index 0000000..991fd95 --- /dev/null +++ b/lottie/test/flutter_test_config.dart @@ -0,0 +1,22 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:flutter/services.dart'; +import 'package:path/path.dart' as path; + +Future testExecutable(FutureOr Function() testMain) async { + await loadFonts(); + return testMain(); +} + +Future loadFonts() async { + for (var file in Directory( + 'example/assets/fonts', + ).listSync().whereType().where((f) => f.path.endsWith('.ttf'))) { + var fontLoader = FontLoader( + path.basenameWithoutExtension(file.path).replaceAll('-', ' '), + ); + var future = file.readAsBytes().then((value) => value.buffer.asByteData()); + fontLoader.addFont(future); + await fontLoader.load(); + } +} diff --git a/lottie/test/frame_rate_test.dart b/lottie/test/frame_rate_test.dart new file mode 100644 index 0000000..f353155 --- /dev/null +++ b/lottie/test/frame_rate_test.dart @@ -0,0 +1,17 @@ +import 'dart:io'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; + +void main() { + test('Frame rate round', () async { + var composition = await LottieComposition.fromBytes( + File('example/assets/LottieLogo1.json').readAsBytesSync(), + ); + expect(composition.roundProgress(0, frameRate: FrameRate.composition), 0); + expect( + composition.roundProgress(0.0001, frameRate: FrameRate.composition), + 0, + ); + expect(composition.roundProgress(0.0001, frameRate: FrameRate.max), 0.0001); + }); +} diff --git a/lottie/test/gamma_evaluator_test.dart b/lottie/test/gamma_evaluator_test.dart new file mode 100644 index 0000000..fd9d0e6 --- /dev/null +++ b/lottie/test/gamma_evaluator_test.dart @@ -0,0 +1,13 @@ +import 'dart:ui'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/src/utils/gamma_evaluator.dart'; + +void main() { + test('Evaluate for same color values', () { + for (var color = 0x000000; color <= 0xffffff; color++) { + var colorToTest = Color(0xff000000 | color); + var actual = GammaEvaluator.evaluate(0.3, colorToTest, colorToTest); + expect(actual, colorToTest); + } + }); +} diff --git a/lottie/test/golden/AndroidWave_0_0.png b/lottie/test/golden/AndroidWave_0_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9683bb9cb9e2f9c5f8a5498bdb3120eb384002e0 GIT binary patch literal 36740 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 literal 0 HcmV?d00001 diff --git a/lottie/test/golden/HamburgerArrow_0_0.png b/lottie/test/golden/HamburgerArrow_0_0.png new file mode 100644 index 0000000000000000000000000000000000000000..60ca0470fed0043940b4cdd3f434eff16fba75e8 GIT binary patch literal 17277 zcmeI)Ur19?90%~<{y6V8L=lYIN|uzFh;If3&RWwssG;J+9;|L5iM~vjgs9a`d(fAt zhrmEG5+s6VkYYsCT|Pt)6-&ZuWD-N(>0?!$c19 zx{tN?j>W?|ozf~@&rBr*)*Au>5P$##AOHafKmY;|fB*y_00B)4NFQg0%C24^VbEMs z(;GG&BKrr~dO@BWNQB-!5bM%*O)npdg8&2|009U<00Izz00bbg)dfc9oPBJLa#dpC zZE(ZnkEHw8_b3(1)7K&f)-sulmQEay?;8E=W1XiO3R$fh{+ndwxuaNQzXhw|)>rXV zYLxPLUSxjAQ!3N#;Q7&gvYzL|>L|aDZfLpl)t$9$m7*=3veo{D;|$xP9PhA}^SuCD zYr>g$wE3jrY*9nx^W-@>&(t;K7!fD*_pD9Flig>|XXA%0&%V84SNXq3MJlGAE>AMk zci9(^N-q9fT->EpN%K!m;MU-vxw)x%ZzyvjF!sW!K6REWoTn3kdAnFY{(Sc32HW)` z9bDko^=#ma($rka9!t2WbM&TKJ@QBXb~H7*l#{cGP9OjQ2tWV=5P$##AOHc)3dnW+ z-41niE7?!NeFOv`009U<00Izz00bZa0SG`~^93?(UvCi^3fcbxZ2su~_lT9>!+Y75 k1nEw8>h&efe*duz7goL2Q~dN%b!-c$D8pS@2R zm_?R4Jh;ES5yAe#{wu@p8iesO|By(T z;gu?j*9wAM2vPb)Cja~XX(J;;t5opnz(X0CjlVbnPJk2O1ULasfD_;ZH~~(86W|0m z0Z!omnt)Vua^-dB9nPjZE(E+&u+dbiP_-zHGaPps_4|*}$dQ(+^WZAO54rbcNA(SIBP?_=^+Z1ULasfD_;ZH~~(86W|0mfwzQ!wCzF5 z2;z&lcEFNt(XTq@zFb;*c+K+m8}%n^SCa;fv(dZcJ;&$Ns-@3g-0MnG)@ExDYxSR4 z(C5XL8uB^k;KqigLS@D~h9AXZ;~8XxTa#Vebo-xr8Gh7F?&U@v&0Fc0`i=G=`Ehri z(9iHD&0J&?J8FL7h-3K^AFPem3?*&3M=wnv@6w7zLt+D!(OIF1U5(cYhmD=un>-CE zk%*lNHD)6e5aTrcE<|O?Xf$(VG&mcFY29%;ry05CQ2w(W666nGf3!3l8{n`c-xiB0I1~$18 zS8v%&wkEW;Y3j;vJFd6lC5DB_-A& z^P99Z)w(rwWl3g0RcS&&R{X@|0LU~Z--YyNas*^ACLJMvVRAHNE|cRR!=^ z#k{>yUyVyZ*xEey^vaHh)y4b0@|qt%I)CJc_hqe>zuU(r6o@X_TheN`t1~;DRHAcW z>wSl!##_6mg^tWS;hiyOdw{FAilg{YJFs(Ap9xRZFH@e{obs~@Ua97c(-R2N@I@D*(i;>_-&D;G zVkO}vvB*`8tpkId9rP;)iO_?6&DjWwEDrhN_foNka9wuT#jo z_+DKOEY?zsQp~KFQ!ApeOu~M)&LDjrxp~BlUsICuBv^TBV+z^+g~~+;qtqTKS{-PX zQUWlt3h8c7L%J8>XmH-fWH!yA^R?%H6gr)w+nzX$xw_yIdH9|0zK2S)Tho@%O1#w4 zi=4n}2Sm-*je0nfSSV^MCb2TqW=vu!sB?=l(>+k(;ucyn;+XIe1Y3)>JL_pa)?=Tvdh~nIjpodOx29&%lT$iD_Y)~*Mvcwl>^C0Oo6}QX zNWxxLiu;Gqorqw1LlLTQa<_j)Pi4JL z0Mb}eUebIm+)u;~xh((==6>qPmP*k=vk&biZk#kd@Wpz=N}3++d#vO=T2+!U7WryI zVPcBs>&1~*^<+g+0-|M^oP6ueCeGkn?TzE*9$DxQR(Nb`_Is>`W$S$CP}u(ohn^EZV}!9z;{9i5-h- zXuo{ve8RF7j~h$1on!PH{+)ZAj`FCO1GfGl`3& zPQX|drc%o=^O32j4|67QfmbuTN7(I3&RW@6XUO;2SWhO|SZ^jVwz4brX;Bi3ZYvycH&cH?C zD>$DZ&r-PIyqbxtQGzDRo;|6-6VGop^z=b7dKPc!>4PWgoOL~Ya4%JFS=ZBtJt^GW z(+AeoCpY)>!IMg@OLw2Ga=HcU#`MW$Q7lKLNI_F<;_7mWl4sK+UyS;Nk*)b3viZp= z9^d;Y=p8{98jYz2D@Ml|?nU<=1$E&W z`YB3%7H$$`IDc^hoB$`l32*|O04Kl+Z~|{PfkwNIMv=OB@pZ99|dwppCaGx f-(+y_-W~#>#+#2uX11g@6PH2)!D-N(>0?!$c19 zx{tN?j>W?|ozf~@&rBr*)*Au>5P$##AOHafKmY;|fB*y_00B)4NFQg0%C24^VbEMs z(;GG&BKrr~dO@BWNQB-!5bM%*O)npdg8&2|009U<00Izz00bbg)dfc9oPBJLa#dpC zZE(ZnkEHw8_b3(1)7K&f)-sulmQEay?;8E=W1XiO3R$fh{+ndwxuaNQzXhw|)>rXV zYLxPLUSxjAQ!3N#;Q7&gvYzL|>L|aDZfLpl)t$9$m7*=3veo{D;|$xP9PhA}^SuCD zYr>g$wE3jrY*9nx^W-@>&(t;K7!fD*_pD9Flig>|XXA%0&%V84SNXq3MJlGAE>AMk zci9(^N-q9fT->EpN%K!m;MU-vxw)x%ZzyvjF!sW!K6REWoTn3kdAnFY{(Sc32HW)` z9bDko^=#ma($rka9!t2WbM&TKJ@QBXb~H7*l#{cGP9OjQ2tWV=5P$##AOHc)3dnW+ z-41niE7?!NeFOv`009U<00Izz00bZa0SG`~^93?(UvCi^3fcbxZ2su~_lT9>!+Y75 k1nEw8>h&efe*duz7goL2Q~dN%b!rsSphmA$9B(#|RlwajaxZ2N_3p8Rvu!8b--FR>uf+%AUtQR%JV= zlg;5(*^Z;E6DM3xqu2L+ecqqzANXGR<($Uj{(L-ckNddY$I~-I11*-LTt`755DQfM zsu2iu#1;f%Jbd^N@HbU`8wY_8I&UK_4NzhC*;(KZ2fa0*CWnEahld@)L7;OW=+!GG z4^qkR>F9ue4UX9=q8#3l_V?#60)G+si@;w5{vz-ffxig+Mc^+2e-ZeLz+VLZBJdZ1 z|Em!Q9>S-y)pd&=Yi#gtfW9l}7abHWKV+31B6&5(MX+c0+a8c(36T|f4Y^+*5FOE;4n5U0rCSeOy8PpP zT^Lnmk(J_csh0l#YAF96?k@s=5%`P1Uj+Ul@E3u<2>eChF9LrN_=~__1pfbtz-{Sr z^3KTzN-1M04oI{zx>l||4;m%lr`pb%H}|U)a$pyjqBJ^jpc~IHPf?B|-zb%8pWkX- zdID9oF%7EK_z4Pj&&4n5lnS+zpdPwjuIL1C-DFb4Skcu@7bR~!FPZjEsC9nsxcDy! z(9~}Xx){s=0u`&1HY365ek@iEX%pV2<%lzObj7wdN)LWSLc_tQv;WKjpuc2=x#b_r za&j$KO6hBWSN68J6(9(3Q*JTMDQ-=)gQIHiL&s&mR8~vNGcA#k9dj-+-C_4nyO^2E zMSZ-)=OXWB0>|CC(4HUKA$#mgttigPZ`%gpsZ>zdo;`^CicqbwMwCugev#n80xiwR6D;Z-PjHn*eqqhXG7 za;|x9Xilzcu865-mXawfWf~0i=c>s?V{5{?rh9y89{=6O6`@obI%;Z0FeF}b^tMfK(=%>vgPqc7?cF)R1K%W5eZ#D@|E}zn9hc6#eEBOn7vupY{CCM=u0<3=IKVRaJAQ z5zsD+V9FK@O_j*#>x7OOo3?U%Vj7&Pp`}52H$P{pEo^oa1>u*eQuSqI?P7`1`<-2W z6HgX; z0z7Y9f!+f6NXo`HBsq*9uu`=$#d8j_4#I0_Yhat-&0jC1Kb&c|>Du~H`Moph;0Tcd z^Xz;S9ptvqr9k?nZpveUcy(=-(i%6~Kt4Nw3wz}+XcIU!6wxUp<7mS>vfb-t1YF#` za+w|NzIUW1pa&DAQgzoRJGaO>w7wCYcBXz~_RBVWvHRn9$@$gj@pOzHTG0KLFl^@f zQ06)1!)-qe>0+;4y?H5on0nZG1HjI&6>h$G#p+}C560R=vqcima9bLrw$cRX2M}dgq`CQ zxC^b+P_>J)E)xR+U9ti5k}n|BLC`P|1Hbi9hj22E0t-HyCJJ$j$@yI2O_7OD0YU;We#7hNQ(hr}99 za$*ZSg9r6fX(v_7Vx4~9N~5MN&=2g&ix)YxbLXIo_xOaDR-?t2R_UI~<-HNZjW})l zL<|#QC3ukI^rHdJnUSDvEe)b6MfEZweanj~r8_K*V9odZ@Z-+L+#}k`n#r3|Ox_2D zU3VCN;g8h1Eq55*0&HTQ{%{isiC&rHyL{2SM+(M^KW11F`0JnB5+0VyX2dfkc;-gM z5~d7f7GKq3%PS?rX~JbeH}0LSsVmy;C=3WhuaMI=kZ!mmYdWm+)(9H1h`NYi&B&Ll zM9%c|)Cogv?ja*cLN=88H`x0n0U5}h3nf*at&4S9C~NfHkpXfHr{mc9WFBqVdRJ&W zih5WA0i8<1-$?ZN)fcT+kQmiH=o?&04HHU_!%7I$DI<~s|Ec&OK&gVsdm**IWF||$ z;rHR&5uxsPXMbb=P$D0_4n5RCXLy+}20LP%%86$*JifIx{7}Nh@&dHAg+gS-H%SK9 zFF*o2Bh@g4<6;h+yCT;Ah%n|94*TvEyi^$nR;j-WCG)CZyO;E8W^39xdJwj8$AWxd zW@M(N{#f34}^;Zn41V1mytREppeO>4#51?t6@8X$+Eh!0D z`ItM%@Tu~trOl0jr>=V|wf?NUM8~9FKWxtl673qyj6|1RLPQ5zaN$8471@qmE$Kcs zr%M6v3|PnSi+k4b=!owD4tnv7-vwOC`O*l+jMp!CkG%YSz`1|Li+f`ik@L3udiI6w+>?{V!5z}52PoJSnM&aU z^sN6~9TlX{^|{Q1cnvV4PtQu2Y*DOTL7L_&8z!DNBuw1r%6>%do$QbD>xG{z2HJG8upwS-bdsFYD zr>r-BLB6YQwx%TbMgtz+Pt!=w|3^f6FRxWp^%x;4nv`WYx_J;96i#}>Rac*DskOP` zuY#N4*`BL4ot?>X>gFPiHuhMM-5v*ah$C1+cq>vk>%2y-*sG z)h|)kA4<$aTgS@YAaru9b1h-85BJG(9qB@XV+(Q3v&|wm`WHjI^nm4#C zuTt+k7?d(3S3*05#=zz&J=z-ySd<+#hoiFg$8&=kieQ0@XAmvoozMiL5N<$oC3x(h z6TH-XWY2?xD1nc#%g@hx$6mun5U(Hm0Y&-_M9=de0I5YWv+m($E^#Qk~W-mhmq!C$mfV0<0mUK2E zOD4>fCvc2Fk{#VI9-a%S5Z zVK(Hr9*wz?JT8JFNZoym`u5m;|9d_%GzHYKRLVnir3z+pEU`c zlglqO3-eI6TpU3x%?m9^Pf}C*2DZltuU?SEz{v4y#5?GU1le0e4zv;aM0J?^59!|N z)si5$LwC!uw{jYWlBIG^O;T8( zmAV^w*pV(bcd|y`2U3`}(y!{bont{Hmv_?S z(p%pFUj=i@JZVuHLzt*9OlnU^5HF#~Sz^2ve~zx|d62ql)D*net<*Rqk(M8Rzw%oi zuPZH3X-f}@^yErh?{OC-i6#kojSo;3sWl$2=0&P4*B1DY%ayM>{i)Fj7<_euuS9i< zz-@S;o7r4o1K1HCG<-s`I)JiTN-64`OuUFp8mUngL{e{Sb&85%+V!jTbgK%G5}k$k zac86lbsFxa&^Z;@0!t)_rX&;uGeiiI?`85Vd2ly=XXwctYP-u4^C++*vQQPxZOy}r zzwszCX=P|slM)z)P4TMy_z*A=9XQ+_?a`%Tc<_zn#!bQApcj|!JowTv&J#pn)O4VG z`++cQkKFYP=Q#Fx#>I~Z9PVux9=T5yL3g89W(Q#h{DUYzPa=cl6Ub6HeF+mCw~m-JKd@M4=&TIu-s1cF6!g)ZVADIJC_ZGv4I-@i=JAcJ zD?}lIuKUz!(xwBF?*#tTIq0m7IK4fedB$zGb8z7&CL%&q&SvPSJw;Um=Q=;7ww0X#4k) z7JaF#&5}>%h?uSy$1vt8+LA{wjJsP7uG+I__3eEJf>!ZH#8hKVsl1`sE^M5^@g*6_yEzl?mf^4uP7J(Uf?wpgd7eHAN zA0it*k+hm6pLTqC)&6t?WrdD6LR@LPya#ww^PaM7NVVBaq*z*or|L{m7@_{xi8o8| zwsF_BmCT8*l)w^vbQJ7x!W)&eBfegl;G7CoMYaE_E}NWo!R6xW*ROd~nZP6==gvXc zCn*+mH-V+3zK4w|L#{uUCfz7{g|cM{t<-jTPGY#`os9LX zwmRu?9M9aLkB6-g~6+GIdbnm>|=A{4>tD?m|dl) z8WA_qYvCjY0p~L8BA#{txot<52`~Cz+=l%gHQa0kiJ?aqCMk(!nq)~~zwZJt3PlR9 zT$z(^=PV%jl#q8raD8((p8}BSZIax5uH#)C=*(}1z(o&qSpfM2!&)&m1f2-IRsX)# zH(g2r$4*f-F?xdy<>gBOFMyq=M_WbEEiGFH2{G;hum#E&0euKA#g0?M;(u`}eEV9` z@R?4=jG;|fj1u?+OKqmy1a*Q*!n0;jWU}R$y)wk=g0sHV4N~7SH%0X}Q4)PDW`!5Z z2<0-3S(|iyj^!q89*5c};6{MQoOY&WJZTzEZYquO+ruq9dXIjtXnG8u_^_m|==h#g z6z}6k=6&)b13LmHxxk}ODT^!2`Cp{|dQ}s|oHcRCk`bz8V)SXGG$95BCe2Z(69!HG zmk|7?%v*4g{L3yU+XephZhsDu9{b4awC!XSO%IwLO|l2w0&i*%o8fEM$ujV@e5{jq z+5}}WaV2)t9zVEw{*nbzZFCb3{nACw0d(c;8EOW7{#BXJBO-e_C@9kr zMv6}IF(C79uH<4N;7AA#qI2hAA2%dmkkBoUTM($zC9b1)IM3rZ0xGkV25)MCebSY$ zz6i(4!tLeIg z!_Kn?#g`Rfc<#anS|uSC@HGvJL;ihqR0nE1x4j*0?M)q`sGdihVYUtsgj{y8))`{> zUnS-?Y-ZrM)rk~fubJ0~(O`XfTr_6rLJ1T56AZ}?&eyqFqoz-MQ=-fubCo!Rw)UmY zQdGeRe&*W&N?%UN6#c(^W8Sm9Jg|eAKL0!rjJ1_i5Yeim60_go6<|axz{W$cx?tEh z3Qb$dm>ASdVQ)MP<%BAAk)&jC=`E5^w_F!>SXmNGlk{9#dUNtLCh1hFX;WxKTztYr zb@Y&ReOk}-6aQ#TdF$5CT}3}JtcU}wwso%fPq_Oj5CcO)A+sj8Rl9Fa#PAfu9uc^FdZd%M6~t89>TkqL*6A3@#i6~ayVUrTL6?VcBN=A?ZBWZF@1FNCQ?laac0Hc zU8_dk#LOO+3o+p^3{CbDg6$Rz4DbK(Ye1NNmEI&-{73+OOb)jl3B%rgIm805h{jT( zHDZW#&|17t+zv-#1Va9puY=6{t>0n^+Fl1Z?A9I02mBrk62@Na2@ST({?7}(w^NG} zK}7R<#H}2G6&<@@!!wQi$w?{W&C7mX? zGu~4#X4)JcPxcL9`wueh$MW|5>VO}>(H_0dg$GYkz6+#r;lr?I&@jx9ls#vTgXyKF z4Q-F`Rjp8q`#u#;f+0XW5HSCj4>|9PSZBIVyJGqU*pazCXH2i;EE@zbhKO~!8KRm0 z{j^wJB0Yis>0?lxB@RGn9V``7>kw^xV_e*FhC`(V>^l&zc4?-$IfJ`oBdUq-7=cpO>h zqXfRhG6^hj;*Dc@&d;(Tx1E5aBn^g$UUM=>M8x=s;F|fD?e0@~z&uj3hoOuulqbKd z0(gu3!%WeM+8dSF2Hl!2!j|PP#E!Cn;uZEm0%%vra>H@lA_P~YMbLUhAR9oDH8e(n zu0&Y@MArF{8$0B82p}BEgCQL-!4#eoGEz6=?jFH#CgVLNX06bw$MH;$&%_3hW4I#% zagaE_pHZCCsL7deYbq8jlIHc6SU7ykTx;0We57t=ZpNpt4?nDYdzGiKVuMn|>WnNu zc3-Znx?dI%3_VDLs372e62L}3)~6gFq(!^|hTVaS*(Zr=oncjO)VVcztax3$hK zYdWU2P)2fBQ{A|Snw(O8YjWL4V~&g_V7q;&OkLRSVKs`O7s_}Nn`uW38sl>jBm;5a;_V7*J#IfO(!Po>Rv(A@OsOkw(MVYiCFs!@btTI z&+CNNb1#Sb;1vZ}=o&Tz&o-$eexruKfq^QI-j*CXg#M_{E^= zSrKXy9ASlZI~9Y0dBDF5pbB)ZN3fvl!LtI$hR-C{C|LIGvMh)`Ku+f4mNlnB{-N+C ztwao}7$&drs+mQ<+87^3EFUk)(~F-Mn#&I|n??mp4?6CuP2YYkbi%U}bS8q{;p%sa zJ)o5QHP?tk$GvV|g(FI^?bRbE%*X}f@;|OXy?1>2wgXw_ZDF05imZtlOeW`yaaQ5c z1kT6!#S62^z*C2>%gN6q-ry_BEH5v~(_Sh_=u&;{4d>;-AK7_kM$LXK`5k#A=H_R5 zacJwcj?H%%iHP{f^D;O&xcmi$rj2^+8W2T>jESD3s1m%*1jVXZ(&YKAFPKn6%bhrA zXi2weLp~tPs_a%$EvfnqRpOfea`p-%9liwp~3z;Hs zD#Ky+X@@W*>>0@8&As$I+hbp;fztV*c2XEr39PZQeq84GGmL~RE>6H*XqFXt3?m=jFhD5}rLm8IE|P%}RU+5LwN(tMqo_M&h0u|MLk z9I}8{2wyb-OH=gAnh1qaF%fM9GCM?B8ktvbWlufg_89A_*S=L zogZrAEG z1rZ^yxcV@P{D|EkRJLudOV71iAiL zJCce_!xS*5K0DzA50b-?z-eG-YqDzWS%FzDsP5<{k`m}c)@Z(H-<^7#e;NJEL94Cy zdA&4A}S+^d&qZspaokE~4Ax`04X=O=piU{Q|5p%oi@W1T(p518R zkD}u;H{k^GQAoUX-Pc**aDMyy^Y*=P)>lyNDVfTCZWiVv=_d3e9=9sO*QRiiSFcu1zx*Lw8XvC>{?3^ih1yLq8tE6BWKHQ znHrS6UvfCNOL~?-uJ}ej>Y;8;25DR$e2oP%$`zb925Ic3^TpC6+cZU$7ZZFxoGF%l3Q z&Py|2*PbdO9a$~iUkAgGFC){r@Sj4J@TFEy3Az|l;^J3@7Rlfx-&WnC7C=YvivL4L zQaI-1%@S6UsNBQiw*7H*I70@4TP!9`)L9Ig)JidSK_3~pMI5I*Snp#`-~J+zq>o=7 zQ?W;)vHvDhIyGHG>GquJ>ou#*ekEcnW$KWuO}Rhz^DlQ%-(ga6VQojcNJ0mr9@-Ui z-lL|07sQ>lpvGW*LfS9m@y<8X3nD4rm3dawnKqPL?8s2!{fyQS;EgRVIXC@a)M9b3S_{ysT?D)c zadN1}&S}M=oL%AdrYODm%0Su3;xkxg7Ne}|Mv;Be?iNiL_ku&QGrvJ&?!*Xd)Unjc z&wRSb@ms_IujnV>1+I!=e=dQAgn(2aY(iOeYHWz~XbMpEIIjGfm7BSwuxqm>*FPYV zJ8zL!+BA!_vX*JC+g~A=SgRED82ep-XZ*odbF%E~9QV#Unn^F*&MwV`Z`25d_Vuau z%7Xo9I~6zf*IGb=Y7#y_0VFdfy+B^RwLnQvSOMyEhP?HNk+XGG`3_qN<+nR{Iq|z* zI>UcIdg|K;%U#O6(ddtxRv6u6gYqT$m^_uFzi&(7_oW6I5cSc8GPvn)W}2P^G7EBB znLfV~<+oku``ue=wmZpYes#Tkw(ONv&BHct-6T%|Ku;N`4Q>;whLU{r?{f8D_P_i6 zaaUMx!zUAS1>{{(-$n9;W3NWik1fDvGZ{80Zbm@l*I;SYd4}2SAW`E0PA@6!-VpH3 z683QX<4!QneX5$v)PsUV5A5Z7YNiVa z@#Il1yFbgpvbr3~niJ$@fg;h5t9^@^55OC^Dt$2wUc7FdJU3ses~N%ohi6sM458^j z?dIEQdy2fO`gMV5=f{!fyb5E>bpIh3 zB6?Knfy`jC#bVnD?rO*RL_QkWC%I(uG|wgHTHe&{>sJaZ<mc(w)jQCi%uW-2n5XVSJ6Adv5!tpE>NaX29KiUEfeb#Ct*@nL^d6F(THN z(9RV$OSo=&D~uBFcQO?@1Uwv)|0N7vy(VGjuV+b%lR+fZd#^oy4c`p|pZ4wN6C=<# zm~lwCMkiy4356_g_XGc-OR0&gjDMOb;iP$OFPWuPHyB`qf z+rBQNfJ*m!s}sPe4@95%g;MWCKF|L2WU>6W^|zhnwdE3s$k%!L{rTaf-3tbRe(rmk z`jFGMrW;2rbnQ7CmE9y}fufE8BKGL10Gv!K-lcfx&ED(xyL>j{~obVL~0~Z$@9&-FS@+V(6wM*=)_X53)bb)(0!j z?scs)p6_?9BJWX;JbGQlz;CyajTNdA_?q#Q*R}vaAHD{GjA#*o5=(5^xqH#7DyvgQ zDiy^_Ye_)v{69BReBX+pBL{FhgnaCE{+YfSs}q5Wh*%l+4UVT`0f8S0uK*g*<@Oq= zH*LJd_B~Rr`#7sG&W_i(m}AoQVUTCHC;R1^h! z&CH-i=W2iB<sopU-vZ z?H3Z;0Bi2;Ze^dEx!n%8Vl(Ts8CK%~Ms6kzp{!N3!NF@CSKCe&Z=hVS?BqU4$wQB- z#|OH_`%ljUeQe)0si2~MpPJK2QkIZ+1~B&jsXW}A-wx*IR%s1Hbef4jBhhVEgaHMu zdVBJD$8!@$EW{X>;gA$h_;^obNkzO*GB)7oO|p|W-vC~UR-QbfeDr>G>CGg)mco7Y zZ`)J<#+Du3+B#w}jdG$DjjvLT?FJfy^>xnX_?-@y zz^pEsLSFQx`1#hq+xm^%_?GTztgGdeIhPRmZllJHd~ELt;dz4lBXM^|7}~PQbp3vu zZYpJh>uqYB;#?>2M-RDGVHruA^l(G~Sw=u~0_1v4TG9pH35E&I%Ir)dFbV*L7h7ng zip|Ja-&?1#+wVrKle26tFJY}=mL%jjx0%&Qx$GW41A(sY&slt8Lh?z9G~Lbi^1SkZ z5^|C|PIIbomh9&5?ufhfWp*&~;-w%2b<-|M_@<*b(}#yIhjbvcNDPlVeAj2?Vz*;t z?`VrU4qRSaaZ0x={hcVS$(-Yy*sW}>NH#4nnwALJ z>Nni&Y%w8?mZ#0e&eyN3q;!^zKb82t_QAGSw}wQbD&RQnk^qwHSNqQJxz_;|k zH}<2?_l8HgXusX6u7Ie#n@-}}qJHq=wXGALb%gfl-ja0Ir7Rg4)BX zNaaq$H}!U0{Ikc9YK;Vr7D?lyqbNOIDKYHp^k6x*apk2?YC0R=Ydm|ZHrGCP)|?QM z@U#s0^|;R!5paKKN!qi}xu7j>klU!e|6j}8?^4ge!b|j0Fa<|rPMX-elj>Z*q@9%i zy^-oyG+#!)7G<0pG^JCcMXW;u_U;!_Q;c6c@BAG5M1beKbE^hSIRlEOcv0!aehw^x z+&C^t{W@YnFa7<;$0Y5ID-?ccav&`gW{&jb>94I=$Y6J0P?mJDRNg8#?a~*!HPYe# z($psI*2#ZuXTND*HzKIsB1R|km<#olHK-C>?mj*C3Qz4rtB~jQp$!Qu3Q%gYBVmDBW=yD{j!N25-js^?Nk4Cd!#iWVOZ174onIBY~AJVp5!^_7?eWw2kbWj z4cDou=r!=@SY3aDRjZV^qq)lrGUKSA>4z&Bj>rqX;GyzgW$#mAZ zv{Q7{3(qf@cD=b7a&m8M`wQ6E@J3;Z%>%~)L!P+AyG#lD_C(z0RsISB>MgaPGtCO$ zze$94P^`ZURktT?xsS~&EoW?MlnsAU1H&BP3ay71r65*<&K1}p%9a|sp5yMROKfVs z)M~iA0wPvhBR$yEls;b{v%ZxRt?OSqJz&uAGpa|oM#dz};qhLA1X3>-d-i5{Cm>|R zSJBKKy|xBS%0&MN-d*2mI{cxvveVc+FsRGk(5t*za=XQxTLvfA<;Doj(!Rxu@3}tu z55;ejD_b4l1Wi~{YbYVF04mP(XA*(9-|-uB#;YqzF?NU~XO90KThAL&rgl?T-Df39 zzcu0)*QV{CasV@BlFnApq$Ub6;wL(g4}TTBBlAD2-g{9iV`ZNeAdhMUAwRSi_Is)`s`H!Ly*lmPGmzn%h70lt2Xe#PQv@maI9I z@TR+v%mFkK;Sris|0P|zF`4h&o9q@(c{1fu?cx-tb(Amn2WM#wfV93+z&!z@6cI@* z1O%1ZBzfEdh-^Bm9Pt8gAz#>6OiE31;dlORAM8_+9|l14O$ul=C#MDZOjdi!R_bxJ z1&k138?LD%Y`otoj4g*HIUuwgY#q3c3$M%ChY_X+%=$Gm2`q4WFangtM*~ zJv^ac&F393=HrekCEt+UP3}OA|NQB_3*4OsopA)j_6|Pi{GHI%{{Hs&chhfDg9V@g z)ifajdCr32`Fp}GFp5CxNs_&Q;De6eqo$_}HP~|=*@?)^#Y_Klx7q$LXy)h93^unsH?>;*IkjIt7JKyF~e&}!~!D_;Mbk?k^NyEx%R;!k@L&h*+)4hg0yxu z*U)93&}?X=2CupVzj$mlN|dSlH1PYUX7s5I^twyD&z1ZiYy>hLG)(8YUtaSw%2q=7 zdNYTA6OgI-S&YOULoj^+;=5C}cswU0z{033sQsFc{a$$w)Wk;C-fi>{pIVgCE%$wcVyETY5)3Qz|W5s+tx}AUB`>%KvgmjkNg@?Gb75-3_W1 z_0mQUDA_%}rKJ1>NCY)=<)<2t3v?6Ke0TJMuo+gI*m@y-AmLki4Y*4h$7sJ@wVOk* z?a%aB@X_a6i{Eut%(ED%_oAFkUQ4HO&M&2SRRg0NM_Jz!JiMvEXbES|hfB!qRLtgi zqd;k(-h1R0Y3w+;iMlrp(-DWM6Q7+NRN1}we_PfT<56@n9WKFgKS$J5kfs4zpQEyC zR=#RQ_|87mEBIkG0VUA~&kLXw?LwB%!#Ph1*(SXF|LAz`hh0TVy>CW#DVJ@5$Kp$C z!u&Sgue{Lj8^-RsTZbDm{WMPfFnrAzsuq1pZHRQ^MLcW=8#|>DNSwx0Uluy=U#BFy zpNUlNjFWXZ2g`Z%NB4M8X6_0jx?kWIr4UzbLbW#n2?yxX1ZRh|hpzD~T|2RHQ2dZZ zO3Z(^L{IJ+*#oPcLS8}_C{JwODWuKMZ(RqrI%CZLT7K#cpuvO#{4Xu>SXQXZGq#32 zJl{$F%9m9Pcb-AB@GU@lR=@v;_ikAQ7=+)Q@BQ@g7@dsuv6!2uzrYvj9Nb-tt@6`? zsHjXpUhNW&WZJk5SWoT+?6lkV6E5zcDvhF>+s>$f1h>X#JM+a1`YlL zRi8PZ5_YE81Gm~v@?TK!iN}Yjeil9op+#U_&tGjAC$(N}lSqtdu;ySOh*}NlCGN*I z(BnTvOP#ht;BMi;tKUl5!$P`iZM*3=eyifcq84VsK+F+m`!tIN@*DAclvaVwbNApS zPcPHCIyUB)_WddD0<(Q#G76ioB_3>^n;ATgCpEqgXt(&Cs zh2?~$rV|*Bnb*$L)~!3c8U49~d$^u!Cu!*%y)SdalDYUg?8nC*33peft?e^OMeYG+ z!~%3Tb6T3WVL5X#!3~2?7nm(={G6VhL1zX8B(sA69RD$0sEJW>n#xKjF6t=HawBo- zdj?Uedj?QtmG!k_t*Z~D(y6uZo}K{fyjEImE3ND+jl5uBZ4&xc9;$jL` zRd=|=@f(d?d?E_(dak$q)_Y2@JM0I%>ydxC%t_{>=G5DG7@G{Mqr-4MwUg`tRcS%h`rOJ7svJMikRnyZ&t_0q=FuZV* zA0i3~&>?yrXblv-XZ^mK7Ty>;`uHO2!mOTgTkY`1#P1kC;gi$d8!u1Pz=$z}raIBl zF~8;0AOW|?g1i3c)QSBV$N}WLtp^;KZ@J6dzx{MDeSYMN{8^dQvze`~$7OWi6B_+a zl2Db6m=KN?Gh}LTLi$?a$|plh-*zlqFRez@gtwzf5yBcXUo$AD^J-l@4MK|_l-qrT z@Tq;1U4Q{(cYEy#+S;oN@{)7`4V2$tPv9NnwH2j@;x-q5GP zm-T{QyjS$>r)g;QXSoD^>6|s6*JFLS)RRVs)9I?DpH85GA^-|y=vsqQHR<1}M*@-b zZ-qYcpKiU!eAA_5j%&D}6O|Y^!B2q^7<`<{5<9nrT(3AbaS1gQvGXD1w z3myy^AYEK8#zpgwoo}qJ0=j#hXmg-wHphFRRKIy3 zO*X*2T?J5viq6cMqp|scDLtJ8w-W5Od6OV8={J6@Hqi1SjsZROttF$b%X8S9d<+jKe$Tl-dA~QahpnS`xXg3T-mpbMF7TYg*r%G| z06ACxv8>0Kp#*fHq(*`=!OiS=p;h4$S2KGXKOOF<#LN*3fuP6MNA@SutMCW<2e8jk zqI?}8%2^65iLT@O-I_lq$laO$aMljaM)TSByPq~X>Hdpm_)fNU@BQKM`` zz@ZL5LBsCgg1MPdQ8&A_F}nJn_n<-I>W{3t$aV0F3eZ6AX?VqLVjSItN~V{l+WekZ z+7=j>|1*f{ytJCJLYtlAmjTbPlR({fc2dsDNG22q91388&@k9`biIi4eO^zD(Cji? zzJnmi>lPToq}T{J5`Ccbdig&Rv@mpqEaK6UQ^da*x$HjX*EX4iOdU0?+x|&)f+OGv z<0BGJ4K zqR;Wek7AxWbd~|{wmyo`9&(;0kZWH>GYSr+ZPt&c#{>{OEv5I z3#&vaYxC&omqXlW8MI7ywFG!U#F_jY$*S#d0E`#{rv3FrS@G>I`s$-)b32|QS+6}o zYn>3G^}6U6LDLu*a)Ru);Xe`guKTW4clCX=U_iLb7F}Y3LhSMbTC~`>&7xNF&=dWj zKKqD^xPesf?fA09uqv~<$M?!w0h{0oMSEK_TEyOU$mzK(TarzBgJvSVE?1;k&Fnd# z-o3;*7*SD>l^S+=(!~93cj1D~BHs_rm*G9joS~v!_Q9)^RPQ{$D2HG<=5;$i_H@6` zrQE=r$@J(0Xsfl?_;{stau0R7b8=v*c`0w*Xf`3!?&~C-dEou6PsE_jZ~r`*4x@05 zVo1@VX(>X^A3vGiGSh2df$i#B@U6Z4_fz-7+d!wlS8X9@?C4vfiH&8+U5DbAimRqJ ze%ZrnX18Yt?|x77&Ujqu!f>iqKTbMosLu&OOHo{ zu4v1N$-Wb??cqgDV{3U_KW~|$viVdu6YR}3l_Ch9@7Vr0%_wta34Ld*eg;IgyL?FXwvomy=dBOEi<#fbBvyMsUBe2AUa2YUHG591{P|PK zT@#{PzeG2GjP;D1SYqdW8_Tyw>(Vxs+0T0D`h}w{R~wI5=-(|ie)9P7J@EFk~Oy&&ON`Ovfd3ybTi164MyC%dcx%(ereF!c}GeUK3Nj zNBo}G^cWkgCi?pE*tVZlV5cMp65-!Mgno7FJM!yJMxbv$CYol!*cTF6b|Ss>hCYl)YKFJUO~3k|iG- z9@n9|{Cewy;e}|M(-I+c06a36CftMj`i?J96WC(_<%^kiy|LN3RtugL65H|*!sr=A zv?jMmNK5cIK99dJ$90hfte^Je-TSBQx34~{au)W~@p-xA7kBEWG<;6@oB|01j+{W^79lx{7!R&c2@T3lFO$#Zd(xe)MTclxFA@We8DH&eLF zVQm0hBqM5~myq!L*pb^9I*zfNz83M+;68_?CvVG9Qv%Ab7w#nhGZVWu7JO$flg{8- znBf0z&3b0__^id0LiEYvTaUcEr+@9}#z__U{R90MPo2V$AyQ`|CD$;VhyUmDf=ko= zv1QN0viqw74bh)lwQzBr_t;Ot?yKq4a-FUTbw#54i)q32IeW4*S*^3iy^$v z>c2sH6sB(*8GWz^@1N%1xTatY4B_=F3E4uQUq9~`jdD^|NRuW7_ zlfEmVy?32f3tGn~!;K>mX1zXzy;^-z!$;WPNQ~ z;FXz^va`OyFRHvS1z}|$A=z^X+19Z_=Bb#0+zqC;k~Wt1anFEo7reK7V2FP&c@9Q= zo!@w`e0j2WfLJwfT(92bY{4ulg+{n~?X+#3LOLLYES>jum2(LSi1_yN_5UiuHMlQX z$TlrtN!>|&j+%?J@MA6VJIygYdJt;$;DuYc*kRPG;O5mQAIsdb*{BI}qMu^{7qtI- z8bHCojKGe={3Q7>b!Iskv-wfeK=Uer_XkEH_d?*yp3BT5k9cuFq&HWY>U#qCEsbbP ziG|3As#9Wlc^6b?#Kg|+UoMD!4`$mY?{58A+0UB2?z}QwaLdeJPDOs}AJ&vmYYyp{ z(}@=@!#A7l&FX&DK8^v*&$<1dn9A|*b93QqJAq>wD5Z553owg;#z?_`>6A385kou{jaOlefWPI zRmOo`*AN^FCgBrO7jnWE__JUFk+EZEO@|l*e=&N07vPq1ex5pV6RsuI(^V&&W#x#- zGpR8hdetz%pD&r}J+FOhT(dU~xM>gP`X55ju|pQP?kYY%tWJBV#1 z(*QD>8Z392;hG?gpnLsI#E!dU-+ko-^ha~bYE0HZm}5y~b?Eo8%e@^qs0`}5S9iAMd$5HnUBh7nv3WZifAHfha9fJh3A{ghcy)+WXF^rnYYFc=Xsf zhz(H`P$VEAAYD3wl+dMx7Vt>#nuOj|z(SQkz|fIUB28(LAYcOoLcq{Ys7f(}(5v)s zL(uoV@4e%W@r`kR$`8wMx%OIf&o#?4pEdV42lnX-oVYx7U{a=pGcedA%`CC9v}FpAy5`f77aLsZqaB#zDebMRJKCUY+Y|iGibezP#CK6ZP97-6G^71ri;@b2p&!`sI{_ab+nd0 z8C36>?n$b`@?>aR{j|1Y43lMXLx0*VXFWZ!U!MnWGA=9GYx69x zH#c+k$eV}9fg|Q*nwKuAH8*?@rHATZ2QsPr!3Hf^J%>jAv}$egpX{1eSqOd3eA|Xv zufXp0bLaAGYH&*T?2*QoYyd~1X!|&#J`_DYpiN1STUwxO2p@a4S_Z=G2I^OA1pGI> zXyZ?6#sL@i%kB&x*oho6&n=BA7WmHbLl8VgCkQczh zBUkaU+!TV_KN+{Xx)l#>uUW?D1vXltanR8rHh@&fRszI6lqawNxV)g1!{_uc75L?pJi$nraIY;2#{*>)l_sy#@Vp z6pY>|?N`Y`8Htf3^n$mGk+`J|yv~3yvoEK#+GO=F8>QHg`GgT@<+}b;v#Xt45snGd z1KbAQaxzfzb5NBM%QJHkMg4ac7x)>7F~i3A5QczlwGF^9F(zAGRw}oBMLO*nA2?Rk`3~Ha?il>E{Wp`?Fr~hh(y_+ z`{49?>JhV&0HTX?X#EE#8}p}5#u$a=v$Rl#zyO)CMuhL?W91d+%A`$e1JT%MRj9K^ zWvm^`m9)*O=I-p;&a#g`GGqO&@Is{ho9Ei97VMTQj(=H&JGYw2!_9BWUcb4e`8_p- zo0jxoxQ^=z-Z~I)Y#`U?-5J-mVzY;za?IC%7=K`hL%cH3Id(eY=~iHtt@-P-u;ez4 zMCP#~PIEyouSDzO#?WL-GGZ{3%DDM{pHR@^skn1K^HpS5)F5o(#a~dVY1yB?>e!2I z&a8P*bG7`5s_{^wn-`1Bdn73p(WQ(-8oWE&cqN5!?e^A_;Z!;bnSsUa8|IQMa|VRb zAcOxjQV|VJrevj;s=w7~P&-;ZSf$RNkztI?d0KzRdFdgd;LNBga8=^e(R#8LkfHY* z;N%_hjXBdq&JYeV)sr6F;s0WD*t(bx8?DoAuOY2&R?%#wn^e6viC5I&3_K?>5XT13wTK1O&Du!<}k!jfg#@}pt#(`meFoX1$X zDm1fB-?N+`PHU)oorR<#>f#okD$iwzmDwC>E@q;pE}UJl6<>eRD6ed>;^Sdi%y5=Po-j_+v50qBEr$ zf(R1Fw^gmzKFO@ts;z-QJzxOAIm-*gxtGMxFFt2*C)@X!!8YWo!qj!carVo`Nu#v| z$mvRYMsRlz8pe`L5lk=r(46BrHTh)VeCdbVuixms81*pX9a*unVB2qLO5{KOA=b0Yuo4HTSRVK@S$_;iq1;3;(Aza1w_Hv`muQC3^uJ z<*eNDOM3ZG4%BIjY#$xvQm`)(PIHyBeZ8*I^Es*6vLP~UMPQ&>eO$N|Fy-0U^E}}F z-M$})B$nqk`nCG+?%WSI_|FGuimyucj;S6iN; zgUw?fRehde1FPi0oY4a%)BOjtswD)e{adK%X8`LSo&5*3=M?n#3)n9o_>6JFcUK z&b&SHQYGsE39)r^bL>xl->p9sW`_gSh~?dHM0?$aU&`Jd;qUbcT`Hf*FII=H;xIwA zUoO>Nr;?s6>c++y5htBv{qC1urQULckuHi zVmF`{mhZXOHn=SL_V068ZuFPWA4^5*Il^`3DDUs!gq7kdB9h0n^)&eVHW%7q4^sy5 z%X;)8zb=lpx>xmgt%JWd7%g^jRCaHjFB*Cx70Kg%+o42q_}e95Md(GZ*f>GVxxD@F z1%Y&re82HC6LHckcCUW`GXs8i3PVmuqJ)pa_HWYywku*|hW@5oaEjh`U{;dN$K|Xa zOX%;)a((+THbFOtANlkmp!804&q&(CHoqetJ6V+$9~!)1>%i8%@E}Wu z8q7`8wDEIjn4!Fr+d(Ev0-`ozFsm1&7$K^}O~#?V{i!LnA{kqz+Viej?i))F{cB5b zc73R7m*NWr{aXKOw-w1IvqDNRXYD_t2$Jmt$^AIt2^2T^<;xvs>xvOU2w@KASkda2 zG(ijZl5?Zg#!1y${0)vZXHsz3=b5yaDh(WXz~Ta4`w~O>mH;gHs!+-4!2DB!Db<0*6~0>14D^la_uq(`q548l}SO$tb6;kTTW|dHNeD| z)Z98`vwU8th3(P8d>=6?-gz)VcT*EycN8`b^PvR>VEu8YzJZ~?x#e4Uf>*$_U&A3lyH}f>?B&jG;HaUav^me~c6IW+na_hZLw=#5%yS&g4LS|^47;~eHcHXb@Bw$j=zIau!}R;^MqfS0&> zX+TalBG7{T1;s0QwK037a!5<*y3>$PtzR+5ojvy!ljcg01sn=U-z}GJ>|JNfy=`eP zrmfQB*AhiJ-%@2XiVPc-RW-$ADBdcFo?s_wD~W$7;Y>hy=t4w%qln4ovAd49V(`ED zdR2zrx>Rf|79@eAkHE&F&T5z<8}xZP^A}yF3iD|6ZRZr^Ad8zKC3v$5X`hrv9WF z@`*#v*2y=GAzJoIm&#JH(JD|}cVUfBkbgsZwa$@&Y;dZ7cmA#HsTlj!506!$xW`UB z^IABoU@M1((S9Sb6hY?)5f-^IpAFGW+UQu3E=rz|k&g!$GBWCx%02cv;$}mObN@Wv zIhE*sqT+Kc7|O}Ew!j{f)`KbRs}1}VP_zCwr24t}g4NJJ%A~4L@FvN2^pXPrChbUh z+mP%iU(bv&CmS(Z3Mi{GqCJ;5AWMqqKmMlvRK!h|&ccq2qx~bBLQ4EsFFP-_o4g!G zh67aspyF@@L;N8uJ(0Dga&M~L#GuB#J2gKbW_`vdpr;JweXVSD%QF01s+<<8?G(;i zT0Dc#V;_0GWQoo*MdkOX#po_3Fu1Di264NX`u*-Rem!0frE?3=vF-zlfVrR0O)Cj> zi@-)L^s;1JGuIlo;kc@U5=do!ET z$yoKrD$pBaQqO0(QnFQBCm&pMf0*)hH~ee%jWv&yXIxeSNu1t|VKXgqRriDIUf!`A zN|arls39hAg_Yvcz#L$pF5)F{$NM#4=fjG>EUp={j56hL#D8(3htyPJ26}APTW6NF zdk2VHrz>w6>=Z=Ax3(YtD_mpHEewR9#}I#@)s}lwX(9)jJQCa{4C_yw*Io-67hsju zqxI`f0QgjTVZ~w&=h>?XmE#lRPDOFBls@+w;NU&LrnOFfZx8wdIDg%NvF7jOegT~f z+C?V&K$SaqAqb4-k+ZJpm|4o8-}pWn-kf_ZadP%db+D_n+Twk3O@|7bvr7<;Z=Fe% zi<320iHmSl@t;dvy_zHOO;jFtR|l3y(;Wu_W3ICK6aN?-PSw`Z@{O{)&(JJ&2Ax4! zlDiUizY`!E+(B zCf1Pxs)~>ENyS6>A_?XC&%+CgfA(xN;4O2aarb%X$Ol`F3;6nIc$Te3rs!L_3yNDFCupDguWpu6r7-^3 zv;v}=j1fY{WyIeOc8&?SA|O8D#fA^e0eB@xhxZ&ovqN@e^ntWk-efOp?6wq=b)$NT zFDhiLG2{AeUGad+$Rysf(w#c=zj;aqDLmhpSKO4Wo^Di@zL2b8GhuFTBsX2NMSwm6 z=GVtPd!vdeGi8EdF-wkmt6{{n(}Y8bDedUMWm?Yul(6Y9ZmEb7c@44uVd74MK%*JV z+$a6Fj#3zUtfE`CT&#j2y?8W$=@vLo2rZ(RiJU11s&*EhYkdNgGqBe&t62r*Ww+*j z44pZ{=J}G?WEHZK5ooP+rTF4ap8c5>xMi}=NrQ!(8) zQrylG$ai&7+&+S6g^S3zT&e2ytgX*vX7&1!p73IF3~J77rj*FvCm2s-8OQ-bw^V?s zdbob2t12{ouQwn&qZh7$DAnh_{WNchUn{L#x=x(;M30Hag_oXOZ+!ky|JVaAb4?)W zvg|00n0AuA9>s>7B>N)n&baK2n6!D4^S1TVLCLI9*_sVOZ6olH}x1>5M%ZKL1G2i6=c#Gpup_JX2qZxgA9I7&Ksbs&9gl$S+e?;+H`BjQHLnaIZY|p!|I}6 z+RIwe`iByli!TtgjOf}5>ubdL$^_c0FHd8nReH`r8hD093JTq=wbEwM?J$eOe7Cdy zm1i-SWSMuqFR)xmx`KfBZT0j$#$&cT)^~XiJ5yPnz9MFywiY& z(sg04JB8BZv&t4w0P_GQcBa(_JnZ;(F50Nuz-FShJ;>s(|LHM?B(+U@=XOg|#01AQ zQ(aY0F=318v9p!fmw(ikURM&Q0sC4994%|!GP`fYk`R@tV=sPk0d5F*DhQto;YFsI zN;psE+c2Mrh+nI_*Nn-kF26FwcY7yv1S*TF4&Bq+F$~Z_{W#<0AYxwzBx2R>6?>#<=V?=K~tq{uumE}$c7n)1=|Ho+XOc7(_0p4CIs1SR)U_O zS&(thWw^%(Tebd16r9$hvf}(VKml=(8gk^El>(lc8oXzj7_>R%u{)e)y{pJ4GbRf+ zTw}Qk>N0%G74d!r{j=2C5&)x6#XFs=!EFb5HT3YcOpX-9Oaw|H(;Ou35y$21E9o2Q zCGNQZe4n)*1yU@zX!Tu`$(Qd}#J*=rq6810ZpUWd!>?Di2dN(iibq0= z&;NY8$NL2uu`w*7fW!W+7ZTmT3zNZfvdB183n8hmHC(!G!IpfjLMg$`eABmlJO<6)&W;!X`GMbn7&%jN{FfVNmt zDIw_f@dbv@9ha{gUuB+sYA#6y>VidA%g)3jY_5(DG&A|@$!j5U>y8sT4x7$C2Y3;O zf7Upa(N}jN_RKMC8CBam3NKHUx+T2%2LBc)LbPeReC9XM*jjVhoP40cJ~s|fJD8et zM2^6+bG)dPoN1Fk-eNem8VrI}#$_v#+q+hYAM7`&IN(mKW7-ycTyg4yj88UJL7{$= zNQ?oZp||xiNeQDfVfwT`#O1nw1;6zwyQD3P*j4#`+9;`Koj`AKYCkTT-3CI|S6UTy zSMo!}Y=6u+&w5MAflV;2PlwXk1X$I=+Rh;DoOK?cgMUy;(I7_t`U(2=(J|>n_e2r2 ztV+-N#iwR&PD{67D?;oSevF~)bB2Ud=e+c)j*iI0n#b<=Q{jKF)$YZI0`}7;GO>@F z)XN{#y}ApOY9MQ-*@#-gN7LlWH38YtdBLSM<&N#u8Hm=Hl+m4WgPjB=$=TV_TS?x= z-;8_}VyHi)q3-o*WhP2Zam!`WejYK?a`2qNwF(lS6N(W<}(YOcs zKH4i87}~EqCys=)++NGCdvy&UhP6?DXrUC#Cj`V#a}l87pIG6t?;O2Zr3`Ma0RHM` z)naQ_OVo7?(Gb#8@T0L>{1hs!Zs?zOlXHHbf@%DcQ zLM2Y~?Y5xr(xj&L$Wy(!a39Z8`M>RfcLBk9592J~FtV5QIB~oi{}d z%v9X+@-_nA&VZZ{@S|7A&jCk`Elh-L&F9J0o#^`HdUz*LJm9 zyv9+g+XThyN7{HwITTe;s<6Py)o)%ZSX1$GkYG6Kv9!o>fpEC}7!e?dbD<>+9yclo zIfsZ_T0M5$SFv~717yI!U4Z_1q4d>Jli$DC?4d0z%nlLhMipP`^1gaKP!1!?Lz`-wkpu3Xbx4CJ|C!y$)8W8g}Q? zw&)-N?Gyv{_Z%G5CEK1E5!{vkwP7=cuC+{%rV5^HoxbR2aH~%pur}-$t6fM{UeHu_ zDN*GO$JWUtNrfyqd@c7{Ha2>q`{lhvhVEBRB zuchuL62=80OO6oF1Dbj-M}rG=as`#WO;Qo@-~o20Krf%xokUezp$O&9N3o%kU%pm{ zOv~mVFzsp}kkET7YuK;E&6lBv`Qen3{b0}hz>UTSrGmq$DR1rsO3E07+tQb@09J*b z8Z>fX>zcwuFEIm!5B~VM)kAd9{qDW{kH3`I;`zGYyV;Kkq;xjn?NC68VWPDb(gxuR z#L4#rr3(Cd3yQ;Lg(?*`l@~aCqjj=R0(lCg-0`0pCghLcDG{bCaro78KXMR)nIE#h8I_VE&}^0^i1N z)W&ERvGxUWnNxShQf_CHMzelv=)J|=kNeEql z$Z0;n3q1x}gdBc!YM12)0=euZIghQ@ymwN)IVoG9-xphuDXqVxvjcB*StS*rAwx|^ zFS7oB3i$r-MG%5J?I1O{DXfKkBtkQ_d$0{oU~ZAclg z^ELti=Mg`QM`DLi#7)oc!Vap*`bBC#A9zWtH@}wERjh|7#S9x3q76D5j#@xm!;8h- zzL!quu7nlu1I;$d_&mqj_(t^)5sUvN1cpWR*IL;$g>$jMvi~T7RNf@tX%e!YlZr2I zi1=n;h?14NBcfyOyzzpg+q}#c@70sO_!?)_5T(!iQEJ<#g~#32A@;HGyeCj=$PJtm zfXIab56(SgOwQ{{@)tw0f|N&Os9Tm~Fz4l!SKm1c8Bx1&)Gn>gK!2c$`Sh(WKJAK# zdre__y?&NyQF-Sj^H@exHz!{FV> z0XJ!bH7d}3APM4saoZOdzA?JJ10R`M zEs12#IQEZkM6t}gk>X`8i87&}gWYNZawZNT&&qEAIL*Da+LNkz{PE}hg8d0HP$E?= zfH_7)OFM`^92pm`&fWsb3BW>~!Um`Ncv_FaKIXY*_-f_BR-iWbn0Pq83KkZ_X^pI0 zy%u`XVa0|gI_8@Bwu*s>G91`%z95hgFpJhQ$~>1(>@6;Vq`*V_nC1Ed*&3HY-gjQ# z8A$~A|N7ag?8SLAS7m&F$_K0XiqKMS-3h`$P^LGj>c63aUzztNGwyzmvStC+H4?l{ zRo4h~yBSr&1LPwTn3%(`>^mfqf$R#)5^<1sM^9RT+I_`mTLz+eUz(wu>VSC`q#pYV zn1gyos5^tI(2?Ib^+40m$9~NWSBK&8LUxLXQkeHfN=w4j+r)uMVB3dl(!&w<_rAV^>Z00i25^$dLA9o}l<00tn- zt7kK_YF7mQ5Jy!?m&r}^5IhT7*DPU5E+a=k@Dn+=m09f0q_3_p%vLkUadJXS#i`IVuk{4clE3{|SEf+qZ z^cUchW@l0nO;4+4ggN6iKQ;26WKVhG>ISdJKMiZ(9brFZvo%#$w>@Oj(e*_%^$k$E zklZTUlP80?avaD_^x)GgDAQxGoWb<#w3c2c^bvHh86MN>p_6?kshN|ftc3?CkL0-M z#cE9#0CoIhz|nf8!W(a_C~6R^QPkhH+I`X0jXO*9=?}}xMcMe(*%f?>JdMx6+f!lh z`vA!d`0!$Ry18qUS_xW02#NNmO+LXXAzZ**rOM>SzP0A}-=5$5?k~_-99Iq*7m!?w zE<{H7JIb>W4uh0iG|XBE4T9eqnw(c{OgTmJ?x7l*`Xgrg=DD;-wrAGIq=z_zhW=t? zt0nr3v;K|&4JeC$wj(6y2kMjAfQrOpRp3Ku#qt}cJ_fB8p%m>M7S8v%gk7hl>UkZ5 z0aToJ6Bh@MMA>;6fVGlU0JtgS+N3C|f#39k2>wng>+5?0eZG*9gtPKC7~+d|Nrnw& zXF$m9I))UOz4wiRjJu1~mydP5PjUNkLnJ_rtRr6Cu3vD17pFcdE#fJC#`@O0oi zQ)HEpCm5;;)b;iX*6K8?SnN3z3Q!!EKrvj8WAJ9EwUmZo2}WqH!zB#h+S#I;>*Aa{ z+D#_DI%7x%o)hys!58Bv{{SPJFmHV>u9ia%7n?dq&;r*6eH~ou)$4oPQyn5iGZqgZ zc@~@yMz5#qG(IlA#fPx(X53a_C*W&H!J1m z24_7Owy7vLZ{{+5tVGk>Y+S$-aDU^uBEfo=dKNHLF=}zYc(o$3q!K+Lr~aJ;7?@(6 z9^9m`f$(N^yUEX)eB~Hndx5Mw>84jgOgv2+o_zLYLqmbi**9OmZU(>ZTcdC2k%b&8 zuN$+yZH#XbKu?>Iz~wuKxLebCR41iMH(IYurCXY^kKR^lYWa0A}$ z;sJ+b@Rh_O-aHc?>06~;JVo5jFR)!a(eaDP*d8$6X%%0o=@2>E&y7h>)auFiX;4xP zkN)8u|j(jUA)3r&iyex z**v2(RYxsZFcSS$N2Gcl1aTXMDdcs?~&|kb7tHURqFZX?y)kI6(i3NXX-V(aNJ6 z-!IXm2;fOE{Mw`aO~Cyqt47DYW31es)hD$+% za6PJQ@jSc6V%Sd2%}7RCw^SGGF6^9&Kjwhw>{A%9WU%8vAYVqL2$~%vAm{=wW;A85 zAkm2hM+T1xfD;tSa|6_=fx}wp9`6OFNg9#cKEE>*+<3> zofObG8KHJkfGsIx$jXYO-qdd)mU6XB5{%DH<<+(@A~$D+93A{_XKzG(#JJ!Eyz6Mj z*#gbJ2SR(E^#?jBkBT3jG3oZ6&>lDi1XYZmPRl)xurkx<98XhWN!{EMO@B!wM|tLx z;M03|+CU%)6$u8FSedD6sUe`ELy=A3h2Bma9-3H6@TSle2fRm=e%Y}5{tTcCq-^it zBVsDGy5yNk37#1cGr$C6>lq;|#~a3F`-yV(VrxSX=aRey@!p^11fq{}zwr5R7-#xt*9!tPa$3dl!e7!i+__)CBDbF8JG);0TB^cy zJ~ZO&$D}zKp+ct+d>Yyg9g}xlQCR1aFWRdn?0%N#{+IK$aNds1q<9ZYl#d1V znz|OQ=+y2m)foeF#J#>Ea}Tyr4JpZ^HQh2%4|=`+V}x{v5(f7kK@;-Op8uPEf&FDo z{C^!WhM0{m5tHyZm!Ic;mILwGMnP zbOk)t#B<()I$IKyRzdZ#zrK;=lt%0QE0L#4DSYlqwl#Kk3(!DW; zyQbl`Jv%2QH8PSVr{yC*r9<{{on7Fr@hJ4)H9v)cn>1$rrS}Q*PN;PY>NB2IiKOO1 z;-Y@#vE7ZEX)%TgfBaTa^=f(xtC&9epj!r-$rV5Ekh|uI-y3#}G0a+o3zo6OHlstR zjxUwN#TUh!;>!3}d79Q`B!0Z{+7;D1_^znFHjB#p!-Ug^(vlS*%RH2BS?6$BbSEW2 zEJYjB`tAMe?i;&$P_*l~?~eIT%_c4q0t`#}_0d&G;Ncww|sY@ zg$#G}%J`9|J8?Ki7w2VUC=y#rC>71IPP5=OBs|6HVC}dowrJHl*v?3t{Usa|L?I<1 zytDL~VO#E~n~S;T)S1%Ujnv|G{u~muojz035jTLQl&@LK}ECGcAUza{Wn0{>SMcvmv@e&0^b<$mUN$@&R_ y|Eqa_&+}UXza{Wn0>35jTLQl&@c%1;YsWEN?j}e~`L~__2~pF#S*&vV;r|1rzW77{ literal 0 HcmV?d00001 diff --git a/lottie/test/golden/Mobilo/A_0_5.png b/lottie/test/golden/Mobilo/A_0_5.png new file mode 100644 index 0000000000000000000000000000000000000000..d3718b149345f11727a18ea7049c3e35518d25fb GIT binary patch literal 25224 zcmeI5XH=8f*7%vh5y!@5>>}VqqzH&eQvstRh)9zr(iwq4S`g`kP-Fz8O0R-S?+PYB zfCLM@M3f>W1gTPzKmvh~!kZ__-20#T^#Am(ciolegHK4#IeYKlE@z)7S<9z)473mI zJ-L^UkMDraElp!SzMt*+_yqRs+0A;VVQ707>-K}UvG#9#)%~XyS%2*E{!Pbp59q2O0u38 z&-Iq5qceuHl^0eR%pKaOH>xiP(*!(v;9WcdJOVrdJOVrdJOVrdJOVrdJOcmy1WL6P zCfNP|*1o$M^yt*I=gB_eTH478sc`%-x~A|c_@+`J~Cp7OKYwm@oi_ zKKD87C)U07!sSP7u)gj} zxe^Ige^vXM;+(I(?+oxRJ0%zAymb6@Vgj99^Y2}BpwPed1K+#0rhj4Ub>Y1pbxyJ) z4UQm6jP8^zbkBa!{iF9vXh5<@IN}%zB#j<#6+vghRi6*HGP3V?(=Q+DMobTjW5%W& zjhHr@>!TThx)%U#5!u@R`Vr9f!rWMQz3OmqnlBDPd*D2hYmT@&lzz?-vKlEVDgWT3 zQdRM}@fbJNvEVdur?n?#^_a`Gb1#7<0xXp{2A?)T&Z88x6db&j(?E4r84uh}H991Z zCm_(nA5@#fuQ9ZimQ9>DXg%iN3q8 zR`~h6OZ2#>9`aMz#({cNIp{4%0Ax9r5>7KH5`7%@NuBl>qi^kj%SVYF8?;5S8 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 literal 0 HcmV?d00001 diff --git a/lottie/test/golden/Mobilo/B_0_5.png b/lottie/test/golden/Mobilo/B_0_5.png new file mode 100644 index 0000000000000000000000000000000000000000..276acdce82b495b41d06a0e501ddf15d02ed757e GIT binary patch literal 23031 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 literal 0 HcmV?d00001 diff --git a/lottie/test/golden/lottiefiles/atm_link_1_0.png b/lottie/test/golden/lottiefiles/atm_link_1_0.png new file mode 100644 index 0000000000000000000000000000000000000000..87dcf30d783c802c1ecec158a993bf16dbac50b8 GIT binary patch literal 156589 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 Q;lBWpQ+rY@^DN;10sIC1{r~^~ literal 0 HcmV?d00001 diff --git a/lottie/test/golden_test.dart b/lottie/test/golden_test.dart new file mode 100644 index 0000000..ad50680 --- /dev/null +++ b/lottie/test/golden_test.dart @@ -0,0 +1,37 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lottie/lottie.dart'; +import 'package:path/path.dart' as p; +import 'utils.dart'; + +void main() { + var root = 'example/assets'; + for (var asset + in Directory(root) + .listSync(recursive: true) + .whereType() + .where( + (f) => const ['.json', '.zip'].contains(p.extension(f.path)), + )) { + testWidgets('Goldens ${asset.path}', (tester) async { + var size = const Size(500, 400); + tester.view.physicalSize = size; + tester.view.devicePixelRatio = 1.0; + var composition = (await tester.runAsync( + () => FileLottie(asset).load(), + ))!; + + await tester.pumpWidget(FilmStrip(composition, size: size)); + + var folder = p.relative(asset.path, from: root); + var fileName = '${p.basenameWithoutExtension(asset.path)}.png' + .toLowerCase(); + await expectLater( + find.byType(FilmStrip), + matchesGoldenFile(p.join('goldens/all', p.dirname(folder), fileName)), + ); + }); + } +} diff --git a/lottie/test/goldens/all/14595-thumbs-up.png b/lottie/test/goldens/all/14595-thumbs-up.png new file mode 100644 index 0000000000000000000000000000000000000000..133e2a025b23a917be504ad6004bccd3f9ab0a29 GIT binary patch literal 25667 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 RQ5%5(KFF)f)yi0e{|`e+tResa literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/17297-fireworks.png b/lottie/test/goldens/all/17297-fireworks.png new file mode 100644 index 0000000000000000000000000000000000000000..f1be459041ded2df4f65b2fc3fc28058f15ad497 GIT binary patch literal 39730 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ºuRX{ax$yBSPpKp15N_|BSD%E5vRnURe(yfT)BgM5 z499y(ljMc~^f1uuiwr65sb~DNwM8`S4{<%%2aIQVB23_}voQ(G=Ncxa}7vl8rN-2fbj(iV~ zFMP7yavlU1sEsX|Oc<^=h)KkUlnexYaOxLc{>(hW@fNm$*!181F;N zTOZ%XYlzsv2%$5z5ZAY^3*l?1rnZ?RkQeFZOJMhW!_*#Y%}QRnQUh5XslVrhXly68 z`$^$Y1DNJB(*)KT23%C>uh85~%t6Uor9Ew?^4#Tw$(AjMY|G~0A=MF_+scxRD9`%B z4eLKs*M0WvelV=O6)(v9G&x9M10*YT##C=V}2#Gj}E_~*-c0F@%QD9>-_(G<&Z~OZUC1-f*Mo9 zYA%D8vq?&|5ZmoV_QkNJS?vIV)PLWmwhd6-=Y_mE6P4# zF9mXN;EDXTO(0fYh3LhKV}fFYfYuSWEZH^1nmdwd49``7pTSA(wb!+8rIv;gpp9o2RS_co$M-M&#AR`r24!2lA1vtM_6_piu zZoYDf)o?wC5{LO26DHX5MMXd>s~l|41*=7amOBzQI-o}=y=ql5Gxm=kRrTLaG{K1P z3qj#JEhD3^8vNBx`5q+&J?`kc*#=b<%G)MaGL-sjPQ`S1$Gq6)$)uBE?x&1KDytZ2 z8Y{y0AJYnVJ&?nQTEdW#n-ltnEvt<NU+i1h0%NSE<4d*= zq{8iV{xzs^Rs2q_q_RT{_cGiS+G>z7yI)fPd%rBtZXSxx%_Ds3P;fk3%1`416qQK) zh4rv5JTZk?{4s!b_9H2n0>yZJ(4~FPg5!2~r-Ph9g_jlt6GFr? z@v9+Vu+mK~coq2Zd>&y%T1RR=1J)~&*c7QODdESd<+9&6SaDzBXYq>WJL=GjmxT~7 zJf2o~VxxKd%j=qxTnKN1)_8nugWFsv`E413vxSJ2#%_8h=9#!iKU&&ZOr)M^G!LG+0`xdhA zvx8#1f+@_dmxZn~`D8l=LCSbvV;{+x<&T5>KLRGAQ?pj)(2O-|b%x)tsPXyB*6gr8 z%x0`?rwmArvfFdo8U1`eO$GwFWF-2 zA_uzB`1<;KuX0}&JC2O;EH-`N!0|xx)$Ir{fhDXd;b>+EHIfNRgs_3%4j&86 zm+|lJGIL{e6ItcA4k+LZt|#mM_T?QMGwkVM>inMb7u(Z!=3jTtt=(>j?kA^4z~$6a z-}^tk5RQDg=wErhQPEmm4CaJB9@8zRoCRbEpq|`=4Sa=vJ!3rTZYdn#Y85$yZ2^_0 zuO06m+&F;etooK@JyvHTt2Ew_?B?w^B z|AL6?^ljn`m@J<+39q5Kbj)L^8hgw`N_HWHgv0P85a{tPYaT3*ol0O~R*AP2XkmLx zCe}5o8^D~=CW2n_io20GR72BgeO@0>K#ffb%H0=LoE5WmHZ#e*UcbE7NIIQ

*%c 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/i.png b/lottie/test/goldens/all/Mobilo/i.png new file mode 100644 index 0000000000000000000000000000000000000000..3647331728ed6004b84748c6913edbf0e6ac5d22 GIT binary patch literal 8558 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/j.png b/lottie/test/goldens/all/Mobilo/j.png new file mode 100644 index 0000000000000000000000000000000000000000..6b30c04d52bf194fe30877eeb355d3d0234a597e GIT binary patch literal 25644 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 V*L)}u`i~#L>sRWK(wD~m{|8b8BM$%o literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/k.png b/lottie/test/goldens/all/Mobilo/k.png new file mode 100644 index 0000000000000000000000000000000000000000..b2a45f4d6d7c4d634f09f57364f3f60ec6566b1a GIT binary patch literal 20321 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/m.png b/lottie/test/goldens/all/Mobilo/m.png new file mode 100644 index 0000000000000000000000000000000000000000..2c3b44e8d90024483975cd0be5681a7d0d9cfa13 GIT binary patch literal 19291 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 R%>GmVjf$pn^-HVB{|o-+hMfQa literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/o.png b/lottie/test/goldens/all/Mobilo/o.png new file mode 100644 index 0000000000000000000000000000000000000000..76f1958585bd9b31fa6b8f96b6c1eba5a53f4a8d GIT binary patch literal 23361 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/q.png b/lottie/test/goldens/all/Mobilo/q.png new file mode 100644 index 0000000000000000000000000000000000000000..bd359bb6d1e1607dc98ee65510a863361162c72e GIT binary patch literal 18895 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

+~ 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/t.png b/lottie/test/goldens/all/Mobilo/t.png new file mode 100644 index 0000000000000000000000000000000000000000..74e41517f6d02809e5bcc823f32d19e81839e5d7 GIT binary patch literal 12733 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 F{{Z>bHARuso3rI`o5Nbj%(mSXK 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/v.png b/lottie/test/goldens/all/Mobilo/v.png new file mode 100644 index 0000000000000000000000000000000000000000..f73360b698893a7e6d9d93b92d3b545882547f9a GIT binary patch literal 14267 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/y.png b/lottie/test/goldens/all/Mobilo/y.png new file mode 100644 index 0000000000000000000000000000000000000000..b32ebf8f01c045cc5ba7c2c4b288215549384e2f GIT binary patch literal 21006 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 F{sY_Ppi}?= literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/z.png b/lottie/test/goldens/all/Mobilo/z.png new file mode 100644 index 0000000000000000000000000000000000000000..c2da09c0fa6cf0d8aadfdef5f6084e3b1893134b GIT binary patch literal 22076 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/ telegramalphacompat.png b/lottie/test/goldens/all/Tests/ telegramalphacompat.png new file mode 100644 index 0000000000000000000000000000000000000000..616d81dfe6ea0a70765c8041b58b9f6d9d248d36 GIT binary patch literal 1488 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3Zfwjuh#WAE}&fBXSdyg0hupDev3VtzN(!QzswTj?ctp>eb*~RHVZA5?u z@3k|F&#sxi_x$DZ|HtI2Hy)3Bvr)YI&$Ys<#~BXPvdA(pjSx&kU=gdN!F@DPAqj`r u5FggssTT-G@yGywoRZ;^Qb literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/1669133489622.png b/lottie/test/goldens/all/Tests/1669133489622.png new file mode 100644 index 0000000000000000000000000000000000000000..cf809d84124032b7bfaa0b5603ebbd0fbb5e4b86 GIT binary patch literal 2788 zcmchZc~BEs0>)nq22=vO!F(3pHWf2un$boVs3@U>{I6^>>gh*6I zS>k;`ARa4$4o5)c2qHmL$_0e2Ob9E6;2?u(ASe)!C}AJ$f0qAj?eVI*y56g<20v

%q1&uvA`2-hHN8i~xFS|%K2h;OAoG>z+R9QSAo*?lKQ zDnp&CvoSO8PF1($qGQ#XdfNv~jGS!!27n{u*JcBX(t) zhjF%j)^v@@tk#R7g2H9xp1-Bq$>QT0(OO!K^=uzWl-t*a(Ou z00g{XZ2`M)yRlu53!v&K9pgN5?V&;Ks#1orK#y}An^Ivs9)Bs{cBOT|U4{Q-@BgQ% zay?Q`*A%$}V6&4OtvH@N4@ba3*!~dQ=f;*|(^up<`+}o;xMk_l5NqF!+DupZ6jFoK ztB5ZdkQQ*I+7)3pl|K0~F>!O&lUwQh%8-xGlPz<6An_I`KCNL&*T#@HyQP&bX66fj znUFHeQeXv?z2Tu^hnwayy(5@Z3MDw%L1R;)2A=BSg!)ujB8oG)KSLO zd5um5|3$#t%lmL#(vV8|i5qVqOWkWL6rNh8xP?e=c2Eu1-!Ua9FokD&qy`aMrayJJ zxO_LcwC8b2yiQk#m`B8|bwNCCTqGFIM(b7h`a_cFa%7kKgNit`j!WptZNE^vV?lP2 z>3K3%*=66^5nmwjLI|R3mI6x6%FeZc(Bm*py~$XhY)V9IAqHhkTi)kD0eL^mH`dmgM)ittK6%i=is7?Xow{nz;fr( zr8FYnz-kOX`dT*|UySX(FpxAos=~{MkeWGG4(HG=c=E~;bG7M?-i9TdKLW6nnojF+ zKp^ZN^8RGMDSq68ipU1sL3d%Yu_y|3FI7K5J0RQcZE9aARz`I}UQz{H@-B^8%1@o~X(?0GhLHHE zy@XQ~XQjmKBOVw#q9Tg@jdkc*se1?sIV&XyzGi4WnmL}`yYa(P)UJpCmvt3l&nLkp z=12ub5KQfuxU8d zi(6vK*V`Cm4>xJ$G49+;?sC5RGI~-kx_mpWW1q{_*?MSOPi>Rb9JLv^W}^}*q5A;} zJ+m6Il@j`1&Z#CY?v=0wzO=P4$&#BU4Gd0=eJ2KV#b%4vV*o1(k*V+NZGeqVDm_P? zLYR_vw;jHmJR2YmAM{S7BM+5p+ZLe&O0 zY|sLbkPvng4+Ocga>fyge`neo;QQBf&QA@#Y0awy!f_IVgzf%LJ%AR#o~g-uq43aR zKJm=|YAW|sGa0Z>Fd$(MvIQ|8m@h|aW6;cGvZZ{hI$!++dYXe=MF`MCA?*ivTtyU< z+KOgN-TSUn8M0j}V!|-OC?dG-ZMgSpV3uZ_bk;PTFNs)pWAqAoCN3$AF0s-T7yv7m zjx`P7E28%C?mgo=TtKG}yJ<1sY^mVF85+EK%?a2lJCG1=_b96$T97L9*-L<#47K~%xq|F3U%fw?4p*I35_Yue_rQqAGIc|Gc$tQp6dcw9W-VM zyKwA1Ir@w!*cirrx4!X1t?6%*vZGY)ZN(4T%A5x-B%~sctc;<@_l92gK_2emMG}Ty zq^b+>E+2x7hNb-3CusDh`~1QPW1;)@-psEI{&U^Z{K}Xa#*3-KK(~EN#^(4K_j8Sl z8fPzHh&GQW0y>?k6^zXF+IOY&njM=47K33CI)Gl(i|!)xKP99UQ>nXq%RKW8u4mPW z_M@;_mDkW|)P%b-1b$hhZvEFMxqiS;dLDWXcex%c0Lt5w=Dfw~K>C(V5c2SO72E2O zE%I=eY8NXbe%f z@ewMC_ADq@-0Ld-dhnO0+DI>5qAc*}^VVJrZeoV92LEQLvb@o9V+cq9)^7$GJa%sD yi#F*;^iD46OGubiF>U@mU}1+3{9Cz55SX3VZ4Q1^$)lmU0Qva@Y%lj_W&IQXFnaI+ literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/2frameanimation.png b/lottie/test/goldens/all/Tests/2frameanimation.png new file mode 100644 index 0000000000000000000000000000000000000000..2baeababbaa01959530ecdf41d6e00dc91104183 GIT binary patch literal 1924 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3ZfnCqj#WAE}&fB}YyJbsdjy)_t6xP(W{hnV=PRkX}f11~nk}@B%Dn%Ss zh`4oIBSJqG;-`DXq6?(@df+036e?SFKb&v-W{&?19; z&q=XGCblV03q05P^fNTn7Jj(?-TSchwZ7%-3GW#HnlVh|Dd zV!P2>?zZag-rCr?|8_DIOkTk3!05={z=Wcz#KLv=lZm{0YB&7bW%jq2@trNY5{n<= z^BGrc@_y(4>C2bCsru8NR8+D2_P)^g`9-IS`(@>@IFC=yzHoe-9{r9Xz~KVpf(DpH za$U>`lgm!ldg}STkNBD8xo@sqp^zhc!fLtu4{melt5()l9r3(VgyAFx4TTqIMj^Y| z!ef$ZLBU=Yj!?%q6!}`DTp8WdKF;yQJG(ca!?^OM%dGhH?S%#d+Se)2= z`D^y1@a67nYRqgIc6?`%^}9If&$K5~U&%MlvFYN z_Px+poW4`CBwsn;sBSruGGGWardBa9%t@JkXZn*zz+hWH?aA$zg21R8XmDUo>Z?P* zC|5b}8~b0rW`~NrKQKN0f0gjzR=-+h<%eJDKb4#K4#@4oOj0vyH2Q2ec*}Wx`UCV) z|FkC=RV)Xlaafgq`Tz`(3f(5Y0`Bd1kP-kWMr=gbS<6oT^^BWyZ{w$vlVtq*8$LT- zSa_IOx<>k8FNf6}No-mQ+{#V{d#>|+AF*?nio8$%gLj-(2X0mxoLu@+Q2V_f|AUep zPmvQlFpeH9v|#u#JN8q`r0vVg*X-G<^8W5SW}pkUS0yy(EAOda&X1u5Z!(+lC;Hue z)txpKe<#=20<+h@{*4RtPp8~Hg>Aik%opUXO@geCxD Cdo61K literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/2parentsmatte.png b/lottie/test/goldens/all/Tests/2parentsmatte.png new file mode 100644 index 0000000000000000000000000000000000000000..bafb09bf5d6f45bb369c01ccef7f21b57cc31136 GIT binary patch literal 3356 zcmcguYg7|w8V+KE2f@@mMWRBY%_#2S8c@JO!UmBfMTw>aCfqF$mjR{FmQc5Y& z$VA0@NwQkXs#T;}i?|@T9Eh{r!cqm~5-4K{8o>_X5+bk@nUTOB|2gO6Jg0hnTlZ=sySPZ3fp!mX(S6M^iFkZh&rL2o=gH|_I5X^}@Dt8%D%3|S4FFTAjXYYZAK1r69vOInZdjv@ zYkWcHaHL)oK33S*lGj0jn$@~zE>@G%HAPxEIT<7EZE+7?fz?%TmJFTB>nN`wXE2NE z#3fExzxE8I4heRry3+V-p~Aw9n0p5&mmuEw;b3uswtZ@=14W9V$H9l^q~X7|oR>NxFx5nBfiTTI$^d^2!`M1M(t(w$rkL6Np3^b!R`KeR7z41|ekvbw#RA=tT z$1aND@CoVCTZ|ig^n^nr$H+!y61CFl?a0Jw`K`F$#|hc2DSxPX26u_qDaj%FYoO?^Ea~KrP_oehnM zT*c6Q(H_PxhOR z0wrw3XyC1%kse=gbZW!56(P>OW5f0&jN5Z5tHKW_0K6i4jk3{Qtvj$0!^g$+jxxoL z7!8NA8R_q*I^Vujk@Y$PJA9gMAR9-fK9bm7!&K(JX1jz5^5kW7D2jz9g1PD>;b1-d28@Mx{EHBlRT$%@^7 z)OblI5rgf$P)u%o84Y6eraHs&F^kw*!0_0@@X5t1mg8f$jU;KP`VpJ1>y#jePY9RG zQDG>wqWb~?`3S`y4{x|NPFu10FntDhJ8z(3G``ZrfLg2&y4T`8l4-3!ZzAM^v9r^N z*OD}3o)zNH3HH8a25yMB2K_p0A)Qh6K@eJ zaQZp6m#6uccwmUonWBQtwKJF?-fb;2j-vD)ix-UIUA z?P6h29aB}$QEWou!9FnfsDKiIB!Ibq&dv1O8R2^K6W6z#U&%Rm3LefAGQo7(($PPJ z0bme~F9u|F;_S5P)o6NYiUV{V$zNv(#IDfGykLfTSHoNBK__Qo>cig#8><7w<^Qq8 zX@Z@T*FlCl_euZg8~U$-7mf4#@05U|KBpEs$d(HQLZQjb+KxD!a3E%iy-$O@8hpVj(Mpz)U|;Fm7fv@8tKC_$2qdBI})P<-!kA8w7; z%FE8eIaWOC%Q&{w*kaA@{l&GaieNM0HjevEGBp*w$ioIfiKG}|hAO{W#&3ns4Zn9k%C1>B(kCH5w+>M`w-46YG=KlduXRp@) literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/adrock.png b/lottie/test/goldens/all/Tests/adrock.png new file mode 100644 index 0000000000000000000000000000000000000000..3a4b1fe3177f9dc8ec5e87239657f667962e2b03 GIT binary patch literal 36003 zcmc$_WmH>T)GbU~3KX~E?mV~@mm-DY1=`~7-ayb`#XYzdD^`lT6=<>GTAbhxAvgs6 zLf`S;@6Y{z86zWuBxj$q*V=2Xx#pfb@`Jh}4kiUA3JMC2(tCL=6qIM@$X7fD8uAm} zy2L)@+cP&UMOl=}QK~)UKd5f9N*^(hf4&%&5hy5hC`$4&AHBXEw%f&9&bzN%wYdbe zxHMdKXpEVn45Ls4q10qBGzTTKWnwY$S+X+;P(9Eo&P7!-P+M@ zN6%5oE2=;A2-=Rz#m=x*7wSv*jR^eH*@qL>fKwOREl^CRq*Pi!T4!>5x3vE;h_ znfY!bi5)5nz-E)t!A=RK!+JYlD|L|1hQcFMEq`4ep8tU@?iurLRDLZ@D@tT}sH3v%Cx;}tcV8+%;(~8-`LA>#m z5ZF6z*CS-7_UeXhl^xG0pNuj&k0VT-qxSvYLmf@uToOMv)f96DB$@hF4^J`w0~KFi z9Zlf+`9uN>vzk>4t?;|Wb?v$&!vP!id6LvhnL3>2# z4EPU2^w9PCJX9k-pjb`*Wj-xqQe`(dCwt3>FFZdQreQDCL!%Xh|6!Dpm?2vgx>}yW zOt;;zPqm7QQ$#5_FcxZ#OUD^clZi%+2c!lX zec;?JoT8Y%h|s~*_GQ!AZlYN+>xD~1gOOGX3)Gj>!KOx<@sssM!Wov%*jeeM;PWrv zB#UczE3=1C3YRXEtuR?Q&@$>3lm)JPTZX=Q)uISUI_(J*`fDh~nKaq=#vcXA>5BR+@yb_Cfw|mo^JDA;lU8Jk=HrmZ?%_-HT zGi=tG;2nXw*ibK4Thh9|1GscKAbVzCQt+9Ut;jrK(yVlB(tklLE%AfLK7JSJQrWWk zUi$x5n#MQ|^RC>MJ-tdvlA~nZFf^#+y6;iZZR=U3Lp+zLZ6;luMWLV_=db8bIbEa4 zdZ1&LRem%>AZMEWf@#6$#=&-YryGWt>k|y;a@jvw` z|2qn^d%%i?yV0ud^C}-&l-s<&UdUC;|0BN5eD@sHi0JgU#p~dtNt|Dj&WYw#xW9ec zyFpi13gaIA4>^KDcs5 zHNN}PSS=W2j>8Mly=8Zg?YGiwp{+{^J0>v_u&i zZ}xC^JrgaZmsdR$wv)c8>)4qIS-rR-Y4-Le90T*#3(Akj{hjG%{WB?O%tm^Be#j)S z2W!CqeEWM%@Vx7TmP?=DA_2IaWW~f}<8xgx#TL~w9<}7ldPN?5_eog(Q&d~d%8?Gr z(f)Tqhl1Vp*(X~)RhTZ#S_ka{nXC49Zl#R&@ z28U@}gx1%1;)V|w^#O$bu1B1-IipE+BOPN76kZ)Yji_PtY}@X&b~sI`W;4ngX^b5m zt-r6Paf9=Z5gB&=rp2<$^NTd?OUX&jcnxoh$;2e_jC5#jKC~E>Su83g8dS^uRY{YU znVPa|e2%FX-aCy()GJ836GchWI*whw-s@D==G)kFryQ(IADV2ck2XIPkUGM

#rZo}JDoCm8x$|b!|YeO;Y1JWvb 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 N002ovPDHLkV1l}1Vg~>K literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/adrock_converted.png b/lottie/test/goldens/all/Tests/adrock_converted.png new file mode 100644 index 0000000000000000000000000000000000000000..3a4b1fe3177f9dc8ec5e87239657f667962e2b03 GIT binary patch literal 36003 zcmc$_WmH>T)GbU~3KX~E?mV~@mm-DY1=`~7-ayb`#XYzdD^`lT6=<>GTAbhxAvgs6 zLf`S;@6Y{z86zWuBxj$q*V=2Xx#pfb@`Jh}4kiUA3JMC2(tCL=6qIM@$X7fD8uAm} zy2L)@+cP&UMOl=}QK~)UKd5f9N*^(hf4&%&5hy5hC`$4&AHBXEw%f&9&bzN%wYdbe zxHMdKXpEVn45Ls4q10qBGzTTKWnwY$S+X+;P(9Eo&P7!-P+M@ zN6%5oE2=;A2-=Rz#m=x*7wSv*jR^eH*@qL>fKwOREl^CRq*Pi!T4!>5x3vE;h_ znfY!bi5)5nz-E)t!A=RK!+JYlD|L|1hQcFMEq`4ep8tU@?iurLRDLZ@D@tT}sH3v%Cx;}tcV8+%;(~8-`LA>#m z5ZF6z*CS-7_UeXhl^xG0pNuj&k0VT-qxSvYLmf@uToOMv)f96DB$@hF4^J`w0~KFi z9Zlf+`9uN>vzk>4t?;|Wb?v$&!vP!id6LvhnL3>2# z4EPU2^w9PCJX9k-pjb`*Wj-xqQe`(dCwt3>FFZdQreQDCL!%Xh|6!Dpm?2vgx>}yW zOt;;zPqm7QQ$#5_FcxZ#OUD^clZi%+2c!lX zec;?JoT8Y%h|s~*_GQ!AZlYN+>xD~1gOOGX3)Gj>!KOx<@sssM!Wov%*jeeM;PWrv zB#UczE3=1C3YRXEtuR?Q&@$>3lm)JPTZX=Q)uISUI_(J*`fDh~nKaq=#vcXA>5BR+@yb_Cfw|mo^JDA;lU8Jk=HrmZ?%_-HT zGi=tG;2nXw*ibK4Thh9|1GscKAbVzCQt+9Ut;jrK(yVlB(tklLE%AfLK7JSJQrWWk zUi$x5n#MQ|^RC>MJ-tdvlA~nZFf^#+y6;iZZR=U3Lp+zLZ6;luMWLV_=db8bIbEa4 zdZ1&LRem%>AZMEWf@#6$#=&-YryGWt>k|y;a@jvw` z|2qn^d%%i?yV0ud^C}-&l-s<&UdUC;|0BN5eD@sHi0JgU#p~dtNt|Dj&WYw#xW9ec zyFpi13gaIA4>^KDcs5 zHNN}PSS=W2j>8Mly=8Zg?YGiwp{+{^J0>v_u&i zZ}xC^JrgaZmsdR$wv)c8>)4qIS-rR-Y4-Le90T*#3(Akj{hjG%{WB?O%tm^Be#j)S z2W!CqeEWM%@Vx7TmP?=DA_2IaWW~f}<8xgx#TL~w9<}7ldPN?5_eog(Q&d~d%8?Gr z(f)Tqhl1Vp*(X~)RhTZ#S_ka{nXC49Zl#R&@ z28U@}gx1%1;)V|w^#O$bu1B1-IipE+BOPN76kZ)Yji_PtY}@X&b~sI`W;4ngX^b5m zt-r6Paf9=Z5gB&=rp2<$^NTd?OUX&jcnxoh$;2e_jC5#jKC~E>Su83g8dS^uRY{YU znVPa|e2%FX-aCy()GJ836GchWI*whw-s@D==G)kFryQ(IADV2ck2XIPkUGM

#rZo}JDoCm8x$|b!|YeO;Y1JWvb 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 N002ovPDHLkV1l}1Vg~>K literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/airbnb.png b/lottie/test/goldens/all/Tests/airbnb.png new file mode 100644 index 0000000000000000000000000000000000000000..6bf9ac9619286cbb572c249f23df0ec43b460a8d GIT binary patch literal 59767 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 B))fE% literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/airbnb400.png b/lottie/test/goldens/all/Tests/airbnb400.png new file mode 100644 index 0000000000000000000000000000000000000000..2378fbd021d92168f6cf81790dc030fd0ef836cd GIT binary patch literal 89038 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/airbnb800.png b/lottie/test/goldens/all/Tests/airbnb800.png new file mode 100644 index 0000000000000000000000000000000000000000..405f7a3a76bb44062509225a50dc1aa04888e01b GIT binary patch literal 103432 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 NlNMJHs}(T_`hVi#XK(-j literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/anim_jpg.png b/lottie/test/goldens/all/Tests/anim_jpg.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd4ac5ab83b2db5710a6ed796ebd8ccf63f038f GIT binary patch literal 201349 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

p(2lSP;}ZM_o)pY1TD+A1k8&YPXD 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%0Dq% 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 TFB4|R00000NkvXXu0mjf-lZaG literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/animatedshadow.png b/lottie/test/goldens/all/Tests/animatedshadow.png new file mode 100644 index 0000000000000000000000000000000000000000..b069fcd0aa97aea5f3591e24ba9db30b5dd41e91 GIT binary patch literal 51042 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 A_W%F@ literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/august_view_pulse.png b/lottie/test/goldens/all/Tests/august_view_pulse.png new file mode 100644 index 0000000000000000000000000000000000000000..40c1ffc2691c33f8df717e560ddc4e0f3474dd4a GIT binary patch literal 3814 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 Hm%slPo=wI1 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/autoorient.png b/lottie/test/goldens/all/Tests/autoorient.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df3cc8956f1f33f2608e76326760bd15806e9c GIT binary patch literal 5369 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/bm.png b/lottie/test/goldens/all/Tests/bm.png new file mode 100644 index 0000000000000000000000000000000000000000..b809fedd9531d6845132942c507bc7c9e05e158d GIT binary patch literal 24491 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/bm_converted.png b/lottie/test/goldens/all/Tests/bm_converted.png new file mode 100644 index 0000000000000000000000000000000000000000..b809fedd9531d6845132942c507bc7c9e05e158d GIT binary patch literal 24491 zcmeFZ_fwN?)HMn!2+~FAMFl~m6FLbfC`FoxG--wwYUq$qRWOK@NCyK!K|rK~^iF_K zgY;fQ=)HHoJm1WF{(c+Hh zDz8!C_GMr0pDnab+#n9;Jg{Vt_*yxZEVkpzgHI%2c19PNGl$L1pkm5~_8pdh>QTy# z^$*PtzHxlJRr-vSK9;^KZ+h6#Gc`5GU;gbd{AvY_Ue%~A%bUJGI(xjH#XJd`9?n@e zTE5WvL;m7_{k6!9s&>Gt70C^Lre|P?iNk}dueF$!iR0FZ_ROYw@aWMaeqBoQMdoKo zooTC&zFbt^Z@&8&IM^o3x2?te%!1?1t^6naQ6v~0lIC%@A1p&?0F#MmDG}bSSn(e^CLa1 z97`3oKLdkQLM_-qkJH6V4(~qFu5Xp6O&xMiO#R2M9fPb2dx{j^aZX;?Do*KSW!@vR zOJ$$7sL?_T(JEkgukU$@y}9b}=Id6N;vxy4R%qeXosc|t;rP&|HPcniW#HYEpsc&Z$at zh7w?N5}XWvYVK(Ng>iQp*pmP z>-@WJ*=Q;=UsCRB%2I>LH#Y~?DXq;hpY>dnC#swEFT<8-deOMyca9=AatCp;qp@3b zh(nGNagq^~P$leKut<2WSW0U*xq$Go_#=U@&wrW+=*k!%Xn*?$ZTkB3^E2mol?nu1 zb(mnoJOj*m~ ziNW!cbC=X2vhF{M_@q>@h_C9Y;XlLbXp*3AkUDKx(XBLo7(%xPp(W#w7rvL)mN)(m z(5c7%*yV*#r0$dJ82``dAw0v=AaBlXbKfadoGC*`aiO#{{}ZJ>Rci*tcK3 z^6?v$FQNLdoU&bh!#%Kwd7`wLdi!DmpMU-gH0>>5b?&>fxkLs3V>h0$t+}K;MeqD5 z^_YVLNyFEjQwQ28*0_3XY?#X(C(BVPmF#gYA;psNhr2oy8xyKV-JO^AT>3jDlx9M% zYsz!l*5eoD7&I^t$6uU2}qJJ?f$ zp4@iqD&L~t_KbepHKY;US6h4HT#VpiC%{qf<2s86dJP^Q$jDv(MFE3dYGo(2ipOnW zUk4!N$v0412yH0hQX1F1*Wr-WS<-2vGwG+gyhyT{d0tf|r^BgOe(S#_J^b$3b1Qx4 zsHB@u*4eslfOSp+(6W8LE@1Vv$e(yFiQD@=A67F}TycdXyY1eI&Ogy-@4}13;dSe$6R^Y~^!eAG{B1-iW^9yF&e-|EGbj6` zgXMoV;#MJXojsEd4gfM70Pj^T7lgI6WEC)9iuCY`L2SLP2HOZKA))i6klof%yS;#^ zNwpQ;)7aTg{~lsgiQW$DonrfI(10!T`Ep#V215;YTauZ#Qk;4pi%mLzea=2_mlGzK z%5dfTuPyoT&)R5!-3Zds19AGzziJN_(rGx193M&Uv<|wajl2E+kkw4&3xgHiRy*RM zpjwzQyJ`ED@qWfOyp7R>?JH?`#fQeaUx?@a8;ib>v6e#|y{pGrm8i2#lj_N^2m49+ zj}WFi&Wbo#vie8Q?-Bt|Bmi8jS3Q#;SD>^kYtSU9gA+`3U89c8_2K;m_-;-3$YQF1 z>v43-r~g+L7`upk^mm#*iyJdOo=L@bz@}UiO>TC*$jiXrRUleq4NO$p>RXqPE3KlQ zpx}ODIeX3G^*YSbKuJUr?>VDT79^Q+!}7q#Aog-x2O)YUI1Y_7*oG%fV&HbEvqz)* z8m`=M4#n3~lCI+tnG6d$O{n&;aR)y+iR$QpzB`UJM;yn;sLfj$?;J1Esp10KEiv0? z>!f2V@j5yvfgP^nC&arqi{_bvLED1RrNZKrd!*c{{q`gQGS2gyZJsBgjfn~^Ol;aQ z$F*Ud_?_M#X)F)7J!;`;fM<`$VwUGh>S2FY8Jgg@xB|C7>} zpw^fNk*W~5p}5FpM_dA)YoP`>3{eZjq3WJGu{7hQ2%`a+ zQ^s|jtJV>nZp2`w0=`U*ID^#?m%5`_tMy{<@%Q`oOW}oshWhUdIt@AVzRaTtu)6Nmr9&Mh zm+Yo#@L(Nh#>;NaCjYttA$z7IPU%isRI3c)ze$xE=BaXqGuZ}w9FOl>=V0zL&N%8R zBr~;UmA5)AZj7l-vb;0X;^IUb79z~0;t)nz6z=IG`NleDeXl$1VbCXb*b5I2@Y!$py)uP`KceTtC(SeHyMYWHnXk>&s z)98Cf%h(oAyRG*RNbUdRuVgGC`x@9?+#KGwhJL0jYOqNB7-6WWtGgzp*Pl7|u6lGW zh7XPE{}&80ZvPflZ2Qq-O_6=sGQ=l(f(4SG+kO*#^R_dMkvvab+vejijBnSViT=a1 zKSDB9mqU2ZG(hVusO?&!hwGg==%krJwk!GOy#h?SU+s^n_czSesSPf->#4NBy5rW2 zlBh@AyR-(N;2O4i^%Z??Pr>lxY79!2LbLef?YOd`++bQXNV?e&W!0hj`|%tN)B!>8C#1xVCP2(A2-G)r zLVi$w@WYpl+t_EHDMT)~mjikZ38Ob5HVT?O##}NHmI@@+uz+UEwxp2z0sWSpNtgGj zCn-b)MUQ*pu|KmfTxcg*ke|!zrdStbx^_<{8I29cTD{VMHr5HZJjO;|Yc}OfSMwki z?tYI3q@5WRZtzz7Fgh6){o;>RTv`tt-6@Z@BhKDv(j-ZjKU>4b=3@7Zj^g^}d|nJ^ zz!1pTVI}zPNLgQdbq^~+7|Ly81{JI{(sVCTQ0+1H8RHFR$X~4Z5jFWqx?#b0?^gk# zuWmWdLa998H$QhJU;nE~25jk()yG1_J>k4ZMA-AtxA~B>J|c964rtve$kV?#__RM> zz2JN|K6cKv<~F?1KQu25OpN$-Ev$=x87>Qx!efkdOD0%Y)LRv{o_|qtPdoeBWu(p! z2FzI*=0eN^iKFc3h79%RR``0tKgf9&GcKAVDur`ofgpcB+5CCSN%r5O2s3v#L1{06 z125s~NPQjHOcrLbx_=cC_9posMN_F8o`DVms8z5?*{hrfVZd3R0*RtRsFRi<>BgMD_zi~6;aIkGH?0GHehU4 zofuA;XZ8b{goTxexG&$)uS!^osWMUUMVY|f;d>KX-PSiz{ z-|N8+m*)+|F_dP79;z#1@IpbOq3b)SB~Z4$4yQgR#y7F?Z#=c4z)tj}J<$0}QiM|LK1Q z0OHi)4-&g?@iHbNYi<+K-vgV1SaU*z+e+A60=)^K$8?_$FB-2*F5bCQ1uqq4^r=>N zZssl~Z^uKltwN`m{)+qD*fbc>N-wHyVQNTnAZ!%*FLLR`iB{Fkg3NMh^eF=!=j1)F zb&cJg=)5TY%(_|jaWgODV%b)s5G5PRd^V=CNsl&mRGbgJGB)m3_`19!*e2{;siF85 z3d_#M;*l(e0s z=A+NEm|MQ-nYt$7o!EV#ZfsQjdrJV>9*h;-lm?Eh1pE=Y?zU{E;M(@`f9e#L;}mM) z_K1TbgNU>t5TV9(&g9BLNgJL3oMjt8x=k~Ufmo*f=?w*BQB-wq{w%9|2ysjc)U6(j z!{$000vVJl_kCme+~6HL{Q0^2*W$iP?#e;;qe{Rek zvq?yP;;~yn$;S7}D7ami|6n0y-OA*>Y=`H;>yA<4p^-Cg*0j?$?Sq&<#3amCM|C#_ zD@a+Z_SM9sV$ zG+~wZ{lMx47t7CcTum?2c&GJ|q3#bMQN5<){0P{(bOl)oXwO`?2Ks<$m^sE(o1^+K zT3hrFBjo0#4g|)n}W++2_> z4h&wjyZ*Fh&tG?x0<_+)ei|n^2e31@3YARx?EC7<`d>5mnbWCRu_JEQ!cp}kzA~vX z!nw#&B5!C^&+@W+n`gmJaQ&pi*0ntE z)t2!G*#3GQg2X3eIi2SBxGIwEj+sm14Y z^F^k}VN#Cld%QDMoHJY6wPC?MQs!iL5t+;jy9IjYzz6Tg*#qyCD-vI8-+9vG7*>&} z*4i8KH&{~&JS}%K9R`UWNupt}Ok6%HuIc^GmZhZ7cXo;ymGXe~ZkY5B9C}<=yBqRr zmi1UO@=I?9-Pq5{Qr)+LM7qkG3iff8i=&_D&R*I6Yx^(f8QvrmKwSw^#Ipi%K1`}> zUR_484i15&{mj-m%JOGTI=lFY0Yd?b6!mhnP1KiyMM zt0#1EqjNjTU(sn6v#S*je*!N;Rpm9A`= z#K0pVrL3FY97_Am(c7eQWKZL0U~mxoOqy<=THO*)yTg}*>^seK`@lWetW+*77Or9r zkG4NbyXit0*K<{+w)nyx*0@+S7q_K2lCZAkVM|MOq5n@DGKh~BYi8$Ma%L*z?r^_q zRO$)a8-{~GtW@&@BbUj8KMVt)6av_ZM2Taxxp zZQCI+Ed+Oc<}Bw@O70)r=6mOz+QjBFeyeYyI_45Q_O@Jr^hf2z)ilBUGcv3ksAvs3 z@dtYvyr!FAQ(SOel!tsXuGRv*fQu#9@|@IysRCcXJw_-z8Vlx+iWAZZ&s?bDLjM|0 z-}N^Ar`j+7LaS;nvW3b;*Mn85Ky#li=sU<~K4!#<_=V}a%(JNy1lJ3lHEr*>8O?a^ zQ0;sv6M5~z(xnMVCN(2?%+IUOb9QNnJil#2b3@9f`Bp7{ zSf31%`3&T=XUjZ+QpM#1#$PIcb0&Tto*=DwgjemN`AknMhb}7Vdyf)+#EsWC5wmtw zOaWDWmQ_&{K>hI94_`yzyC=kIW-%YbOB+`e*`wZpd2yl=EWG^P-7tlN)eK$MDR*w2 zO$2XTt;KBc{J~0ppplDq!FiFJHTCf zh~-3@^ZwzA`11c>|Lh; zu@S4AxBGlG7FFKd8p0>tRVUFuTzqWp4^Q`B)M7q@5$xKQ}}_PG~-e zU(jo%=l@a9uVPhK{L8xT$w^u58WE-zPnDr`jRVttgs{>&AwbQ_dK4q^#vIwH(v@{w zpU6*oZPHdv8hz<63pb@*!wDCUITjb6{7ljwQWbwlFaJ0B1|&=_5e4k6__8W;_$le! zy3Px&hfBG)nQpFv+#w+_duI(q-LfnO_-IKp4L=yBP=lV-L z@3p6OCDba+w5NghbI+b?E+M5-S0BCoFJtIa%>^iqU)cibrN3njfr$yy%sQ9cm7Y27 z{nv-tlOJ3=ZpRFi*!?xo&hFU0Us0ks82GiJe<1X;aW12T>HJtHk6&cWaLv_?(OJ{E zwH1164*$0`&ZN4PVYVX_#(?f8O-fVqF#2eI!m{}M3i*{zdCDgoFI3t zzDc>o-puJsuID|c31;`&6-^r2we&tDk!4x~?57W^d(wU0!jVn>>n?q`=|c(l(4Kg8 zGm=tZ;q{lA#qi>x@M6aD(9^V7ZAR<5%VphxYsRo<6_W{9sO<*9DWeO~P~Lp*hqeBI{w0e?y`Y=}pfh!Q zRTf0>W?bN61liv8%(LxZ^GCYoxRuBq>FfQdXebGY?v*&b`WG)+JyZVM`X??bWm+!KRFr$eIrbvYM#n6Zm+ER$il-#qf zYc+=_ji2>oD61>8i6CafGsRZ1i!c7TT_w13^lBD@*`zh1v#Z)S5U(+c_j}*`LbzJR z>5DgqEMeCz16~msy=RIU+;w{-7UO<`tr0;(Q4LJ%?J8GQ)kv6ZPZ6_>p7Hzqxb|i5 zOrFT7wv(}Rw{2Ip6X?HV=5zgmqn4n?QT}XWm-uPl^N7TuTEu5a8}m9`0uZ3C25&BFW`6W z7(=_B$asuZ!O!Gf7G0Ivq-FBTbbpL0*PV5fYnLR=%MV2sb!0_ZNOhI#@YI2)nmQ}1 z|M;Cb?M|MhT0Q)6j0&7`OT+FBAp7`udCrFYCcJ|wRHOP#7 z$o>#|VrVfdo%CstT@f5ps zthfl~c3kWCSA@Q8e33CAEn$(U60&u|N?2u3EJTjK`~ z8Y{b2&*}yr3mJd9G4@HN=iSVHrS2|sqbDUvBY|tNRQ=wCJD2ofj^xkL`Tu0GpFa=> zHXX33hYmNcM2vAzh5ADOd>DuQkv&>ypdaW|6pfgH`n{2&!knaiCq47w{asl1h#b%yUUYF&{W-GT-lhcY) z7A0stDckEJ^0ADwd!(%i<3-Re$u@z5Bvm1Hh|3Y|=0;unvxzayLD6_ha@jaZ*1B$R z`==t?4&8XPT<3+cv-sC?+6tDo7uj*{1BeSks~`H+YmFuI%$Gs$Jm(k&BBee0WtVMe=V-Q=_dh5VCu zAqgqGsvRbL-A?ryg*dop%0q$+s0#QeUc@>i?CHsfdj#Cgh!XJvQW@(uE-$Qz1qfGNLKhM@+$#2>~ z=Gi!Ckl139_3|EjxbRR#wmV&XVT$a-g6yW(?xBr$YM3@}>B_~xv`&c%3k36~lv9*H zMQ`08_S7y;t`MfxYKA@-ymwi>3&ZiT7BlqVo@_zb=XVD>Y%TvH!fvlSpbqlz3?lzD z70B#1=JB9a&(nZ&zrDbRySy*%JPeOva}1t%aq@!Zx(@O1 z4d!=vF&bY&FKX;~$8$Z!NJ;&yPK_dBSbsrB(o$myEaGmq%TmlxF(J7x_ulEh>h+}4 z2YQuhxe$H3R_s#5pN|nJYoWWY{(9JglnCdcr)*P0V|Cbo`S=?Winq316_B&}lPxpB z9kIVrB|S04)Z{#&MSX84CQiM+WeO)Q@AAJp-5oE>?&ar5mNdRO{`;YviDOdUtGfc< zrY>aLey({R+@Mu(%qE8%@_IbnuHjdK@xCgQd1Wj)bWfQf7Zu?$=Pfx`xF>bSt zr8l#hQrNnW)xNJrtIGNYf7J9%6luuiEYJZ0ws$RF6Xai4K5AKKHy;6R71!NImk8|1 z){Sq5h^aJ2d321tKFBt$%1iIvtw}fXl@A&QeQoxD{8P>o*paUEJ>rjTPcP#_^Ul43 zgr-S12brn}k~MJt-F@o&jp0!%Mfm%0M#Hw7bMwW~lNf3A-_<`b;L5PLgkt4<9l!IV z4-fNPLJPe=e3suVV zhqwR%&!Qen&e`mzUasg(@M~ft5QzPPll1TOk>@i$2Z_)bN)rhlImmn!#1JQtwMYQyVXM? z^tUU|ooNA$c)cHJ7HsP`<>vP_Om7k}TMsQ(sSWFkR#>@A8^bZeoV-)3qB9O20aLRb zX?8s6`$nEo0AIE(PADC>J6*3S`Y$C5CJT3R!qPMJ_dIgOWkAdFS0%ZNmNAlU5xKV) z!Wc=$we3r1{eg>JSjJ}1&pFWv3nDX4) zh20mxm#*1EvoM z5{WeeE`*`3F_&K!7I`y)Xq%Y5GeK0)iBv@|JF-k0K?fT=S1R;Dgr|I#F*=Md`fMa0 z@{8in!fvGY{;{rECw419kQ=r!eX!&R@3WEVZz>hkQz^=Ah~{(CEPMRHGU<`OwqTGy z96$O+B_FfQKKiTA7?=UTVY2sy57~irp%3%D#ruKfE?h=t!(F9i)-1lerNd#0Z4`e; zmQJcFk+T66z?0(lPAX3lGiJ-3LT%5(lHriI?j_Ufgr4-tMlSqmK3vge``ScjJ1|O% zD{42X&t;)o$pq`F6u^28ps5QS6+8U=0pk4qqsh4ypWCTMb>>PXU#G?3D|fiCo$D>@ zCV$(Cr(E5)13!hosmo3z)yZn#lPh%aF|MB(fQM`5x6OZG6!m^m_XazVt8n!G_sB^o z>rHsr>=$A@n+9x2t0Q2~J4_}KV|(hN+F|XinhA>M-f?nw?B=uDuha#&uIzchg@~gg zYR)3g_idB@_Eq+gMWc10bTi(M)3>Taze~Xt>E*N}{sLJ>jO;uhHH}jiy^+{^lk=WV znm3Dp2QOB`K~B;8S~%C$+9{eyxC*cIOW4wIx7@(`-sLRXZ+!MBm2Lbagl$*;_CDo~}|XUq{kA{oazJ#hP7h?!CDY zxJ;)?QK~U@((0aui?eNc(}_hNSNr}*>^Kxa3-ZD8CcB4mV!C7Ru6XPT{1twZ#&PAh zrsdEk4O}0rdLDnWeJls{@|UgLp)f*09ks-kEeJ#>#g(vgfgjXSH9G`Il){LzP;UZ` z!n%s+8R|?BJ@`^$unP;D#AFH5?xmD%{iye*_8pq<|EMZN&w?2&xyLxZs_NvEMd?A= zVlvnSz`OVJ@Hh4^zF73TaTVmuN~DGL{9QiLT)T%xR2~oLSt2>z?8jt$lXR>y&L+~o zVoj$kW)_Y-(iCJ}fn1d9CoPe^>BNi#zBD#Edws{yEe)U^B-ygVSWc~!VmIA?gWDDU z?TGO5?2d!tZVzhAM~(Sqj%47ev4nwlDa=*$jGq0b0!=`kM)AR%9nm4J@fg80(LA`Pkln%=u5PD%SKnn?yT%vwWtwM2>qoyd!PD1z(I4YVo&Cg_t=ppMXDurr(u&)U+= z5v(-y@}e9csjAsXBIYl76<7RI0zzmW9m8Ov7J}F zyS&Y>zxAL8O{iCL&i`u!z>5$5^CqkD=S++`l!$T3IGPKet^T{H?cV+_qm9k@K6rA1 z@77hJWhYpB_7|)Fxb329wNpLgnlwS>jvrAw z@!FnOkq+~3Qxa2nu&XfH z+E?z8OS;<~^bfeoY>w~k=w}In$6qHxMrpqJWk>g#(?n`zk8!SMFR3HCgGwV1R~lFN zdQ|67Vng?CyS0a5;|0-*YPpBb8C+y77s=C#E~t=axJk6jF2vv6ioQHF80;w757eR` z(ES=5{F0|)sy|39e|ZxsDz3bd56e&Au)RE?KQB}4(@hXCXWLB8g=u*YVMs)#r!{j> zITeKm8>QhIK~}Fce*GKNFt#TWF~QAI8rSv;vJgwODLcv}y>FmaNL56>yg{tq&LXm= zXR2bp6>y7cs!&@0@1@u&TI6V?U7*45(|rKB_?G_Md6OGjX)IXW$JRkI&~>cCblSp9 zh^b06wZX;XDVM?#CdTScEmU4Zrw#up&E$=LX5{EcQ-67Ar*N96%nc)ITKZnH6UHph z$_z316l*6b*VtfJVe>a4j5Bcnoldg~;(#>`h|V#u2HB|%gRB~bI6cK>?j^;>2nN@A z(93p8u^6ELCtmJZfAQx&HMCMATurpgEHGeLpqj3&;}-fyxQxQ!q4$#HMbBA@=hE%R zLb{e)9&JbUUanA{Mt_?8v7i8ctHdmRuco7Rmdl{Tq^Rr2&WyhMPEJ*Mbt08zK&caA z5=(?=7rvLWb%;r6*QG!~`ReNlq4?lwLGV(MY}q!ccS$G}uUD7Tsz@TGS*+dF(DmbB zvh+M(;26pW>#8T?<9cXl(U$l$xAdN0PC9oOjX@OQwb0^L8Be72OF@1f^>#5r zs~7e$rGOmu*YLZKW!xT{)SE~=X2ygt}NFxug9PH&4p~)WlpzDIZ zSlhW1w7JFOH3Zj6W)T$K!fKOGrMMCb5v#a?*F*T+63NXg-rG}bv}3C?PD1O9r~?ff zjt6(hTV7Dxwc@{m6opIN>mH>dIBB$c7l;4W)lul6uX9erRn+fD3el(f!cp``FYQo8)_S24`%YOfUP)xK*u2RP28 z%^+W6dD60il~nIUdp@w8A}Ios1ph55wP>I(3i{GSdFllP6?L6CAE=I}IW!-0z6*Iy z+gKR$zU@GqXpE4|CwM^Omz`rVfHmw}Ae!5$rATv5s0dwNjgP&RR;xy78aITbVL&g^ zuH(Vo#}11{2RWdxI_g4nneHl+_7v^$!PL&XwZ0Y1 zY&%Hz+Mwj3<~;6}a7cK1c~s{##K`VlU2>MaP^yBe^Y}pz(K$$TUYl)2mSXtita6lo z{Rw&vvbMI2#V@NljsL4e^>p#Q<9_9_@-=Ie{&<7V@+dc}?%~3@k+CsG14(t{7-mE~Jd1PK&f*BbB zXKX}tPyg&qjdM<*ws9ZV{$wuQOp97HK`p(9tMt*LZ2XPS0zS}Vh&r_o(eNbuu6w^< zR;lVi^I+aGbZ;DjC)z2193ye4n1Af#9$p)4k5JJPGxRt67N|`(G(G4AT$(zE=;H9@?%j?y zYTZI@aSQzOnNn+$_@es?rzH+ID$nX@)Ih2#Nbc{d2)jfcqaR{oJay)((!Bc)HA)Gq|(Gc#8>vc+f-KY`_Nr2p6lf(<^dzickA3vsW!f{U1*JT zE5C2Ty~VyJ(P2dz^svFv$<9_Dr0MF#)JXzl{3=$O1nPEXvbi`0!M}(qn1U`bzc*?Z zD{X6A?rktMvV7kr6q+izyDDCtDC7x!)F9Jr=?DP|qlA|@Cjm#tNj?ANKTF|yCIqwPKESTwC? zdE+`)_ebpR*mQBaVh`P|;9qH-kyTSl6<_&P4d?zM;~Eu1y{$bxhV`rxU_C}kXGW?W zKA~g#e`J`#qJP$o^VIicj>+r%JRG8X&SCn8yZKj^YZKV53B0Wy-#1dQOo6=)k!8ZD z5B$t&#y=}l3$E{;kw#t?Fyv!1Za(|KWkoG2A%B}f!XcwKOZ#{Gez>GBenjh2$t`a@ zEQyZM;CjZYUqMzj^e zIjllc@mf1($*I1cA5(#*kwR69!;W{HC0S|5*`mi-h?~R_(D|RFoh5>Wtc67}oqdeO z?<%)uIvqbbWlL(ny;;y<5PDY$6e@2Q6^5JWpScP&TJY`Pp^}pA=jc@foaiOREWLpU zezJ{7nad@EKF4q*b={#gU4OqWcH27cN6ZHR)0WR{UpnL)j zzWH>8dGeam-w#@1KfjUY69-Rr$7MiehA}Vn@fOsJfKA(dXyu*?qf1& zzS1{^qjHfhmR4D!oI#qSYo|IEGU>Wj)RExY!rp@5 zCDh~KDof1fk#u7~qzCD)?KV;sD^IFusSie-}_hdqD z_{G_Vn4C;i=+Ehm<+*afMVMu6#*kM2IZG!~7Htm8?n+|T1+8TN zuuU#ZG$$uCPA?u6&)5)qEa1Tggi|r@oPVPqd)vajw=m(lGGDg2WIN#fltEVkk>`o! zgN;B9kNl?fpo(pY5q&wvwu@9jY^cL>? z5rVnr8`i6Z>v%-;IHRVaL|X2gC_2)v6G6`aJK-z=GhTCHP+H%OM?GR!Xka*{;zU-0 zYLR*G_+YIC%j~`83CosBW4(EMmmK4Er`)2T^dwrJvf8{D#SE`xVDQ@JQhEsO79D#P zj&-4ai{a|&%0hE-Q0MZ|3l3th%y(*H_1d#lLFA4QemGe#J{s`VIKKoMj1d{t8R%TES3hlx#xqqUb8LPVD*o@hmcRRday zdCt+qt^Y^kCH8>eU7(_tl=AQgsp#P|BEja_duv-5%2(U!SGK5ik1pW5!cQ?rR(6>e zJc$u9_o{4{MHI{IJcpgAoXS|(=VQYC)Qv6HB6nzW!iarxH(n$AobIR$Wm5t7UI30Q z^`?IaOPiNI=JqJIX6{2;ymJ3h|MX|0f(#Ds4GM6-emQmmj$|x#7sB4AJHX$g-W`S) z{t@0&(q^7?x%;6+Jyg?hQ4l*er~A4RTtgbP_3ZoqZ61Jqf3tHu*7`(1 zWtVEbx<1+hYDJe7@1GnOtU1->EH|iC3U!w9PTp-0d(SR*Yv*Ot82Klf@#N1RN=%d= z0Fh<4#&&q~JNdwI&LiL?q0nyfPf;}OV|$w{+@-eDBjN-0Tjwife`YQ-{rv1C*-Ut- zQt-!cE>ommO-0YchvGd5)MbWzZ zB)@j6@@3WkWOOi^n!?`Wr^xLT1@QaO9J&t)e5N842`2$Vo4n7TB}FBP9ub0K^7i9i zgby0oKLC|duVEi@M)Q?MW8h9Lz!83lAz%{zZ-aPZ{o`;`@L0X*OKlva0A-t$wD|gl zyvwKVRMLTVyh2d7hCGHU?kQp3R)|Lh(e;;59^v_Sd$J9}RFuAdwLWE$h!T=@^ZnOU zdB*hIfJ9F-O~At?J6(HAHW+0YG!-S6MLRMvAf%PGUe-ocG*0Ywd78uh-jHk!IUGA) zM#~<0|BH;CiU%R0$^guNoE1Q}ZO@sN?VZ};i>=+=UO`IN5uOds68qXxVH6au>fb@?C?^P0ofUm=H;tY<E%ntItQCjSMli|mRq#1%ZGOA=gFOsn%E<|L?O-`(J%8>;fy<^l@X9n zl8jmHRxxtk04i)8wx|8pq0aj1KnBo@m0K{}p2y_{@w^r)n;EYeSZuA&3IH&J+q(-iLzx107|sd?iw^2!L1v468I21HcZ_WU9oN4L}FJ^H4 zeX!i%YmJ`!PN|MiI5B>$5A7i}RA8ORfcq#7Hf^HTnErALutCLY9Z5Zmi%uZI#Fp1=twXPD9ruB3WkmFgC zVpHBpQrx;|Urc7S+C_fol))P9opHzFv8*MyiU;jkZxjxynvOca4dLGzN zv-}3Vp%hgz4bkJEY&_o0R&B3oS?5!te+`P~?_d1zapMbtKVlN@4&e+wC1}@GIn|KV zH?uB1%}GDBTL?YAPM~;ovtnjO42f)O+3O#W4Wv!{&LI_Arj)*~gXi1!I&+EaP9rsx zid2yVZtb(;>lP_)`@G#>7#Qns*s2nemXnUhVGXi$MzuyFV#g~hreL8()mmHQuW|VB zBh~hE;apph{&H|znU&2aL>bRLKq9xWNob`Iu2n7p76mq$vJ;ehFDTn5 z+@O9F&}`bAQ&$|2x)quLCnGhgt&e1wr<%EQHDubxUnh0p|F1(8fa8u=b=NQKL&55tdjF^Gvwml*IC~Efrzq8T}O6g4)Tqq=HiR$ zYy%pG9O`CPp9Uw%Oucab@p&ZL-J+~I!W`09Flr$}hiyrk3M^xC%n@gf$ zJ|sIIOp!E971ahdVratOLzTLq-QQE-HTr9rA5LFx0Nc3kZt$8@CoXs{FS7 z?yPiMVfEGMGwbrc9NLYgeZJJKz_s^nB}$`n0G~uP@}&JVH%I?WK(rHh{EUGq>fZ9T z{V^{ps6TKh-8;!IWwfgP?fk9}LB-c;y(Cz@w3x!>|cDTtkfJA&g;+my~y(Rcl>Og_$?&cNF0TtH7|nd{k!sP9>I z^XAj*z$VpGy?+!`&s6wi$0ly6^5UZI|=cW}5A7pI5D|D|8iU8<2srUM;?= zOlJd%cq5XVKtF+8>@@phe`Uj@-1Jn8Q$Pk?7(cx|9cRPxgTpsmqtzf@%g?~1hMq8=WTa)9rY9bH9lz#(SFt0D?IR&>e<4(l6-<`=a%WT-0czgpq^*Me;C($E^IFs6@0kzv=A($ zbmZk_dnb^_Gz~KxaUc2q0lo;>(T4f>j`RAv#QN#~x|?oq%?ur;kNNr4gR54P=1h6- zx6Eg`&D&Wq2f|y;9$a*{=6@UrXGvU~y}<+pzm{3{B!R9H`JErbi>Gsu@*l^CC)`a> z-h>XM{B{7OR`ThtdpyxG_S-8VJLYe9-@U=iSY9V5*OW4SYNBLW=byY7ifvPx=}XZ) z60;DmuNA=Sb9VN>zatwibY)EAs=S)M9na^$l%m& zu4`G#@qNRq&42KKOuRDf=0vD)>nZfys?He}>*8MXt|qgZlcY%CVSS}RG`#X zwiq+cGnZRd-j)sTWW8OY3I9wn);%5m99b%5im3rlpEQPZicf1BMgegMoc{n+`-4~JrGH%E>wy8+_f zmDDceCV|ywt8}ix9xu+aq}G@_2PHXLxMhN}Y&tULd6RT6Y;1D~n3g~(Aor2JcQC7e z4tLIa^|sG?y9fcJS`GW;CqCm48Ta__tRgjbI&kRu7$?rO=zWA`Zcw7?%${F8h7SQL zEuuk|Yck-=KMoN9U>L&!@E187Cst@8!Cb=`d=*;jOe~0f)o#>~Z3Lq9i&bF=I)J$0|Oit1$%9vrwAwS+V;x3j7^y%Y+%xKqrwU_+`hEX)ND}KC& z1Z8y#uFw3)Q=-cpcMw7(OB!uZX>;v95;n{KcNVOJ$is|3>oQ00EO((SB`+Ow z@`x?5#+`YZHU&k3q;A{qUS#J@Ie$H=4@%Y?IiI9cKgwlN^LMN661>J|nOWVIBIg<$ z^Rz;FgqxM6)D?&0Z)RB>8LsBuuHE}ly_Jws)o?1$@NaCWi3S2C>ev`rTkLb@jO&VB zTaFv)D3~b<3}XZ7T-6G=fv=Ii-!Gq+ZU5}obneR7>gv%j$z&*CDCPW15QdQ>wSEXv zsM^e*t}w(RI7G)OxD2-({!7u6x62S-iZQ)2@b=hFbtL))Np_z7U=1mrav2{g%joE@ z@nT$kUmDh`GfQ_`fS~)fgR*eaM4rJhfE|^ck|97O>^6 z-8wP3F3iy3<2cz#Yw%O^nzpT=5 zV>nl9nOCEuwHf#6V3l=Zd(@GW{`1+{A5JHF)1XBvC!6>_ zGBro>D=Bms&yaRZ-VLm!R0%9D(r6IQd5XH@Gw3;R~{ZosvovV1R2kM#V7Q5c$BBpsm%Pzu`PERzFyn$%iO(HVx!ta=g z-cr(x>G(4y$#qQ!^vXz&RC}LoxwiGYyz8+V{kdr-NFg*AhpN`}{3i8`kG;oSoJq^| z_8`pV_K<7N(@w6LfnSAF16O=EuKaPnxp%a~J0sPkW6;2(vfp|swUX=OHUlbKMyez7pTf@d$DpeHo0xR+eBb*JDX4hC0)9(I7V8GA!l+3kuBP2#9Ry1dgOx;dTMqy%U z7%kmiFVgnrPhem8!nI!&n`1YzM(T*8_l@2qR04A{GTllk1CO)kug`*H{kiq1eiA&J zr@=Nw8C6}ytkdp|3octiO$iaTss$I_qx7c0u!{Dom`R2udlMG&MDa>g9G}Z=g>#Ye zG%W0EYrS#L%@v$Y072;idtT;5iwBybrQm_@I913Br?yT@mVv1Cb}`%Ayi)3F@1`(j zMpFb|g}uwg*S2mqa-FL~GxTD1E~%_#KY0T`Ld4v1mx#T<4|-Oj=j|YeQqdKnO>8c8 zJeVkEWu+f%{&i|#C-)`)DvdoQEoZ4|OTwDg>UO>Di^+`2B6N=Z7nex5Yw<}-PQO&g zO!Ts`mIrP7cj;4z#tTuD^OCH3y@bt~m2dWZWU-cRBq=&UZOQ;!nPR-q`hC}~8-^uG z7aK;ujBJab=_ECI&Q?J=@QQYFKTP9cWwYYSy`O~{V9u?GjN={2xYb{PmdyiLeL$%p zg^k83Brnl-(A?Hli#JC8bR{DtXXwG+nvyEk`?ms}Sfeg!VNzIxd>h2F*uBONIvBr` zw>Oq@VD&G><1TksVv1C-gw>+E6ftz{hS;Jm^KSZHliI)PG8?|ab1-Xu*#Z!8T} zt_s$Iri_cD=y;xI!;0DXZ_iyH`H?GF%CpwyY`pqmmm7CmR{6@DhqI;o@0GCiwi(bzM_+kf37^;4CDT;7$>lyHF z>#-S8yNQMMD0)u1Jh6Ws=+nol0kz?mcPS;^xzb0@OF9Exka0zzA>FLSjr`XDLw=LS z^H=CvI9_Z|MXME)G00){CvHUchV5IE-j_dxunNdDLr(^Gw7!Jh7K86$ae5!RkH||9 zx@C9;$^SW#y!NLjeW6=bGLW>=H~A>r)KDhL7xGAw32AT0pOtyIRlJ-dCB^9wC`7fo z>oc-Gr2d9m)bmwEMimh6sZ~9+wMmbt^g_Fmx)?28+o_e5;05swQry||TQ-rX2qq9c zrWxhBxcWA2Nn?4_Xs!MU(EBW+a&dDGs;tP-O(tEEdfj?qGz> z$r-08BXvW&&8WTSw#3ODCqhh7S(j3$qj1n*sXWD)_|YSl-m@FCpWensK2TYgl;D;t z4DZe;8O*5ho?tQ>QOS1aASLCqR$Eqfb7$F^2o^>Wh9$wglOIS`aTACOgz{xEwl4b5 z2(5ni6cOg;7-#tkzZBaK==h`(pG^W1_V| zuXNUOPky2YbtN(ITyp;^ESv6-){poX)Ge{FI4~pKd+X`v1Po8|l7t0HemP2==THLak7r&{H zwQyE1WIDE*^yCI^+S-OxATX7RhWit1S=k2quWpM}PbFb|7Ak_NCutS@8!&GIQ_)Y6 zM!5SKo^WrSY+9V$vwBe1)NG9i#QVX-8tGXfQEDkAd?pfIbV~% z6fyCvA<@on*i5C@aCEja*F)*dJL+eIO`x5@v#$`@dtz;Lz11}lHGyt`O9BEy4BxB2S z%ir-k&pi6Qh}*$k8E>;~XNh~;Hu{*b1n-DZ>hARrd1olmD;oi<6hXxuz9IKA+kDBZ zQxcF!3dbW#fH+uVXz7pLO_VA*&TODwITKj3lh;#2qslD2sz)_bK&R%G-;^#xFEg(2 zEhN+dw1qt5A$r9_9a53jFSv80ad~PfF*|Ss|5io~TZ81|ZE6qdyd7go&sOH#?CXla ziY{I_|1GwNUIYh?S@arP^s7r+fm{ZV5$dxR)7_-@(Pkm1Pq^zX!|U{V2Jh?&C2@e6 z7z3rj%{_ow<+vYzfi;VhW02~CiEOYBCW1sq_=$lkJK%NR% z(CGcO+6|kFVaMJK?M=m*IBNbpa>EQo0$PM&Vlhg_4=kHv?IK0h`L;gs6>*uNj-h`rx<{^i3o{xf-t z5o6}ly#%EAUKF#N{s0~EVX~m7wZ0ySiR5q_5!7peE{Q8|>9;`1;?j2@n%o-Y)jJS= z1;z@I%~73M_AzhG9^aU6W4Tn6_uF=x2&vZ0_3o8+0&v2l)LM-WZ1tcL)o1ADM&UVa_FKglBqtT$?`*kqnjwT0z2f z#8{j}Dor4j<$ZU>91tYruGDN!{?eIxw!8~`cZ{Bqu)5OdCF-e;Ku&3WG;)GdBjP6j zC%ykK!cf&ewaCL{j+D-qC@aW261H`^KHTPbF%$n3qkU}Xg}%%bcjMZVyet01amzp2 z9kbvC_NEw4-ImdYd}y{fk~Z8tw_#;x_54rM&c!Az1ZQuEMNb!5#CHNBq?3B1=LvqP zq|tUvF&OV*%ssG_t_x2s`ahAm4;$su*An+=Uiyw5??SZ4>AWZ?V86>Rbp?#5!snJR zxwpE;AHK}Z-*U?A9P*onZ$h5pcU1LJVF^jyq@Kd;bP;Kt7@e9~?X9H8Tsnvvd8N+9+L2SYch zCCjIoRTl^5LhlWxVT|y*H95!M9!p5cNXh>}IFBU8J3Kz|h4ICXl*G9;&~`lPH56QEbShxarwO zt_e)nYo;Z~2Zr5wy#wJvX3%IJx|LL|BxhiT56Wz~fWvs%?<>P!;FS3XxJ56@HBMc> z=_PLl+w=(>z=XI2w0|V;q_^%dYg`ZKGqeHlVIzH=JB+UWWI{lJ z5qI=}<-_}QH_H7=CDgP#FdZBQ@priz$E8$?t^_*ZckKxh#3or}*-B?w;#f*A9}q>7 zV)FyWI@)+eBxH9WM0)>mBSh9AzWLQF9z?~1N+D~0}3S4r{8j-ySrO}+4 zoFAMmQ7Z~I;2wY}@&_>nYhH}$j;?-?&Vx@Y2AVLVO<&w69(I)bdf55sW9zJtT89aS z!^YjQri%>J>}h%i=aWwtS9l5;O?);sPAWDb-gh9QhRS}3KLq!#kL}mI2O|9dZBR+^ zyDa@MOKgs^7P+Bp*65|P=20h@t)~{K?YUYtmlkGv{{8!74-RZ&031<}Ml-mxb&=>P zYDVng)uWW%_|t$)4TXY`Fb2-)emdBbw4xRY*BOcI_>Vq3YExT#r2#GvJ}cq3bDX#h zL$Y?^J;f{a64J6TK+Ur7GV%qVg_T7eBKPt<)G{)~rE&GjEM}Z%0~Tn09$NAv zdoeC))ix9S>eyMh- zxLML^aYn<;bi3SV4GKs^)_1)D=CKsv&IZ&+iGrVKBg_v-$-<&=Lc&{SMyDq)5E{25 zlIiK{L?`aShs!_lcs#i-+%i5acAqFg97kLT8nPaAiGQWXak^Kj#R3<+$A}1v z{*T~8r>1eKf6lI9RI6UFM&wN`h7a5Ep(t3*DnFV<{<7+cXOxYUt9atw;rAtPP<1M! zykCI?$VoiVBrw*?@%uL|<)gtlNo5v%iYQ%JU^oqrWU+7@ah!dH3hgEJ z^=U(Z@bOUTY3>yVq&aAu>J^R7+C7o@an?_CP6e*$%V_x%hq$rZF5!s4NdD1nLM^KJ zsIDpAe5rOge#!R8Odrpk6$#mU)&@0UF0`w-mi*;<@_bA5>sUxm2nGG#GkGHVb7PGE^Yf;ew1otmIQPWkedSny+zW^{QKv)0( literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/bounceeasings.png b/lottie/test/goldens/all/Tests/bounceeasings.png new file mode 100644 index 0000000000000000000000000000000000000000..184146512e03afdcc3032df1dba629d4cc18d76d GIT binary patch literal 4630 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/boxposition.png b/lottie/test/goldens/all/Tests/boxposition.png new file mode 100644 index 0000000000000000000000000000000000000000..4a7d3a8b96b16e1ec6bbbbf19de5598a806a3706 GIT binary patch literal 4079 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/catrim.png b/lottie/test/goldens/all/Tests/catrim.png new file mode 100644 index 0000000000000000000000000000000000000000..2e19432a3249f540b57cc6018259ae7089ba330c GIT binary patch literal 19826 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 z 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 z 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

~A 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/dalek_converted.png b/lottie/test/goldens/all/Tests/dalek_converted.png new file mode 100644 index 0000000000000000000000000000000000000000..f4aa7422f7d775f7b55aaa2751504929e68f1206 GIT binary patch literal 12835 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/defaultlinejoincap.png b/lottie/test/goldens/all/Tests/defaultlinejoincap.png new file mode 100644 index 0000000000000000000000000000000000000000..de41d6bd89898fffb41fad9b3eb85ccf283ef7bf GIT binary patch literal 7645 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 ZWVTo%5pY}n<5n^M*jhPQR$837{vRRK{(=Ai literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/dynamictext.png b/lottie/test/goldens/all/Tests/dynamictext.png new file mode 100644 index 0000000000000000000000000000000000000000..de0e14945c20c3499f68870a60cd78b1de240f1a GIT binary patch literal 12808 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/ellipsedirection.png b/lottie/test/goldens/all/Tests/ellipsedirection.png new file mode 100644 index 0000000000000000000000000000000000000000..f26a6fc6a84e0e6e7938e8da4f302a638d975ccc GIT binary patch literal 13243 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/embeddedfont.png b/lottie/test/goldens/all/Tests/embeddedfont.png new file mode 100644 index 0000000000000000000000000000000000000000..de0e14945c20c3499f68870a60cd78b1de240f1a GIT binary patch literal 12808 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 VTM~~9RpH~#X;^)4C~IxyaaMsik&<| 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

*<>@i<6BkdL-RD0 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

Fi8yR-=vhvHOplSYl+r4%EgRDB{eP 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 bMq!+;}6{dH`c(}m{GgBVKY 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 A&Hw-a literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/font_text_justification_translate_scale_rotation_test.png b/lottie/test/goldens/all/Tests/font_text_justification_translate_scale_rotation_test.png new file mode 100644 index 0000000000000000000000000000000000000000..055b7e3527dba81514c3d57e8e5a9644bc320c7c GIT binary patch literal 30693 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�eD;AnEX`J3Vy~&^JHi#B9+}*+6zV|7k?}`l^FC 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/framerate.png b/lottie/test/goldens/all/Tests/framerate.png new file mode 100644 index 0000000000000000000000000000000000000000..ed78982ac584207524891c3f192df543eee7907c GIT binary patch literal 2028 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3Zfqj~%i(^Q|oVRxkvqRHmj(@!0DVY;kA{^E3yEIzK0FT~SWG<<3h)0=agYpD#Z5zs{~eeENOi zb01ottK3WUS*Lo_C;GPYrmGdg45y;%ML%orwfaV>zzmWN9@5zrU&#isl^Pa40j}4o!fO++Unn`o{ zc1wGfS-;uT6tk1rfw2i{-UC@HhP%Bd+dcKR-jkj5K004c)R8@bOHXy@{lx7)7h;js zLhMG;3=%j{HR&ziZd)_P1#7-4-h5Td!H{6M?hfMu2AH!x^&_4O{*lc^Vd&~)p zO?J%AMZ3RCGR!awe+Tjm)WC{%zSAF5+t1Fo&S4T(eX)VXxoH1)$%d=XPC@+!3M+>9 z7aBu1Oix*S_}yf_*=sZ$*-uGN`m3^g?|DY|lT)o>;R6ib!3MUN%X~dBqh`vJ%Zu+- zo;|I&^ENP1ypo!{{#Z)RpP!q*pXX)JUHjFJfnkFMEaW2I*E0N)o_yZw&!b0|6?fjO z5MH3;sJ=ewpYP+d@yah4ydR?lO(NT|C$Ck+rO&_PIT`lY_rU}f*=G-vCY_hgpVzhE zaL$e*in&z2QD76_1{v{5HJ2(r7e2OCJA)LS4vhB}GH(z% z)|_8ybGhQ%uL(8RlRPdkMu?_Q+H=3+v&(8ll(Bp)M0Mmb3g2%R^4~!McC=LN8stq#ylWp?${9N%-PFM{XXa*|gRr4D$k`>S|*C)@( z*z+^^vF%_>I}Fc~U(`0FN=&w&B$IDbUFz}9^d3utdDQ#b235;>PwpO@eO&52vdg}=rR+bf=TO|_$NhZLo01!MJvQA=6klM89#Sbj_q;dVtSa}A z+j6gE6^rbN)ieHIs4DUC<2(8J+U|gf+U1Y}3!Jt0IJ3`aH2i6C^69b7`fX4A9{cin zUSNFouxL`gbiQ5pg7a+)m=7rSp4`e;|7oYKO7!~wi-7_UbJccU`YrI$yO1HE8J6=g zQVWJa$j|+E)~i`wtN0uUjGctStggiQ@4I&m%o=Yl+$WLhxVCya32DL=JN-olbest-fw;{ z8CY5x01GX3cKHfrVCFo0J8q)yAW0)LCM^8UxGVuw)#TXh28MI5dHTW6GsMm(N7?je z&b;(FBEP0%z#~}A0WMu(B@d`7p@~4k s-tUZRN!6}q&kw;J`OyX*mI*iiF)}~@$p24I{47Y&)78&qol`;+0Jk=9i2wiq literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/gradientcolorkeyframeanimation.png b/lottie/test/goldens/all/Tests/gradientcolorkeyframeanimation.png new file mode 100644 index 0000000000000000000000000000000000000000..c459ca5ac374025c5a3dda19869b7954cd03c29c GIT binary patch literal 109391 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

<`ksgV)M6|W7pOu?mnSfWv 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 b;oEOk%ep)@T6I1Eu%8#o+Ta?+m+$`zp$2R9 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/gradientfill.png b/lottie/test/goldens/all/Tests/gradientfill.png new file mode 100644 index 0000000000000000000000000000000000000000..abb2323623918d2836130904c238f45e4cff71c0 GIT binary patch literal 33178 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 Wh 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 H2>E{i#8Va4 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/gradientonecolor.png b/lottie/test/goldens/all/Tests/gradientonecolor.png new file mode 100644 index 0000000000000000000000000000000000000000..8184f1f3e298965ac205e6a62192ff799aded9b0 GIT binary patch literal 13713 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 WV&$YND%9Vq0P-@*(xsB7LH`4Qd^N`a literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/gradientopacityinterpolation.png b/lottie/test/goldens/all/Tests/gradientopacityinterpolation.png new file mode 100644 index 0000000000000000000000000000000000000000..d6aa263dfee6b5ec43b2883132e56dbecfd139cc GIT binary patch literal 17115 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�h3N(ZKAETf ztUlVK*_Gky8IsC^_OX0_{&^UK_dmzEPd zI~?(W-BeK~VqSMuAJUt8GXt(Of;vx*73R09sX{+~Zj~e_#k|OR6Uj|5JRvtCmb-kr zJpezkR6im_mocM|*@Jzt9F;x83Y9GcjIC4}(-C&o2X@GY@tq=``%~g-5FYHw_L*mN z+cr>0zS1<9)JDLAZ6?}(U)7IA;0x}HVVT~?=H3{!YZ8k|!pUrJpGHqeSQT`{ZI_Dt z@iG=OlTI(GLKg(5MRCo?9S4GZY>5Yge9KYKo(63*QLPFxO%XpJArih$<30;5a+Hb{ z5xp?YH!`?!box#IomMnk@HW%oRU`V1RNVi?_(_=JHXWk`m^vKFuz^SdDh`vwu>v6q~O)L?*U?EAoF>urC(r0z#rrib)o=$;X?K8??&#UOuhr(C{|D4&?_07&(&MOaJ``UM)01r}at;?gyHeKHrSR!32WWlEEw4Xc)b>j)v^?r5{F0C3~wt&7De?r8Uc zQ%Nzlz~)9E2{E^|;VLhn!;-{l}JB;s%_`uStbOyJs^ z*b;%o2A%l%CIPMV5g|@f!NE}6m@9zWK^w~OK+_M=kIicj*Aw#X{`8d)t#FbA?lFU9 zgBINAFp%C8q?QwlV4_C!1mP^TQno(3z!-2#8JFaT^GAjcym%Ta3HZ;`*)zg=8M?N` zxTC}xc8pCS>{BaP5!py!hZ0r;JQp0Rq!1LD>)d+?I*mx207;}H1t4|hF^B|$G!ijU zi$*IRfZ!)szxtDUo09phrjd7_lgPr3k8vKB!sN{#3}`W@93$h7BRWP6xG`Zl%2{=K zYpU2-NdIy7It_cMz^1Uw~Z=c-pK>H||nQ zgEPe06d*~ev4yx6yLV+cO{u*X!hsA0bDAMIHJx zsGS}MAm|3`4`jmDx_)1Ys5XdFI3RCAKT9trz+~a%f{5TH<4#JLT#pd&F`@5%?JHkg zs@?R%{>navLn;23q?bU8z$6!QG=7i{{PK%^lvfe_yic=yESX7zwv6gOO~gJ-cRtBj VDMy$VTq>r})zZI^r(yH>{{Uj)Zr1<+ literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/gradientstrokeblur.png b/lottie/test/goldens/all/Tests/gradientstrokeblur.png new file mode 100644 index 0000000000000000000000000000000000000000..6224cba723056f02397abba4f7fb88aa7d35b0c1 GIT binary patch literal 32654 zcmXtf1ys{-*fyOaCDII}MWh=>w}hagw9+6UBP2$5hjdO#q(r(?5F|$DXxONY9x&qL z|GwY5b9T1<&d&D4eP7RYU-$Kk*4I@hBVi!H!onic)KD?N!oog#cqS1MJY0ESmoo71 zf(WAfCp02d_(l`@F%j4!op(3(o|7=^ELONLp!^o6)k@861%bDLaGaN z*Y}raa#Zldnqapi>z#0{^`l+eCl&&$f@3zQ=SxBF7+P7w@HT8WpLbx&r0^1!tn9FwkeRSKlRDQgy?JBJ>tQlu&6^U-ZUfBR%Wl1T z&2Zg|x<#*oHutX02ps;3+rTegdor5|fFB>2+aA7LA$`|Fzb0~rjWru+2^Ycgx;U(r z2$IJNKov0Fvb$|JSPjFaYz)zag94ZRjMZOpu}r`8aE~=l;2X8CQ`7pjV+;ptc%Vm& z)j==Or8N>u)Q$mt+(CNn*cXc;E|2`zm+dVY7_ zH~YEw4yd9=q6Qzx88c}Ch7s#1QVyL_E#U#P zxX2HnAF#NwIAsZZ#WEqh-R@^Ci^bcYr*%o>-)NFCqK8F)(pe797}+hB7bKz~;v}NN z;dj&!y#@t8#b}qBUP6^DUU0!lg2j zarySw*%0iYP369Pcml8dAKukvL0Q6|;a6#-hcbgiaT0>nK`!HO>Uqi)qe-8?xm1ZJ zATyq}|AKv)kWP~8rbr6ev%_juoMfcyW~2s|r}AA=vl>{BWls;WdET$j`$(KF+y|2| z$JYPZs%`OnQRRduFHuphpxw<#a??*phbnw8Q&P{?j((LK>i41~Ui|am`K1VCBt27e z=jeLieb$PP&^?e|#)=pcTiaE)lCRc?z6|(yfgMFc@rWwU_?~#;I|V+;>p~iQV>VXR zPy?cGN(v-6GJ)Q&gFTq{65XC_5wWp_sjwT@e^=$xit3%7_|EV6>qiex5bN?Mlr|pG zBnD{*x-(0b#xAs2Z}e!=oK5KVvB>8wu);uEMXUR<@)Y~W3c^^UW%At0sKZuhr@t3I z#ee&wTuFzY!BL+Qt7-yQO!v*66#))Ej8#)1#g~E$2fcEt6Zn-7Vc1Z|=6MZ;2Y4>M zZ!4*935022;u`IKB$T%*jcZ~>NpMujIR11ir6Pl!UBrkRcX7u;Pa_gW9a3u>Gka6K z=$-D1o#>CQmC?7ZN2v_o&TzYasHutp5ed|=FW)8nC&}zu*R+gscjNfXzCc7=Vz)7K zt=?JEuK%pbZofuRj-<#dIIQ4dd6zg$ne7jubx*lE$cv)e2J^sGG|!#&l?sCtq6zqo z>v>r93%hBQ_7B5IxR;s9I+WtuW}x(BbYdKM6?`NZJ+sx{3i!Qbc(yo21gG@e6i6Xz z8K+N8#;uquLsTHviTZnj-YHhf-S_3iz_;R_@?IlK_g{N%oxb$pi#?xS3^C}9JBa_# zsiul=YzqAjW$+13C(&4DW9ydu;Pf}E-m@4jTL7DVuTmNDSZA-aBXDF2sth;y6&7X? zpa2L0j2)FJ2b0q5T^7m(1n)|C!ZJ;sdAacI|26phdTvAdt{V^}UX!>UCn4>*y%WHF z3pY8*W2wlgiwKY{PV$N2(zVKNZnL>HI!BYT7L^%WhW$phi`Vw(3u4Fo@78HAO?|I|C%$Ayo#Qx!-1@J>an);rkWZ7 z_i{t}`w3#P8OhgCBWC^t^`6@z_u+rhHb_6bRp*|DI?)lkbrhcPDz-_NjLrY-{MEP8 zm-XX0OghUj9IUs)Pr|jx$jkST#E4B~T{Gr$gX6Zc(P9JCw`Fo-oQKs-H5SLN<(Gd*wSlvc) zc>2WwAwi;FNC*1&10qng-lASf&%C>dGjSESW%!fABh zsEU3G#o_18(%6*Q?gkrHF|v^XOJ@=tFqsP%CYI;724WrvgFviH1)abj%1&a3y!0(7 z3E!GZ2!LG3S@vgM0WL#JS#;_|{ixV^*s7eHUPl!^7Mr3mAFa~&L-11`ykNgiShSG$m21HfIq-88c(R0^z@YDRsd9X8#<$ih)2k7~g*)dvtHzP+HSehq; z*$?RI=;;HSB+>y9qOMO}A-xWdHFplG^;M3^HY z_&q^azCO%waEFEbqgE5~6W7V%E1;jK^6K#!721LiL?9kmX1~%&kvD~rjDLqlCac}ZtK5hWF%VJ2P|I* zSA%h!cUairFkspM9i}H!dD&{)N?wg}@^L<4efS@Wwv@g+I*CuqniH*87K&N^@w-jM zPw~@uekdr1)8dsywX;7CrY08P8OvNMcN$y+Wp7H8tUStp)y)JgD=rtO>oX0>R`wv) zw;t}mQdOifa&nj7wADc=*ZJvq>pcb`G1y$am}v#;vE!CZztLR9-h7U7v9l7o#{{n| zvWVV!)M_r-D9N*YD$*~gM--3KlP#m8opf@kqL;en*2bqlILiA%z^m1^=7ls>v(VA> z&(_j1p2;v_4UIOMkZunBq-UU_!_c@=fG@4iK~Ik!&!n8fUa=?HBviGpZgv{BC2~0-09YJzDZ-1R^f~c7pr4kvP4)He zn4H!7I!K7LKX?>+r2M0^XI)ry+nbp;!}kRZIUAhUo|L#SL>U|FUNM}ZJFqqE?duz6 z!M4F)`Y4O#fe*^^EdHamF(VJT*#82s4A;%!hU@j;S&nYr@^}*ShRsZtSP4ro_%2LM zud58B_k}t!(@7v;c#Wv7wDk_2~ezR&HqGMS=T)S|&267a$nxxy;)PB^6wvqo${fnzF#0Ray0 zAba+-f1d35HI?0S=p+q4jpR7zz%*Ld`QKkm;!5CTzw0$d-t(B5 zyLIg+{QD}R6kcfYh3y50gYn&6UG=|*Jk?i`K@Tlo4r{7c48Gcvd*-d_SA5eCcuhXOFdp#OY-oaT8hWEOVrX+c3&%!yP_4S>~)M&oXSg#b)on{dh%t$muYQVSy zHurB4(uSY+|M9=$3SS%40D1(}*F{Ew544R6i;*=Y3@MI-b}MpmDY1x*lsdNPy*yWMfINtS^Z<6$1_w4+X(bZ~PE>sB5p0+EUyh<)W(Dxn}Fc!3WXqX|u z%38Q&!p{nz$55}m`FZ%t9lt*dB4nfT#q%FGzG-7yM&A`n;Q4KVE>mKQt}j`?;JjDe zdq?3|&O&g9EfwG)GNU;2B{*ww2ORjKyhwoCJ73xd=s9^ht$+Cv=Q>t31H?f8?V>|NSf8Ppu^gN>I|wWf>}QX^n!gHn7UY(3PAZ2P|34H#7)o#Qts-NoNmFs97fHo?*{!SKism zDzdwp?_2E5!@MfVD1UX^@Wvig6T~rV>uu$T0%}uTgGgs>-iGbSh; zmaB)%#x>>rlH2TXs<*C24Hrx12CxfSb6&f|j1=KQ!s*zr{uUy^7qTFGgZz-JJpGN& z+uy6N-R=ONWLHhed7Y(cO&+%@c@7fHDISzSGA<$Tf6nTZR+E9yO?pBmKznTRl_h=E$iEX43PFLrQhOy=2{U93UyLT9fJbW-9HM)a(?y2}3;M>q=#^DxM$ql~#wQ&}^!NpGI-mgPff2I|5hm43_Wi775?AlHa~YJL5Pd<+oaj7A)QP^D z4OEkCxdyYhj!n2Oc3qU#oM$A8?wF{qh0}Aq=ZQBZ<0fG~TnUu&T3LU!H#BzpY|43~ zpl(oZwKZ$Fu^2Z&PW|joWbAxc5ZK|q*_S+?3{tZKR2-6M;?VB>1?#^QHDOI-YH~!q zZ>frQp-O~8m4T;uRR8e)F=s<*=Goq=h@RZ}Xq`Y#S+O2>K(NS>_pE24AW4R6yyU}k zyMljgU;HYG+k+GxMteHx%^miY@Vh^_8{t)7V60t4FH$E2w%uXpY9F&IO!}-Bc`EsJ=ETE`q%d zJ%1zqxP3gUa5jdeUC$c$kXTC2_D#s^Jw6REuYpFu2I1Fb31BIN(cq=$OEjkc=Cnct zL6VFSaK&(puvLzJ6!j1R+%f~E3+tC8{2vp%2GzdqZ22>OgcGKFeg6b-4b9cXCCl^8 z_Pu{uI(_t)UCcvW1TE5yfB$uBnMkuN$>4{nYvAYXFzpR4>6Ob-j0C?g&|~k)Gi!N2 zEn;j4C2gyV9v?l*sgVMz9R-Pqjb5=}!F%w#Kpk*?6-@+_7Wp@bmn5>N0&hs{_zA^j%trx{v=QlNFZXp8V;#w z#!t&{f)LRBiNN8aLCuRu3K4m+G1)O+OQ9OxGLG}NJ-zUrV4i2tp7~ZC(394>CCn|o zTP$1__O0DXxHod;BT_Yz%j3jt7A~-Rm)=Z-49>Hk@M# zk%1LUCE=4EOxe&|URx_5Xz!M*_!8O|?BddKCwr#8&LUV>%?eU!wA!XvAPmX&ru*_6 zP@}j=)1d&&dSJs?nu9A&-==RJ-eFt#64iQTpW^OvMYGwhI<7_3=Yb0`0a#;bm0K9` zJ5u`IQHD94P^zsm-}80#men4Q-zqLEc5jpc>|^#hEu9_`atA7~a^WaBL!w$cv!HtY z=JM#z5`%%r0?^WKhx~XR4#V}Nc-~JdUN7!#xnx0<|9;~ho9CBwj`MFp_gumEgVuZR z+rrg%w&?p{ySAU}xUx7zCWj=|QDyN4f* zG6g#yb*^aeJO`n*r{eshH!P|r**vM~%0xT=Q?>kpIqE?u1mt#N=OiE7}FyFRd9Ec3R+G51NRAw#Q_ zfJf8^vQ_M7gJQxtq;VSLt#bW! z?!PVfdmyPl6nHjV8d#MV2VO`16a(d*HT>GOAQel@jVDuZ0CN){?LBOpQ$Z`m;FEp7!^ zA6))ZLMHlFCAI`E-{a^}`q{@SWW8y=3Tb&QfAosyz4MI4{sD%D$3ViQ2*Ov*oV{ye z*{ozR%t{!1L1ZR>X_EAYt9*HZ&rZ0rWd{^l2^Qwo3+4V17p(XLOX}mCy1<0Kq=jkx z@HLcFCSHg0+w0P=R_5FSIP=FP`{hnWhbvC8#DTs?i|9zlFR>5|QgMPo`FXL>Z7 zZGRv+;otKY%;ZtNtJ=1;z-!B!qG+=}g)idVS3m2g5`)<;Zk}cVoLyI>DDEGj<})LJ z@MEd^nPBI;mLGQQoiBAlgWUU2AG}3-N6R$}>Yq-9$vIYRqsw2K zEUi~(px6T0O(ZEp#8mO4Z*1T7@v#zwhLqA0&FR<}lAAB!i40^^Clm}U3ff?a&Lni! zO1}d(%ELR!xugHZIO()qR#f@WqelvfkWUoUmGzu!q~=?h$(1%h1K|IJJh*S@t8uWF0MceHWOLL+PlE?q|c)6_U?8R+HLb$ zN>+TX>e=G+nxz5X1{a3|5-8-Jc@8FUC&!d!O+}3_%L9orm49=6MPJA;(E9EfJ4Iu* zl3H7ZfLEdAZf#;&lV+x^rr0XBF=lf`$)qOKm}-kK8JgIn;* zPUntbb@{QLVPu`kuMdHDM#eHFxl2@xsh8>blg(EFpQM(|lKxxploThIa~E~!sVQ~f z`%lH+t`V{vUm9FB+A5L=tzWW!P?~pl?9xNp7EHKfefF^7L$>t&hCKOr4CVLkAL zi~!H6%4hntbExVE?j=#`Yo!Oe%oxvI2w^{xQd^5Mr4G?sjIu|B3QtcBn~j?O7aniEB6m@9p^iW%32P~9xxbjqw@~f$H1kHAKm%ba^EA10lB#Z=(?nc@jw zPRzI8ge-Kd4sJ<5O3FIn2ycP^CRGJ7y6w{zJ)l!6rW2_pzpDr2p0{p2`Zn9{(uh;S zdHOV*%ljd5-7|chUL8>NQb`oq5D4vKwR?$zb)FbHKV|p5|5}-#$vAwLS zV*lm(cl8+TU7*FCAwyVy`Y|PI*u3f$%78m<7c;ibnYwG9y^HLyv%U-XS$Z&Ml~|&4 z>HCtdFn08-O!yt+LyJR2r=cOnR9y>0m%XjyBR^%%a}BfXE$gJo|Jj4dqGEjGp{OeM zymd|bv_*UdYSg67brwEvqFl47vKeR|lT_n>qIWf{z3@Oaz3?m~DUp*YK4lOQQX&^D z-uiO0_o;1@vz#1tMS03OE2Q7pR()fL(j6%cRe-U}dCNBn{+%riBY36N=b|7FhE}hh zTn|Chd#QHCkFH%0q9upy;V*glJipG<)>G0HqfRuq#0_|};4I<(nXmW}@E!Z-2tdkF zW=nu9=O|o(`V6$5cr|@%iXtsqP5iFYwyK(k^De2s#(uJ-V9ZYWz&jTaCjR0RG17JkvY@W2eu?jL_Tvlr*Acamoy?3<+tJQ>Gf1=&h zyr6DXTG6$-W?3PuZiq6sXMl)niHA+$rPqt|eBN;(uf(^ZF~1W1e}EG4r&~%Qv14L7 z%?!MS580BayVOr?-!_uL%Oa16MrHNy$MsuOe-IdwcppOqT#8;HNNbBCkkk_5(_@1~ zj4QMEsmSzhs@Z;X4QyU~k`IMxR7zSJL##vgB@cTbqOphYDi;L};iZRjd8uwVyOL@j ztRv9k9)j40d|)4&rw-|N?Wfa^+z_@>tiN2rI{|B3(B&1023mW<;4cAfL{G#ibPEr* z-2u^yI&8xf2CvRF=f>(=`-f|45tmnNR1|Yir#ElDhVpdP2Nma}>8Ya!gf}wK;2qR$ zkd%UI3kD_D*u|Zm6j*%YY9gB$J_N76m=ryuX<4>o`)?P1KwO=T0ez;zbH);Ja+{%O_)EbA?D3vcptQ;I?7F-rYYFUyv%YuND~J222)22Q zOq;z}v@C82pop9vwPaH?A=j~CbRLiPM6hR6E*5}3A6#M$8+`hGUS49D7T%9%o#vsW zL*wY!APyAU)>(TpLMVt+QQozCkylhs=)apNnC0r9=+K%U>#*Sae_jB)Z}+e(*?*Cp zJ*;j_Sy0+f>SSPKl~T{AirekS$=WBckPRdusl{R*R_?CMseagO^i^*dT7{dG3H!77 zgG-`4jCQVdwFP`TJ?u~YsQn`6{RWawtnz-+KTeR6S`23UkjNQ(Z1j46`?GiB8+?O5 zzY?m&PsceKFfG4Iy@aGyM=vLr6rRyr#ds5v@^W4F;|Wg)Czrdi$xf*}dQVk`zvG>D z-JqgMldV&L0X1{VH?`@VP@hgp2#3p)EL}lqSiVCTM;zN8GU6DE49xe+Ve9o_ZUlxa z#q8%eXH(K-UhGQY^eHrLA#Xy1=1JKIDq@83*Fnz8sHnJmy@y-q07uq34rc{cOK>R* zJG!Gk44P>A*DfLI%0Fy*2!Qtpp0#v+&|wIQWYp=H@mVTMNx$rI!z&$TKlyue`^2C? z`-vX+fx`<;zB=-iXC`q;EjeKXedkl?{)FuP#s{h9sd@|Qr24;wwIh>jxTeq?ycitD z6FYTNFtzdDojq8Q#{QzEEMSez#%b)}zx!OFI-Q>+&$<+9i%vJu_z?77VOYuO!11wf z8N@sI3s>qg7YC5_dvZTds_-$WA@P;mzG@BTbZm5XXxnw&x0Pms`f4x|5rGW`wEKR4 zR~8U&rjuXl;=f0%X+3+VfpW~xZAK|o4h?rc?rh*F%rbd3s*M&qUpq_)jYbX40zJa{ z7=9iF6np&*>wMzpgfOJ<7v^gxOL| zS2;7&vH)KmhewKfANZJ0+e~y-U$srm_7+<{bvRBPj$`|E(Vcs{(xPvTQJV@#f6QfI zioIz3J3hkvJH)n^*`2gsDsDM%V5g)@eX<8BD*)!FBL1QWXx04Z_ee+X0Ych?$mPNj zTn%T7r;v(qnp6>+DgqJ6@5Pqm64Gy`g$?wZ&lMW8m(v=n|C%}vxoGF$G{(Ba16a^c zp6NL=hJNd=n9%jRXynCq%YP6VEL|=hv;EV7%L5+cVzw)Kj%)vV;dLgeX`{-5x4&%( zTV-Bq}zeAHQhF!P|jEilJ5lQ2Dp^du%ZD zzew;d6+aE-CwWzz&6@?fGPahgiOCH6Ezs~dCsKbwFT z>d_+zqikM(X)Rp#Oy}%=bOia3XB$`yzFLCwPkOAv5PnMxYpJ?dB(7-+&0ME8m>2PBTq7uMrvSUQjqFWB z_}#Ra>H(S7OVO5sX<3ts;J)f#T=hFT;w_J)sb#c8FJ!TvjI$kaSeX4pF)6P~;rqkG zAObLOKFjnub5(0aRc(GC%M?^*T3o$(;hMDJ3^hk4&n^VOtpb-l$*l7~Bi(=1kxy3$ z+7MNurE&ZT)h{B{656~4b5yhS02SECm=gq;AD3gKR%k7?eGDBf4y-Hyt+6=r8VV`h ziDi!hgdqa`*rI1|UOBE>E&5jJ99*}U7D#_v^|yDVm8&vy*dWs)2vT!G`07f>kuzhN zx*K8S?tKso=>E@S(0`9;m#88-PZ0+M7N_S$OPC)olKa>f7{r!kk?S9xIP$)gn3TH! zx9>}oAY0O(T?0vf4~+i2k8;zLRU5M^ma}URpUX&ywnxtmhO;a3I!Z1 zKZ&JlT1vh1-xKw`byH)P|3YRPtVKBR_Eq)>X?^yzw$mpG*Y}dPUa166v-_PQr_JPB zJ3+%(e*&BMDQ75T$>d72^lZZRdsJH3-B%PSTZRPR$=v7cUmIoHqXYQQ3j-*Hwz(V; z1c@9o8PARctHrU54lmVBMx5dK9Z;f+@>~)r9 z$z`&OABXH$OP#0uTn$9aqBko61X zbF6D9y4&sH{s+1DL8zjs(HZmz4w=Bg*vazDrrzQWQ}M;+eD1x6v@XE z48Ny<5hiQfL(2Vw`f)?T+{@Fmg)Ok6@geqYj~e!xm~T629< z1jDwvk*JsZ&CcFfS{+&PA6&$PRg8WkgyTWjX;o}31$K`47(KV4__kObu|~*nZ7_MO zW}O$Zc?~7cm2$xoKq>1X0sp~PxagUxp!^|=l(S&Mm(?TW4Qi#uOY|JuhWVxb%PnO< zPHRMRmEw2uyv9lB+q;XF^u$O<#466q5Au_d2|oKpU3B^D%Hs?VBgKFCrK7+}L(wxI zHzyJ@i`HfPV#5TMv=?K^x6wX`ZW6$Cl6%t(6#n{p-5(*4Xg8wly;D?n3ALc`VeuWn z>--sky#DNi*d*)plJBsQuiCzZDfQt=NG!Sm8+;?Ipz0yya*hFjXm`}dPX&E_dAkog z@$DbG*f6YL#F`8YH~^A&GyyUr^TCJ;r&SM%{_fJi*x~X!{4sepB?a1!KMb zswl>}sdqXTvvL*YgUDS|M!^I=viP1|8NealQ^ZqX#Pfym|5m-`4*<+^O}+H>54b>t zT<#l(lk0!SLZ~A`o5d;a3E{q{GRg?+Evs}eVuh4K1|7l4$>8`}KYE}V?mt(&B3+>t z9n=M*@Ge5h{Z_Fa#vCRjk;7I2r{#tjknvB(r)Gd{bD4stwlUh8cd0RNqhoPAJ6IEB z$Zy4t`F9{94>&%ED|#l@lsReXXOfWA62RgvoJ%R1>`m^&T>_cw|8d?(8gmLp@Ef~} zojgq$G03xS0BPEm>w+p9#xE$QFfYCWJub?wbyV6;9T3WJ>E8gwqqdX{W!Kk|*0RMm z7XK`rDKr0WBjpo~21{XZRZYJ~gXa*xugQ($z_U2whlB<6F{P9xv^&?gWhtpWA6dZb z&+GZo!GlKDwX_^VGAKAE3}QpV?n3MCyht0ZSEP&0Uj`PGMBTn86aAZY3LV|^Byt7= zTI-l^k003_GEPBtP6`6}!N%$KQWxOdmc>PeuoW3G@bSNO#ZxH#gTRLEHnt6nkR`wU zw{8hMqZo+d&sug;H>^2(ZYllSEcFunP13~KJ;PojYnAh@t^!ki`btoFIEQ=v`J`GO zw>-M8J5&B4vY|Sx!*bu=*sWQiiuNemY9ORfUa+>PQchf^k(+&Q__xryIygBo8y_*2 z437)KUGzBv+uEP_QQU0o6RnvjX;}lro>#wiFRx-H&y5_5%7g`0-IvRBWATkEk7srV zi=I7kkIkM|A3@5+o2Ir1H8~yL=t8qwF?J&ddwN+gQpWA-SI4jdkNUG-kvhiF-11tu zZ5RA0(Um8m{F{V`u>h>ximcTRgqOE`DI~`)`|VM${5R$*s!T>fYOM|+xM$N4`>k7U zTP}Ytik&c#P|PDRxPX%nYe4t$Q*vYdantxf+l2%d!&#{y7c|36;peDa6QcC|7hIPA z0wU123X&`nBLzBR?Q1gUP#*+;KyBEX9bW$f8+U)uxwuF6^Tf#bEe*(-WADy~n5;(* zs>?e(qLy_84GTG=(@C5iB^Fy2pK^$nQ)d#D+{WcEFsoQP4y^8%yMcGj*K+ibkf4_Q z(*1w(!UC|V%t%pKS9J_iBL6q)Cc5%Xxp?qT?JxqB#FG+k6MU+F@v?pe5tx0Z+{*;& z)sFMWpCr7+jtRutv>%fL?6Vc(xRBRlEw1Kv0fgZuSURFX9DgS8J z7_IufrZ8d&#&f?NpLvFUl&kHNFLaV0T%|NSS+qbefr+EN{}viFo=XnA_h)AckUJag z-2bm`d??5@XM~=SCj*qMT`tNrm{}(%rJ`}F1dV;Y+iM`+#Vgq!zrI7UzYJ`xgfujc zEf$Qa%#N%$9I&HOCb@Xwf`*}WHiPfX7#CVQ9Xn+>;_-BtjY;2ho%?d(4 z*?LWCSYGQS%};FsbOy@jUXe-er1&Zrt~wfIJ%f|r8#NQ60v~6t){KGTw_V_DS>%72 z2ge>s^xbr#WY3=BH(k;-6v~qPcaA*}55QefyaS>~K5{y|OAP*CIRu}!>FqdnabkTZ zi0#c@DN)`@`J25=Q%+qx1NEG4o1Oj#Z3|oBpJf3hFKaf~jx}|D$djY88)pKH9J*-8 z6_yhQ_DjdZ&hr=zYlJc4V^mF8Zsc^+B^O27^`?(YEAdBL6T(?zq_|M}Ys)MQeg{%d zGZ#jscB(|r2skC!@z~hmFR=kFJ_FOshos+^=9={yy*luIJq(@ZJq8)-B=W#&$AD)I zGm#o{YC8~N_H19BM^t8(Ovzys|2fYaS~`C1ToAkXYbYkKVq>$G{8Gi3A+F&5uQP()h3XXdy4WVT}po;Ht{f zUqvs_XOMfl&DOd9smm)NH9eW~a#mjDfUzyCF3!{4htJ^(n=MxPjtktUH)^EOS3|MaUtcXcx zOc`Z)1J6Ury68&Se)VQ)l?UW0rY}2TRKAGR%xMgT{pt>6X(0K0Sn#Sm)y-C{Ib=nP zKT>4%z@yA$SaJAYK&&wMvS#}r`RyDw*!z)5(hjL@i|LDzNXMP<{8lx~HZeS8YK!Kr)>xz7 zR=9YTNR}ybI=S_}8Zxdeq)KJj-(ze=SYL`v_R=>Tbjz2<&~M`a&)3ksoMx{oBVX$O zViIb@+<_Vb(L=JLSm(IQJN6q^g9CdS$vVTgr3vGEi61*)iOPxlXznNeF)D2pgso}? zo-bON$8JD~5jWJ>&1o22WL0e_jqSJ(qE6If1%502AKPIT^SBTd0+ z67`JbdK5)7lI1BrjQ@I^Cadm2ct3rYl;2wlhF@bZs5B-1A*!4iCJgJpwW^E$xZdtD z;1(bq>Ax4T)evo_-ei<81RLFY2bn3i(7B!yPnqu*tBbsWBgJRE%0pRD-Gw7jUciiL zLxQJuuovaGLI)r2b6?CAZoP9l=$j;Y&bMIcW?8^5idtTduN}q&86@&MFzqjJ30)JdZQ{~!Ny2%jw5K4IDx|x(sRVa*?RgUv zc2baYwG$uzd9G%Up!dUuOR7oZY67u?O2$nydN{WOoY)Vma!n`S_O+8dopy@cBAaH_ zci1Q{tER_s?M~IM(~>hI!@h4(5g`f_K`|0-4jkDs7qeAE zjDGMZM`~%y5#D|#G%dJR{M%S!0xZm`vop6l0E~9#*zQdOng_jrXACqJ^*Jic9}bjP z@&AKtdY}i2(CTG!Sw17@6&0(RGN;0W(VNQ)o0lVOjH2w-q2r!0+qA5QjV~>QG^=iM zyXNg;AXe$DP*)TCs2PWNNT`&twU*fg;3}sHU?MEGX6P+;+SBe?SJhB6D;xU#(L&gYPO9Uo%S!lkIu5d6!L4QG zv=pX}I09@0LpIM7M?S7@uE?Ype$jL2;C=V4kFB(1{1{@iG7|FDfmXRyVjK5C9Qf(j zeeDA;7hZ(sc9NwtZc99rVD;L+O#e5Wp3jrf(E0qgmhWUIasDI+RrB!V!g<(Ce7Rvw*%mp z20uZwyhhrkjpml7_N~T$w^o>Cqy~2!=FKaW*3RZj+SqIa>H24~fIQtV+-6B@HQG8h z`^Ai3PCPV=8a9mSHCCOD%0o97lh-7>WS?nT-BcCS$$eb8+PLr$Cz1K5aGUm{MP*b? zq`+vY4-QF83HaY>NXTC&+waf~)d(34ly;H*g;hqHOZT_|%e8fum+||0>~{=OCG?e~ z_X{fa82ug%t0QHN1bgMeY5_U=TMb?Dlp{>eFtwH(cb93IXNGeRIFy+POKK2n+s{Rs zd-&0Du~sX{NSEkbjX61eNcxfW1&-A-NT3S2)!cZDPuZd4B&c1y;YPQ}o#Aog@(-^wP-C6?-o;{+ZReSU4GHf#lYfw4733ktm-poUqXFg&((OKf z)6k)a%(K$^^O9`;zX!kP1kNaiezB& zz`$3;xP#jMqCenj?`Q~`zNj$mkCYXkk6)32ynhZ`N> z6aynig4kbN=p}kPe!WH&YqsOb3>NC3kYuB*g`TgF(L^1AadAa+Zug5qC*J!+GxU6R zP02pHJzK)bSkl}Sqvv^%BK@95UPoos=Vdi{zH@2Gh0UpT!wlZGYf$uyG)r|tJ=f&T zWG8Sj#r=D^q2k{hSNmTBS|DgsY3SfcqeY%7Y-s+;&txid`F)9q){{# zEq3;f++X==Dvbu%ZtOwPlW|16!!7D$J+#{ktW~x+p`#zYO~G&QP{&1O!D7vI(X%NM zMJ1Ev-I>$zC?>?LK3{T}&!toz2x-=SEpbKp|!YBPGmZ(Nlp@wv20lPI#@=|P4~GJC7rF}L7akQuj=u`=jQ`+_7T!SARd+(G~9GOxt{f$bIj;a8i}L20&b8gVS#cgL+EkCdltYi(GQ4265Vj^c# z4XqvDyP8+lF24@`5-R$;VRo!95yY@yCSraJcdoDEhleiG1{Il+eKS3AoYQMb&^XPf2~_Rd>18kf z?&pqvw{KjEt7`tp+v}gSA(aCKDy(C@EsOb7hAs<8kM7&w+R!-We(C$q)<5`ggK1uu z%Y6(8)xL-t&b+OVE8T0m*khda+lO`0mDG$13Jwy~YdxE{_yWppA3y5k*^%|}WIOVC zqVrwtFnucc%W|F&4|aX%wdm_4=_N!@Pq8>H`+ltz9h+|#nCF+gw^L1r&!B9bH2zLi zs`6gg%JnV{wF|2tQ5-{D-Q5dTHr5FRrNXcvmEfm;Soz0cm&4e(h2Lv1RsqUuGpwx0 zN0PRdUGZj8qkoC)Y63x%sR@6rkyo|u0Tv{AeHvLrD_mkOwAnA98`RDm`@P&j+THz_ z^fhg^km&K8 z6Xdy>l;n9bh*q-UJn?LQiTR;9tzcO2tb*5_#929;w|(=e@~w27x!D=3pU4n>vV*KXcj!`SIkVehl_Tgp!$!o>1a4%X&HJGR!zPqC7k ze}}D6Wc9Iwh@a%HUtOw-n(=B&j;Y#hTDG8W z2PEjEh)>w)_4IlJv_cUNC3T(eM5v*wF!#PKaxd$7s@8=e+}2W7F0N;K?TN{EqX?e+qEJ#Bq<7ME0(E-^i4Elx`<_=(8yxc_nO^4 z-uuFyqSGRzYMV$zcIzwFbGqcR+)(raSj{pbq8g`GD^IOnhP~rW+=2Z@jNo)5R`ai^ zS$m|+(uEf1b(nZ2NLJ&GUCqIQ46ru86+AE&$#Rl1nD9K)bHZd_-H1-D(L1>fzH;1_ zJ~bLRz9Iwi4+@()u1-#udTx`lME4U0Vwm~uX3FNMJWe0YIx=(_JXatF)>8}%Wb5X=sd8jDp; z?6-rC2$u4HZAJ0p)6+IvmrsIQ#)ZGWT*YNkE-I?N-3$QQs8wh#jo66?yQ$%d7UW2& zys-P`xi2Ol^H57CVBiP0?LK=44tp-PQm5cw7?*FD4vG64YvPie$Q6e@u1T(0nib2l7yor}##le0=jf;xX{cF#z9@&8); z4ydM;>7EkID5q=O`MDGCHcx^xh*(5oOFL+`zJ zkQzb@{Y~`VU-_@M-dk_2r|V1-GUuF`UB11)oy>$=XAzN_RiGZ(m4DiIx$z-~23jK| zDh%G`AAkt!%_z=8%IcOc$hOITFlvvTQ9rjUG;gw0yZ?C7OmiT>`rXrA@FU~~fy`2cHrloR zD9$hH!)b`R^2__J&|qacH?ZRDkZk=~ic!JXG$&2!DD9(?7Mk<>?9kU9&;gWIDeKTt_ppdF!GtYW4R_EZ9V%r#DcxYfy(OO+%s6kiCLsGiuldACGl1WDM z#e#C*Nma|G+Nq_J6J?Y4nTwqC?3jyugAVS3NjrRLmmiVe}=$#a!3x1{HsnR z^TlaPZoXiM4j>&WM_;Nj3klna{wrLwV;CPtcLHOQqJ6O_o$gK>iMWy6v720Xq{q@V ztA$#uJ3vtHU==M*loX@x#}2Y^YwY!kca5UMh3@a%aO@tI^wJG0G)xw=%R=lLM1Kt& z6Dv`p&JuHUTQ?@0>mJMRu6#a;My|s<`$giPnVu`d=#j0vtj88O2SaJsvvVoq@6W@- zMD9t%Ont91HvH+x{6WNy?f6=J5d=**q)U{HvrjI5y;=Oy!71t6WFMVHM;VwEAK3rl zhx^oWuMN!2VyHdObOcvUs67=<-MxU=1 zC-_$i3|fp=ev)0)O592IZ(F=^tqPJ+x_Z{_AdZLImTLBnwYr0-WjBx6ebb#wHJ=~O zH!QT~akyoVAMQ}fr7uW1dw_giLS8|^^S&HEnaGQ)bR;Tqqug9v+}jbKA|H8BGM1GT zJ3V)@dG-^3M?xxKiloMEfV@c-myRFlvT5nHoGi(58x=_qWh|rjTmA|$aiMyp)Iffk zlyb^qApzT&GQ~v8%UWpu>Orhj`*^g$bbCV83e7tmk3GnfJp-U`2iHZk+$xN&F8INs{hc z<(9$dq#{j&r%{!c%eQj+SS2O9`m#;44;Q=lJA-cu6*ZOgbO-lm->{njgmF9H#y#rn zdy-cA@SPtL_v#;f8-=+7rx01^&*-CTd z*rKmsdECip@A5%&n~Vc;+_C6f-y@#}UGH^SF{&|Lj#eST>+hSa*3VrGr}=5}y?)>X zK5dCeE_B}t7Z)Du>qMH41&h|CpFQ;{dx#8~pFbGeYKgi#e@3NVo1@7mlb7}f#c>Bc zp^D+k*m?3(@=sjpd@mst3*UaFVCnuVHKJiK)zQZ#$#@-0(t)mfXf5&(WV|LbfbpNAk2XeT? z1Fn6!H-u7zR@N!x8MM5Z?<&C};oIXpxtjFI@UBKj2WeglOV7vij>!nEj%-BUr@da+ zc@-s5jk=EqGm@9tPFQ$Wqq~(??0*P{Huz@@k$GOW6;_jjT6o_6tb9A+%K5%yYVUX- z$tw9Txlw+Vr=B)@hrP7RI2k87LD$9cCF_=U*1W45zzfzSlGh;m`XN|R2fqEw{JFw$vliG1oX`%b`JM^Zi;n%?;&Z~(x#1daAXU&IO&U|ORPTESI zM4GA)$Rzd`V<D|%z zcL~P1Rf~IzQ&jKX?~OWZyf_(j7I!)+i~elC!a4@kP9zMpBcf{d7U16{7sV^5Tg{&B z&9~mJnh9SHqi}e}a@`%t%sKls|sh0-06Q}d3 zuV>(1EWgle+O6=NbgGokSHq|@H-|TE?n&F16!IY@Y@}`moNh8|=i;J3`d(+bo8`V$ ziBE{1`k~OkhjkvGycv7{vaLlgi{>4V(_O}7u2z)Je*PDA&`I-W#5~T~ojxma)?ws% zSMP1`O(gzZo41`97ItV^XROq(z7pS!tYx&hdOUl9G!-0H!@GhYs}or+HvD)$se!|+ z{DPFKUc=)!iDhop8<`uFUQF*b`lE!Z&F_D<9O_Lao4xP!$%))uo9 zu<1BWc@j zvQo3RM;)RUm)JZ{eC<~bVpVX`jDe<9?1_86>jO3=MJ!*0`w^!IMfk98#ib{xeBWva z^{dfah?`ux-bFs2zReY11Y50K>8|~Hmrt~Qx<;eF6GOFg!+xUBYPaZB322rFE~C&fl2(WQ%pJoQtxtmc&$3}#e}C&W*a`kM+>v9&eBNS2p_#s({+l2d zZ>rI0m86{_8@9PMC?vGZ<7-A<6{%*N2fBrtCtmP28?>iVH7Rjaw9 z8e;YnTRyJJG(4Iu2s6W~c8mYG@~vWCin}4RMi@P@Mgbq?y_>Zj_1fx8)<95`q54n* z!Ocz6uTWPwoS~)FwZpKCxT8q6(%QLF%FXue3X{iLW@d>=C8kGKj~;Arw_Qs^e}ARa zd%^R`mxCat_Z?3Tv>tSebF_ZC;fM~p*eh*QXdB4XtnD!n`~2i%H=gZVJk8pC%5I^p z3x{!%s~eW;$w3@^2QG+UB9BT*KA1CJpyOvSKgo?uy^Uw_9bWC>8_`S` z!`0~NBRy%SgWj_pD)`VNK00coIbRM#f<_dij3r_a;HJ8_t!|tmR+I4n}lxV{gL!|A7wh*XAGfS3^D8RGY{@sQ)fKqkSzZ56jk zw=VORsQ1dwQ2}#C0IThitmPYdn^`@BQ|4=?chvF4Yl>S+)e#Bw&US}ISJS%VY!%|ZR3(zkng5W z$JCbddC<36WeaO&AwOg}#{GP{yUv-vs^G)B`|Rr~U1z^mQEBIPp0ny# z(M*Ak&d$04wuG!#rk(3byCoMOXP;pGk69%fVMMLv~gny<~on)(q^#cD9xc&dt3d5-57+8TW(9ue8gFr7zx!JQpgR zT>5yWYnqSTlgUP6hBB#M_;BDVzJu<_DP4LJ!M-Ljr4jG26#}W4@n!XxqVi1<WA?LCv`*!UQppjHqDS>M1O|^OX7@>r!{>9Sih}++t~UT% zVIVfdUzScn4%0odj=QaMOm587aPmMzw?4&7VPF2)?Q9SECc-*)PQ*(PV{77S;@WyE z5*y<3LFSgRqA$%>a=jG14Er0cl#s7UfF#GBoF>kB-f3)1Gcb@(kurr$+qX?tc32)1Vw4%=zSX0rH92+?dX&R@e=~8$Z<>+SB5Hb!vJ| zK)WdIo7ay7slu@sL5yM(Y!`$4)67U5)$whWLEb-c-|ZUyNcZRrIqzu|o`S>O8$0IZ zHh*D^7Mk%o{-X%f2t=uj-N_)ULAr+^?c2DXYKTbr${g7qTlL*!nda8Qtx8?a16T_z zNDvY%2<}4is0AsMj98}W^oe<$^a=W*H!00oTbsCW^&WhJz3VD_$&a9Qa~c!Zt+ntu zk>BTJOkHV#MRZ0{8wca4+huAew!yI_Q=9c}T>|V$C>w=S5|{PIy`?dldR<(2c(hA6 z5^9bM|FMD!6FZ@K%kKt}8h#Wf-rwYhEshnQO$W z+=^6Y*X7j6DezzC!ld#>-uaAtM;H0-%(`~U#UJawBF~qFja2n?Ie|r51qfms9f9H_ zn(%|?y6Ug5(eBn-ZPw|-zS1MM4r`o(v&@zbnXF^x!u$j=v|)2b%kB8V9k?ZUz+HbAZ9gePJ}_1^B2%K7zcw+oPbc#%H>n;zL5HDS8A1g z=Yx6@`w^ZNMOX`xI8Zk~u6&tNDp$caM)3?UakeZOW8VvS*Od<}T}so`7)eN6TF~ng|_iU(c0^qrzbX&!%tIik9|nHZyN!-ULEZj08qq z7dA&%p%IC_!Gx$|SMW&Vq8>lBZ4vf5g3Hk2t0QqqJPC10Jc)qi;LGSP=XGJ5NUXQ> zVD@*zBaA|%@{@ns+L8$D$Gf)nd9z+l&>FBQ-x)FV^i`L{L266+Ptb+#wy?RdxjdSD z8K){!rax_n5XP?Q_EUIuSLijHPEYYtj@wI3_|8VW1n3a*Mi7IX8p69|-L>V|dH49^ z6q)2cvvA9d&cENM<+_>aLL=Y$6&dH!Ku?RF{NX$i0}quQmu;z&kHo&00-`v)%g~5- z!HKF*E;l3J_2yVYXPaPH53o;+g6EqDZ=Y5uT5#xc_5f9!)#beRLzi=Nxe*`z(-iOG zur%O9U2}WlP*d)`CvON4_ZNeUFVrIY z+qkc_shq*7O61B+&*utav}cd==&6WCy}aQ#x3Tzajctlf(!;5y`{t1n-er-;UzZcB z5Q*irJJG@9T)`;M+97fc!+1yQAM~>)cK2J$WLQOFbAgT-|8&fICFm+BR)%mS?@!^{ z&5^&&O!P#WY|%u^9=iU5;Y&on1x{-=&J0A=jrI~2!lb_|SfLds$YmYzEik`DPENZMma-1!aBSW_HsQgVnlH1!$p}*i()PA` zykWPJ&K0{2P710>EEwETED69KlHVc`%|1POu!Tv@E}l1f?OXKBr2MwPnk?&)0-i9i z_i;`HTIO+U$%EeRB%t?%7nOLN=kHfp$Bg`5ws7&GyTLx!mZ$J>zYBl?{GI2nBp`XN zdq>2=Jpvp*XusD>n->qcH8tUTJ4MhnZ4eYr>O?9^c>Vw;EWcKE0MW3IC!?VC5po%`b>z>#aMeY{Z+fhWw zn?J{mv&lIZIb^Gq?OCA7n4)#g@|!Kli}^AIB@8FY=Qb(;NSoiK6+z>Uq4B!^xs~CoH}TP zz3D7r9Ip-B#>AODouoRgLJ!f8cBib&l5sb2y%l!g?*qccC}NrbKbmPVU);>q{V*-w zAo?@ysdICV??01X??LGMb|y}ROL=n7<+}K3{M7;r`JZo+xe@|)GcOmA{O!}k=>qk* z&?$H*WiQE02hXJ2`+LaG9@`2M52CdB6%1nN79`;Uq?b1|VO=KdcR63cvjj0Lz;0Nm z!htJc-z%R<=s{El`6Zw=G4;C}cYaXXok%bdk4lXb;>BH|jm&IfX0Gfsf4dD1J-fl< z3;JVg|2O?l;G5J2WUdLTza{vO6yKfSZ#hVFX=zTtMC}3-3*y^gXq6`p>tsLP*<6^osUBZ2@B!x4PF+WsrV$rm@lKyc!We&B>jF$JTr`S|1Gmy zh=!_nrSZZwiBOqtl%_7H2=FAbbG$(AA(t?WG8rBf0ZrfzngTA#?F2kLixGu%P3ujV zqazBScJ~)lSYdGjOND3sZ`~5dbA-o(oIPf~(SqFBw0cWKoe1J!Dlszo5Hwpwb<}G$lmFJhU4=v= z_>lA2-jqou=x7ST)L@GfnD{X;aWWv-S48199>F{{ZQ6VUb#L0V6#+BmD>`LK!BT!4 z*Muyfvx!tDFY~anv*rPad4GYX2`OqNgh`Dax3gyep&j7sAR`9?_8G&wVu&=ViYw!L5#q9Bhr<57jE{3XC zl58TwV`WOw;M#`A8Mk)WN3q%`(Sws&M5t1Tqypw8RS_*?%H2Xncyxq3m)wC4poJdp z!Oy!d9Vjm+K0T(G1^EPonFxRXeg&@C+Sj?u`Rlg6u{2aA_^ohesZ#oS!620#`G1Hx zbS_UcGI|thRB5ZuaF>LEm*&ur^kPNTmHabe2DVcSYpA+FjZ&~xU*#lgsS`7_5vKl3 zm-9u(3BQSJn(Rp`0RNpsVsIbc6!z9w%(}qQE^HrKH-j3 z9#!RAndWMdadFFz*No=6Hl!q%EaZZ}zG|R|7)S6&5;QBrWR5q@MIZfk5fOlx{nJ-k zkk%g#B2$a`jGnN3EM^?18{d4GU{C%Zp2V)kDWWhj%xfpXpypo+@s&laVTJ{H=JPxnkz1?kahi6>`=A&E&gsID^2Bfaz9Ep`NalJb^gr{y( z#OOs!m2{4pV9NqDHt$@etK~H47KDJb2qc5~GM)eqE3;)niX~dsQVVIapQTQVqbS!I z*o@FU4d;NJ_903RyT-X&kSCVF&XBv7rc;Y}oqUNFSS!!jIG?E135{zsD#w8ngC+;I z8-e0Zn>c;jDbY0)Hb%G<&ymq&Ho>pD@!PFLF{Et`Suyl6Jcex81Oqe<*@nwjX&4-|othJvsofFwO770Iq-G#9eo(4(61YzHuwSm1t`OD;+Xx-t{@lpCwb9u7)GN*vH zekcRraRg)}BV4*c%UrpbMJ0|} z%A)E~n{tKR+#SU(-{f2@RM)zsDM>BR8$|5?m1LIX6mWTZof7VSQ{j=_cBj(M>W6J_ZE&ORRrwuw5|Es$R#K`$*31x<~pn zr8eOuK7d+;MC6|)qz8dgNIc-mnsbJJvyNxeC33G*9j;i(!P;jebM>u5uzFCZ3bvmjf7_f&ou}SS?IqliFhd z96g)V8A6pax0s)8KdWUM+hVW1BINrf_-@OD2Symj9EC0P%?Gnl$#h${d=2UmBD%Zd z16$cgAxDZUT#bF+0r7`sd!o7@Uu9@iTn)a5y7lzAYZ}I@K!zP43bA%^a~IRLme*7? zk?gS&rei98Xx7mTWBDcZv~ro#`i~X^8}R`k68>`B!EwymeyG2G$I(ip*6zVnyy}hA z-S}%cR!5iaW`SrK^1CXLmkl1%h+5^2)%p2jNS1%GCmy zZh({A`7%~xpyRliHF)6sbiKhk_#xc)o3ai!OUB-VQwBV`P z!2!A&?W%)xx^6Ab7a)9;svuHH#}qy#4R_EaDMHur^<_Siolx5I=Im1fNedB>TmU9| z?=}I}K5Z7QxQJmSuX&oJe^oPwp8Rfbkx;2-6#L{YzIaBi=d>fVqJry3bD#)_J2&!> z`RmC85YfK;(-MmD(cuCwg(77-*I=brgtU`CX;e@UW9rq$t(j-vC5a~C1S$(_10ahd zwzXYz4}{9hTc{*h>E~%#ag-&gDzd-h`M)TE%u`O`2!ZT6_l>urC@$rb>F57Wh=I6C z>nShTa0kRVS~2A4q$EQscGskPsPeJpW<<2r(FDQ6C-KE8P}*_-bQ-1SY8AHcxauS0 zI!nMX1*uZ!UQ@Mw=dAJ#=m0=&94IAbiMJr#fm(V7?{Z@99lbu!UAh=&a7Kkbl(&1~ z+$XN>_>5-Ysy>1k6C%I`MLxB62YKz~X6s*y&>vmJ3WMEL^x{?LqfL1!TrRQe5UXHm zfc8WX3mQOL4FjuCO#56VU2*H)X6Nng$l_n(@3D%2GzWszj#!PHTHg8pU&YusDRItj zv);VMN-?MQG0mp@;N)bsSe*eYzUJQ;_%(n@nB?@^j+myx7nef2MU-xEKPY?!%@Z~Y zGj-WitnxK56WYo#_`WVJ>{DgXz;15IxoCK9%dpttn%nRTN%&_ghuALVykB<+a_;rs zhq#H$RBij61iQ#Ug0R-e?Yv}U2t+R%vU3U@(3>_{$1tm`%?1mFIuCncTvIy2X7$!Y z@a!WelZzdE1KTbL_f0mVOJ5tlP&B|pa8p$sAmD_YfIR?vW`*n z@wsCmr>K-Ia|e02U$wGCBSiU7feXRDLDO~5T?M7cOfYOsT+6)^aYE?<`Ro;a7K(cL z*Crh~>O421JF`{!JWjq>+g+s+9zj>h+DN6Vr1O}!eassjKn5+~LUhZyn*>~xliqvK zG}7;4$yIV|B0Uq``!o!*NVk5TaGn%iEAM{mei(-PJ8JgHzGKM6nCoI$vhl5^TgB{h zA11Ka0A~0{E`)>EVJ8JXb>X$V#zl_jnO&J#cY^Q8It^6f=%`Q}h)()4X?l8Ufm-*c&Bvb0wENV-a2iyQock>KUh+F9eCpPRa=v`AP??!u<=UZ) zij#`WxMUha=WS^?N@(#To(KB1WB1v@+XQuG=AN#Ceu#A{yh2}I$6E=_g&5^RP~KQd zz3VPG&nAT!g?e8K%eYK|l6PM`_2=U6Xu)nEfZP{yfXbE>yD#| z`r|&8Ubg3Ol#3UHuMuMUVGl>TH}xt0P^VSgp*PL0`=0vebKov=?u#k$hnch9`e<4c zqg2y>MAj98Q59Ouyz?t1K31FKj~Z?hl}Yge*ZvR$Zi_M>q{72! z|22};Ub&_JAuH()x_;7xf>~`6;)KJr6z8Q46jIi2_6cS1+P=1cDjDC$hSR6p?n{_ zLB$C7KBzl`s#fN~0i!`B`L!!jKrQb5hp`Z?@RNp#rKZ`FA<-YhqTg5#k|yqVVz1)l zeGl(b5r>C4-G7ug5K>=pQ~0?7vFquyGY+d0(U6;yb)wQk_8{x_wf{8{tu@I{Hhx+R{pWQRnMb+`Ru``i9p4}F3vtqrE>HJCXM7v$E|=}>Uo%JK z<*3l|E-*5q2-^r|+|R6gkB;u!FO@Bk{1n+$^PZD6Y{zKNWs#x}ekcpkS*DRP7Y5tCb`m2M$lQCtxjA~1mQYHR{MkmxWyXCu z_iBGP>8rwKr*CDOZm0?3-%oAX##!O$fN>I`KybjngF?^Zv(Jmdh-Ro%*D$=RIpM`~ z4=lx$1Z8`-ik$&CqPYH_7 ztBVI#Q$=(&W_0iRsFA!XD3z%hGD0*teA0&+{tOJSII183)9qAPqC7mP{5sAGD^_c< z^_&Vv$AoZjv&ND@@dxCj(CGv6)!a4ph&lH3O-p!11{x% zXEId>dKvWlQ9ha@Z98tgxD@c1&BHhC<6@$0&)a|icXXwX|Ng{~$^{xI&X$?L!de?}*05#9-n(oRXx{MWm4M1rvn`}3YT9dyS>D0kfTy~D}q95d>P)dbEJvengtN!?nq zA44$fihZZ}(YHD*hAwxLPpF{hCdt5zX;Fo%igxJ|B99!32NK2N_svdYoD`K0lrRNH zhx%UhuD{~9w7WrmKmu*V@NgmEGhYmw_L3dbOAXyG#rM|FkyM5+vtR9{lE!%*-X~(U zS`%jQ&2xn%k`%|VD^+_Mf9YiwLUEH!~8ml2x%=6Txr zaE9x(-!sq;%_PVmH-Ov18+adgE$7;z%@huH$V>{>9VX};J{y8ee_ z4Av`QH+N$CcWzm_r9`n~*~_6Q92u0M8aoEGVS^w{n%z8pMk{ObIf?&`g=Qu6a<)A= zbk_?)g{v8VME|={+vsv7r?tNEyw{;%9k=bwp=ULKaLP?7Kqo_;)cFoD39Eh~I}ssH zYE(p&O2rbD;^^3R^;gaV z0i&cN8?f7K-#2t1QTFQNCdYjCZYOM&YR!^wFc&9h;5bsKSG7M^8OkAnPfE#8!yl}e z4h*`46ufAk-2N<6)a*%&=(pBD{no(#`IzGvn00HIew$bEyxh}G6`T2Z&eo6}Qw_+x z7igt7<<`5PpHI}JBg;<2Qzx{L`-Kb@!l+x=trvVQ284i+Up@D5AOqv*$%vmsKi#Uy zi#(8cl^+nzfwts=Y?*`1_Ni1Fs!=m!L*Hu61xE)#`I12ss<9?AgaB;l0)?zY{Uh?g z1!~zzxKl`%5DNEGZHyA`GL!z23|g_FS>grx>5@(Jy_dgsD6F^GI01%APaWzEn_)pC z3bSAu1RNP$sT!a(ce#g^TbE!1wwFRrv(}~AOZ|1Lz3=1WuBNZQO!~L#zAjol+A;{S zKcD}@!QjK5iy!16h~3{&Afego42RCpyf#-xl`uoU*&>t&yBZuEMEtB8Mf|Eo^e&YD zu!By7)4)L@OKzPrN`?1{OP^IId=JI=4YFyqIgi!UD&F2Sp5cBlHd z0bgish#X%qHJHU(S^Yx4+_4rxNRfs$@jN@(Z6lhNc-Kh5G0|^}bEw&<=0{Vn0a^r1{ zNG)rAGGD=`o-rr0%UY!fUw9tT;jf*7z7UzLvt%Po)|KV9=E@6rXF$`GbSz)5B|>E~ z?rygpA+Tk>5X7Vp9f1%;3$0j91A&6h{z`*wxVGXXr;)ntg-r$KtQpK01Wxe6$W7Kk z35HZ~Qx!ddcIT%|HIf!wb+O9I%$rdjMxLD@bj#vwq5lc3$}6fsBhl7r?~%S@4>!+0 zVW~EgCPWj&3DK1B{Gw$Fl!@iQJ0_HNQEscFuOm7E7pQ-5n-qSGN)xwFQ`bC+?x$&X z44JHh0F+n(7AlPs(Qtr*oJI0B3+s=h)$z;%)R&h$aTta^}XkzOi1yY~2OrkDB2 zWR1Vj-}$6r5|X-=o97y3$I)9$shG#FzrPUArR1?)!HJN-jg707=izN6(3pc8b#~}i zf=98#VYM(U;zu-wf|O@nb5??K;y*F~I!-e9ywPTu+pou$=>10TRefDFmiivueljEv zMPXcD0tJ)8D?ofKE!S&4@jnF>9kK22T)$a=g}cMe{;V!TF29^Q|ISpxIUk5YC^V3N z$LmnVtPF0KGuM7AM9kw>fNTcsUgQ3IMIymy1=$ku&98IWI)biE+w9NZ^nNJqux%{H zZJ?zIuTK4*{UV-DdQRVg-04%q#p93WNT=UU#IZ_t&>&U&m!tk9k`<`z{VIKp|0kzF zrZw2koM87^8~4R1+;Z!i<88HF^ulx8?w4pX>oziuRxi%h$aAI|<$>sT>Kgqwq}mo! zSwNr(pxB$LQa=~l1_>56iwQWnUZls!CKWRMu2;?uoy)waNKU|!@6q-Bq@KmbJ2A~G zK6Y0bpW}peuJ)%~CNwz0JFbrh})q|*1*&-_;^&1;a@Ol?3r>r=%!lFMzo z#R)sF`Hk|)A zC50r?NM%$sQY~-Fnw6)R^#H(*F}MqrONA#)f$<~3lTheOKu8-%Y1o6~fP0)2HxGo&U9}a!D=NA&IeQ!AHP9N#N zPK|ih`6b6o(5m3ArsM0A<~oV&H&- zs>a`9v&o>;r22>9q;NpNC`MdEa?jyDek0Z~{!|!nWl2|}pS)O*RDduo)=?Er$T0!F z4~!OBeG0wUh8dmcT%F|eM2TgI9u+Vzt<>6FD@&>OmzF{SUVdI75aR4Wz$M2YE;M(sah%%fd3dj zn)RV|fzX3x7D!z2IYrm1Qus5z$<--RVrZpU3ISV%re)u#m)z7FU|1T zTZw@msm;?~`onNbtCDH%gnhkp6iAz5VKSdY4^^CmvCk^=Mi7W@3aqMw*Tng@K4`MJ} zlRlYQhty?B{!ZR`Gjo<)#fux#GyX3Pyg(2}Qse9B5Do`tPy|w_BJh(=o5gOJELI-Z zCl^wfCp|m}v)*?~vE*X?w>xv+ZT;XD@+)qt*H`RTe`kZ!mX-APyTu6Y;^fq^p7xi& z3@2V#mTbL*6c$MjYph(+Bx{mvpa2Y;7!3cDcBir!bfU?!zO?YW4%}~a-5AQ2hkk|W z|4q2@ir(pj{}bQN{t*2{RT1t!pYYQgU=3C;6q+SC^#6@**SW%KSE-lp#@Ev=(iO!~t*mp{xmv_QhH6}AAV&qPGx$0|MTE_oM6MeDvZvKQ*xOX- zcXG%R-m24od~gx3gmEf8x1Qj%<8^LF4&tQj=9aW-H4(F>+4``<>%Y17IU)gnP!BJT z%p2cmD8+B6Y5*SOb`+i(+*r<-!zd|?n*s%aRGo5M@|Q6tRDI>gOD1kNZ6zPI#{de@TVFED-UL%R2NDIPm_uki5fZ||MsT=Fo3Jro4Vx*o9}G3W`=xUt7y zra4*~JmggRoc&i{g1Pm@dk4=Z&>cqo0+}&4&+MyE!dc|pN3F^BNTEx3ALP|tD{+a& zKDiW|=aVu{?Gh0O0hI7tpnmUphzrpwgUIgHr; zr%cx>v*76DUP3F?s(#+!?D-W(RtZ-o>~8MWw9Ib$AS)BNQ6+A#b0LK#>po_uAzP-H z!i}X7$Lp7jjXbAB-W)@Tm2WU-aa>n1q$y&$UZ-nF-=p7QDe;obFfGR_n{4}zXwQ|k zw2b#4L#RIw_|99;LqbrF_oW5@{)lPsy@!YDh2pbP$~42Q^fPf{g`>MQ$yM+XC8T8%Nh{<6(qS2yxy!#qWPN dI&U#2RPzFU2q#mLaT4(F&h2}*vK0)y{};BOap?d6 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/gradientwithvaryingopacitystops.png b/lottie/test/goldens/all/Tests/gradientwithvaryingopacitystops.png new file mode 100644 index 0000000000000000000000000000000000000000..3796d166ad9ea937bed3ef930dca7da1f4c3d723 GIT binary patch literal 1514 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3ZfpvP=Rd?~N@=CKr^pOs{L4({ka~ z?E9MoGO9Iy2v%vywRmMNI(S5Fw_#!VqT7cTIV}umdYke6`)-@V+|2(E^PIOaey;+w ziUM$8QI_iM)1SRQzuTIB_g0+erYj{vlXCL)*RQ|7bIP4;bJ?f&A02zX=wH>_Gg7A< zCq0~AzI*MrPgzs7)Ya2BPknjvb31?i43oLpfotmvpC8K#Tw8j{Gj{&@H1Dtf7SG>r zn`L!QWJzE7L3muz!2 z(Joqh|LyYKxBTmqmG54y+x53@Qqc!~zyAv|Uc_9eF{+PFcE~@Kpu1QlG*tER60b=g zcf1Vg&Q6Uxb!PtZQ+_jjCV8J-78UV%rHy8n(&uKC(z(|zeOkS2^WN;!zU&X2zm^%* z+pbjCmEFtPeqL?n*6xq*@-DqjHIY*F{C0iWzJ=xwo<2-5iJZBv?>PI*DXGgQd#cS$ ztGXg*IyYC)H-3)Y>nmT6eSBfzS~zQ$op0>*%2K;u_upoI=$g`Z~s2rzV$l=7)^I>+}b(s_I7LEbVdpi->BBn g5E!@+__6*kCl~AC0MjCdogi0uy85}Sb4q9e08!3}Hvj+t literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/hd.png b/lottie/test/goldens/all/Tests/hd.png new file mode 100644 index 0000000000000000000000000000000000000000..ef528bf04a2ac46d0ba01ec50e4dcb16a261fec3 GIT binary patch literal 2595 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3Zf%B}Vi(^Q|oVRxj^Mn&cS}&USO>I(DFu(F;iXPplPrVpcpmAuxLI3g_|9!IgS>f_#d)2Ob*RG7e{C@Vn%>J)$ zE_T~iZFJY?{&wShT}k}=S5fo-KV298dg;CJtJl$0 zdFc8*8Kf5I)SCtT@jIb*5Ol34?qFZxZdmR`KQT&&(><+S&OYXXm-eOLJwqT+b{L+x@b@q#T#68`z` z|F<%K>+1g5ag(#c@8|zpW_xY3yZ*NqN9FeBY-C4EOgOlEf=1IAww!=1#8I*eofV9x wu^Xf17)E(b-9$K=#zxZ^W}9Gyrm_Dgzopr07RsZr~m)} literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/heart.png b/lottie/test/goldens/all/Tests/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..9672355ca0b8ef3e3c8351ab9a99a4d8631ac440 GIT binary patch literal 11970 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

SO)g8Q9BS&7PTD*3KOKLX<{oA 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

TI%5+GLgb_iCR$$Q0h)R_ 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 PUyrP$l0?0jap?a6Kz_90 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/interpolatorloopback.png b/lottie/test/goldens/all/Tests/interpolatorloopback.png new file mode 100644 index 0000000000000000000000000000000000000000..4ed83945036ddc6b42ba2d4d6dd03b9d93e0ac4c GIT binary patch literal 1218 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc%h#&GB?`45^s&_Uiur(}fZTK0g2XO-Rj|S3*Z^t(Q;EKbA?8lMOp1eExO( zmS<`9bkX?8KBwjEt$AG=5+~laP`X&>Gu=#Pui4AmlY8SXKX;$^WUs9t&=vx~VC7}Y z`YrF+j;-3o%<#iLb>+HicMr^HuS3LQyn5`e!lYAS($a;y z-+}x%*uaY5f4?r|tv8uov?XlOoLN?LD)(-`w|D0TD~1I3y66{zf@`mRnz&SJp6ij1 zxy!w3&U8rcJ^0wYn~#NIS$59%9UDLX^8S5fVf6id@BUAic(&t)xS*u!ugIsbo}Xn7 zzqe=a{o8+I2Ah{hn0syZ?kjz2@8gV^i?NMCwwRfC@N7~wB~PW z+UAtFO=lP%+@Dzg%i?B~-RxeAaJNDorCAdVdnTRt{`&acuV0tH@1D&$WCQz+qCMk} W13~gt-JPr;Pk6fexvX#gqNY_1D1;Z%S7hQuU-#8M!z#Zfxp|mWnsC( z0(z)wtFwLzxwO%UA@2ldEyWCsw=0)AnGk>H`hmZ;#q>g zk!1W6a~fqbvbcqUFA*o0kM0;tNQ1Hr*74eCt1FLe*msDW+20nnx6g2(DFIAWiJW=S}A^lxw`-V`M)ZG+-FMw<^%HU z%mKa@d3o;0FWLbU^hQ@gaW!v)A1f$z?73&)w%Nhrhd?d88L!6qUbcjaq;^jvBJbuZ z%gcyb(~Mpxqly)OK}lcHsDfx`jtKp&$1n@jj$haCJhIyVuU^$_*D8sdU{Y(~3#bJ` zZ^j^ZCJpeh*`^L6#^ud&U){86&`VLl=xF{_t|Fg6v2z2rVk)lTS?H4X#6VR}*2(*) z#8vS6>=n19Di^q9CK3U{paQ$h97^~Hiu#B)6i{QG053a_nw&Q)!5axKOsp@S?4HHy z0^<(+DT-XD6S{5I)%y70`cf-}fQOy>ljWxJAm@SY2!8M)yZp_HB#XEw+I7#eAM9#ZV}YlEYza|; zYe6XAbkChuPyJT#;EAVap7ia3*kVT1J=38gn`Swp(V$0ifbmMUErR=WyDK~gqBIK? z!~sa3y4VtCkmsj;+d~b-6{?kNe#O}qgvKpa9F7_}z7wj4Cgp)O z21!(cBB|=yncy$xKC$@5@p9~3Ov+eRhT*jNlTCWKnkt*fV6{f(nrv!Pq{0kP1qW__ z-$Uy0gU-G~!37QHFgq!5lGqy@A=ri^Kch;d-RBW?_eq% z2b}r^?Ps|dA2V6W?gH+M8t!sWl>oJp8$knPtncU&xn_<>up%j3e5Lf+_|cSnF}zVe zCp+sTw+%6+q43S&f;G2|l77WGUFX}g=My$OO+wRRq>Cj|9pF)lwtvb~NwWtF4Rx8V z=n31w;SE$bx#YoCN~!$f-UzJ;Rw6M}nYMlnOt8;Tva4tURy6rk0FQR7Euss?QVIZN zL)+-$ew2(n2ezfaWZgEsf6u6r&r@V}2U+JgdYmkYG+o<1mqz~fwEKE+5_a8wVY*2K32^1@H4njcy{_@$YfrO zgLZL8Dsaf_A1Vyw?C^Q3Y(Q_ zK4zYTJ~z-_HrkQZWB|=b#wLeuVZ%#spzB|Eekv?$^_}UB!?Cwsb&e0K&TtaSU2SE z6Yb@LUW=$L5pV5OP2lCDJ<|$_W=Zqo?bMi5c;_&_x*pNuz#~C={Hb29OFleV(Ze7! zB4eH1y51*^bXnW_yefm_Tq3z=#q>+`k7v0Qq&=K<7~N`jJ1z7Z);||1$m_~QI^JBX zqEsx}hH^fK-m{JmOT9Pl6VXBPl{>9)TU8vohY?B|tMgfIwu+)8$*({x3Fx}()IOV9 z6VQ{s?S%%lLq#>$KX-xogh~qwIX{Q}#kFg+9V>B8NZLF(;EiMob&Rc)zm`Sv5ikIc z8uOi)vDr&8E_FD}djOtP(}hYV33KRfYt#=H{phiYx_UF?l5TdD^l_^Tf6BH?!1!J3 z_|u3AhT+TT&7QAPOn-TPFhVF8e5M<%;!fqNnI3ZpMvAtS5-J7&y3m@IPRqixfxuKi z5fL}ytfx(A*ccHcHr%3R6#}iREZWZaH8~8P$WR`cNjx&Yb=d#vnMoqAsej$`I(+8i zT!;nCykg$H+cs4!(oxp;brMctCun!h;g1d|4sKT0eeyO;yzgN4?J%faVmWSf?3uM5 z&}4Ra)kD;G^1Ly0H)MpJ+e;cakv5VPs3)pr+$&gIE`1R7VA>=6L&i>#Tj<%3i+hPR z2#w-HNz7*Rm$XhDWrO_}1&)h*192H5Fe%gxd=Pk?fGgr-Yeq9egs^}?>qH7YvsF9j z7hToPw`ERy7zrpv9tFRQtMJLl^r$$`^hqjOxK6CzQ3Z%B?gg`klqd@&g+;P8&l~Fd z>G|QQYn%ljLDA)Kw4Y#RH??E7C!g?Li*4F7d3hM02s^X%kr}`)t`YV&+%DB#pRBGY zX2Rbha+|G`e*yRyM6f}Y53Qr@bmF{kOG27H?s3LsXDt*Z$sK%fqT{|UK)QiRE_E(3 z0+|Ka+Hz@3#V7*pGhw0xnn5_h`%2JzI+;&aH=BAkkG?7N^%%K!l$L7F?$tol=N9_hF?DXx8~XPRB0>Qi;_peBoWhJsU9O) z>q7@c(5beM7$_i8x_@XifS33+dq)0^+f@!x%{y`+tgCG90{)~%bXVoxg;0=f zhPZPex`0tBN26q7){*pmYjUefgKi6W^{yYe{#KpbL1JYfO~TAPb0iD0dUn~KrUE7! z3`&VfGr%Z->4>v@B3uk7Hp)-c(D$bLQ`c4bOT<4`V^5c*661f{sstGGqNjoPJV?t} z&4{6akZD*$9#qg0T9Mzz-%v49hm~>k9F_d7*%9Da_JPD|Vy6FSmpyYx2rlb%)xzkQ z1MKfxX4#)y-W7Zt&=gDwOc!3SL^_HOmKNwpHr|%>_g5zGQ(~hYUpjOY;W@1kR%@3r zkl?NQ{OHINnNMJy2$Tj&&CohRVMYLUcQ11yOo&5yA$oa$8BNSKoreJL|ICj(%eeP7 zx3X6*KaHa8*f4xTF@rT?R;Geda(&#_8ebmT z;TYPf^q4>DjR{6_D(gB=o9^0(I#1;8xr7)t@|S5SIgvLLR|xxY4z)Yrf=Co7>JMK|!^l4WSwFGCjG!AzIm$k8Od%ap(15bx*hXK4F0({m}(E zqy#^F;a<%R>Q2O-W>C?Cb#5yMg2&@N&6pQIWW7PDa$iviHrZLWk0iuDuJZK&V_a6U z9XvmJPi2hDya&NwankM%XmPW1?GfmOUb?fQBvB0kHov3GV8)ua7wy}|YQsB{f;v1@ zMs_Qd_oZ2gl)gpiCXZ2eyMs`=QB?c$aB;e=VRd z9zq3ic_$2v`>$$+xK;~a&O6wyWtO1JD(SH|H9hTYhxf`>OP3*To5su-8yY@XBD-@ zWs)9nd9Mdvn*(jH#Fh^6U#EQl!M%^azjDtodZef38n58w*0ShO_$f>h8)qbMRzKUK z+Cpy)9)_?tW%hIhZN(p!TevaAI=u!~yMh^`Ly{q%L@R%hzRoego#89F#PgB+Pi3vV zPA*Y*YVo^{;XuD$lt&e~_V~q6q;$JdY_iPiy|L*466#HQ>C*MXY2v1=ByfxUbQ8t{ z)3Wr#yCDybRP5IXoJ>q{7~K-B4FQ>79jFyJNbs4bJKcGu%@MpO38S)l4Ck{4>3TH& zIL$$T%u$uI0XC8c;CSJ;3%5 zX)-{T?gnO@YQrs6A1nbh(Ck;KIbXitYTAyAtnZ3Am{(c7w$S?T1g|^^A@lU8Tv1rt<4L=Lblr98}f1k{Ierx5#HmVs=S@HNb!}vH^= zMcoMNk$Az10Dq2LTI;DBzm-}b+-*EP|4nAGK}~7L#4fc&m8Y&$V?>YxelhQeweQD6 zkAxd36$H#=W+JiSh`OqOo)}@x??mvQ8jZD7LFJuPxSc;HO!{aPKmRf=_UkY(!LE@M zq-PcUAiHMjda!_5bX{RF&l%ZP#Q1fUQ8lJYUUblM=o_gQXaX0$c?g=$yWaAFwgEtF zX*0a{iYeA)0V9+=5a=Hj+O)qhq;XGa`R&u$PEJsOY7-A0vIg996n z`d)oy)34VUG2_`w)>#3Nb{%-c*G|`uoqh3E8|%3vb2L#E)uSZ#_MV#z-|_e44?di! zhv`KHXC5C@WC8bT0-@nGXLL0;zL4%I5Bs^wOm$3j#)_uOG-uIb(r7Q!J)`!dvRnw^4Q-i|6aVdrj@*$i3dcp?PEi#?hRlkudrtXnNHs?W)M_9KT;_03dqJOB$R|s zBmLob#NJh5HnX@TM)kiP)JraSda#uMzr4f+cH`SmRhPx#T?%uAB!QCymny56@I>0C zWQ1?cCFAze^4UNYUM8rrk;b3X7l$ZWYnBQBd0)_r z1eiOisC11ign*!NVnCbh6zwq-ejUC}mR%ZFUy$Xg9J*GC!|x!lc0bYx!M^x?mFUXF z0v@J@-NT)+0L{$A2DUyZtJ*GxIuu|jF^lY)%^PDXb*%;I=7btAW0)!`FHHc08uOl5 zVP0XLNc;IaTg6p^LO{D^z9jj>h92Oxgnn7aeH|ps7G7vfGmmeub2iwC52gc!SwFY+G#i(nk(ZZ$sc#6kW#Nt=ZW&6;9*L}!!4uQDh z?;6VOT(A1etDe(7OKx5;?tziw^Q^w(42-C1yrWQy%(2!vQ8Cj+bs^G$>&+-W6=x_t7&9 z$xJ%6rKKwiAV0K0hq_<&!Lz%i;mk_tJ|}?ei}WF$*s2nd$no5Ek8b_1No83_hSQSvQqDRfR!DLo&4plfxev z(Kgg6Cf$<;`x$vw-a<5RnlFi(jUq*zrKaw)*YO6$5n3Bvx64`;zam~l0#mj3{s1e< zbM0@*nhUYkjDNU6nVW2I9n{c%)8RS3;U?1E78p~Iryr!cWUf50(zRfnJb4GiW(WJ0 zqjKTFr&!DV4*eb_>y3&qi^|PLpR{Nffh}XN<9*sy1Pat#ASyo!95MD#k8io973#t7 zO}@3Jcv?a6hJtM7S__kBCua;GnA~buw5cs2SPxMz!P=xQx4$s}Yzfdc(QUWZJARsr zCtaT3@UyNwY@V7k*^ydU4gBM}#9RhhY8&c}7_pH8Zs8qn4gNuxdQ( zcsi<*nZ39WpSZHWae)lkY&IBP+N3bbiPcCH+yZB3W;+mAGX;q|7ZeLndcKt^EX?aK zgnP;~514nKJhCz|yb|qErK$O&N@RI#xXkaH&+=zKot-PRJV+A|T|yI&2e_<{2FEP- z1_Z>njO4LG|4~rv|#7_pgqvj^0?6@k@Ue*RxB-_~6bEE}VSxGcPoP zDQvkYc58pH;XC0)mhTql+D<%Aa=3QRK~23(z~23Iz{RzTYmqB(QXU{3C1idjvQSWJ zYUQ0=M^R6&tnJ(ET@8l(|+UMCTdVrkgF5@{8;wdZAP@7{!m&E&0d|w6% zYW@DK23bFxtyoTrETMa9Q&_}Q_dP)Gl`>?t%;HjWvi5KV*!y|gIa?9d(+UR9l4K8! z28wSj`oMlqT~1n7LYsrfS5zfa)_L#Y#~|1;o4Ql{`l60-L>W$TDtscPmu#94B;=d~ zs@yp@@F?$=;rRNn_8MbJQ9S|-#A&M=t#WCqtrxgZ-=N$ zlz!GoSfg7c|45sfNFOuj-4Z-J*ziG5IqSHpOgLcuK-moTWH!jZ<9C5SHtPJxC@|f0 z>uu*q>l`lxu?$;EO3p~yoX>3{$&_7`IEDwrQWQ-r*he?ADrL@C(b2mO$Gk4llHl>xX=7?4BRqmtPG3K>cT?zO~yc(DxGgw|c#s8gK`g zROV{uI-o{a^SQsV0%7my*@&;`n6BaBH?e#^xhOk*AIux}#19xt(7*{nHK6NKVz+D` zU5lChzIh3gxa;H6tm$Q^FsTEMA&yj_7Gc*+3d=F>)#=ywAK@TMj3IO9*5{EUzZDO3 zaW-e&y(b(@8I=~a-Sn=q}BAdWiYuS|YBULsQBNhy& z95XWTFGZ9Gv)v^-INJ&^XU?+uG*yw&RPN5mo6u~kQ@$h(!%+t;*Z7g)<(EZ&cKD^f z9Q&xAH`92tsB{GBP&w>eC=xt!vfGgu6?o-mhcEmRo0DE6^J44DAi2>mn8Oc^bN2!~ z%56yRIP>Iz&mR{=?u$MiJi%hz?MBX4_+-BG&hXR!Y=!MT$IraM65!;^d3I(Q>gD#x z@CUl3;R>dbiATDDJS^?%s%$0i!VyB`z2wFzwG%8lS41x%HklO!^UW75_wyId@C(+| zcC9?z^$_G?_|zAvyWx>dllZ3^tIoC1qyJfidlg6kgv^6^JD+ zlQBmdo=8@fm)2&oBf@BzLTl5Rjh~F*e0!MUu@7@mEKh%#{MfG&G@!sRsP7CJs&`Cp z@uQLGp@x*IpmIsGmi}3jZe^Az0C;l{2&DyoBeMz7CZ?gZc~4~FaCu9+{!QPscSL1S zri5=p<)Z5DGXWEvZ<5z<;twr@ghzGIi(x3$T?|I%aSIWlxd@~7gJ4R z1E&k#c%~b88OU41%A1VJ>S~_S(v{T$rsoQ_tY0M3jO#nS#KtOj2YPBJElDO~=;-UT zDW<&#ugfW#5{6EEON6sr2&PWW@mf@U1;Cb|kx3K0$oi`zXrXkGVkcIh6hcl*KF!(O zI#l@zaSKUF8S^^+TGvMjtm?RZ7OSh(1AJ?Xb}DXSn5xwHC&@2D_tN6rCHsn4E_Wor z6PcT5DCHfl`QZ-^Y~4f?mA?at@umi6EC@B7s@`Cg6bE!@Pt;iXuA}*II zhV7JOy ze-A>X$jEXW?x&%~G2sf7H4T+|$*+99B*U)e!5QaZ#pc|0gQU#$LbJ>#-{y7L=h&qV zh3zTwP=$>dPb5c?5!aqb4fBP?5>H;O9P5FQ-gzP&#ggRP8NUygTF~vglwBRP2?`st z-9U*w=)GBCIEL{#PYBiIs9T6AoU;8zWa72hYAG+wz2|I`>TrGB@=cclECo0{>3;0M8b zi4{`;-ybc;isRmQzP`Cyy7Wvto^HP5ru`tkl%sD2 z=~NFbR)HLX#c@+CEPwv~^DKZhbZgLs`zkW2U~eH#T(-v8ji1t2RVV+4{VmS-nqx*_ zK#JsQ4tCc%^;~oT;+Ihbe?5C?qQoFwY z?fsK}%ApJ|qohf+xSQ>>ojB4(6EI=u7GQ_Xl4MqUYZ`;8gP0O2FK2KnM$|p{ONO`x z9Jg!$@DspNWE|SN7YGN+w8*rLH#Sku*ScH)xCo`{{7bvvHV~`jEB-Y*^d=i_FLE$E zC3Eq3hC5mrW9s%K(q!>*Lhxk~8-SU_vbYy5!LT-MNvY(I06T5;a%|VDX8&e9tVB`A zMZ|YfNLGDUQrzNGvxsjOWM)->AIi5Vr68Jmtb01hk6A{^O(w-@*1gxPGx7qYh^=xU zwuMlcCM6V0^XDDX>?+_AN=**>7A-G@(Y4dDADXYL>{v^B-?{qLX!3@SXi<@$8FTD^ zhKsI>E+4A9`_?Bu&pe>l(aL|u;rzAh>{DOZ<6@*oGTwu!PJ}DSA?U1&K7U!2C_xUQ zSw*;kbiImnEv6{lF&P}WL4Rja)0tg*Z)l#pFsMIK>o-1|G7(4V|IsgtoRHKQ`7I!- z&oa%`T59t8zvIx|w84_EaKY$+q1I#Vy!w?i2g&zxGb`A_A2k_uA_PGaWCLYOs{E5% z5qU3sXZ#@`_W@wyuVw}hbg_n|i1l8EN~0RJU1+7KmeSsqueD1n6~Y31-mA`l;hq}^ z=Q6~TylYF_VWRom0*HG^R#Y;eWtOb7lBK3EJt7#_d}mBq^v?i0_P-jm8)&+t0phTA zD_prBfN@X|c5- z|EQV1Gpo3X@;ytokdoBPJm0=kKQrE9x%M_H7%9>=Pe>(W)(>9X>DuFesYyaPMW zTKWLu$oG$0s9o1q{xBK}5M$y|2pNSt}8ZIRjDU*Kfw=J06)yv?wJudFg5nUpo*d$9wlZ&%9?2 zSg{amf<1e&``*MCfObBHYVR3*+@E36L9Fe8*gwK6OHQfv`$VO-%um-WLxS%q=LJ=d z?w|_rjrEKzct*T3BApXxyyKafGA&n|9Cr(*#}?@LK0S-h@N~S18_Lk5%s=-4+*Ad` zQ7)6;z7tzbX)dz9G0fiTU8e8xx2%f~mF^f1E>Sj~>laPdJtlZtGsIbWTP#yyInK)# z#1Ied%77a0C z1ykI6U=GyVyfnrzdSOr_b)``+RiTNI+BtU{K+E3SPP~3b%@ec#d7MpIs@7+sFQW$e zum(rspDQ|wY#_GU_AfjnM!e|F4UV-AGynt{&8}FxJMUrmdsaFp2@;btGtc~Lea2h( z*Byl)0MzPBCiF!#6wU6$?iM{JClG3au!l%fD5k)3bjdN1Nehq;2qh-6Jgi7v7S%WV?ZNP$2@hQHB{ ze^h$?G=9e3<1)=j)LPr?xY(i+NO+;S_#$)tUGze{CbXvVM^O#4#%o(1-E5&+$lMY~ z=lJgHShCV@F2GLxDCgr&+4QdNpU-}KNOXgUfgNRSrG|Ejym1+tbrsp#aq}zr&qMMK z=VG*WhdCLQF>-BpK7?j3Q8e;eb>X@+&E(|zyvld=+V4ydS0Q{csuy? z;r&ySmA5HJg8d7`_p8_{nZf3EKzW$WjO0LqG@d|jx=TL^)-3I<;}H*sz0{pH4~(p2+b!alQ^ciCk$qC=$BKT3+qTXXZjrP|JAtIV zz&|vojcL}_y}_5)C!4l2CTX^OV+W83oI{d55b2`EjGN49v03W|k2$MnllDI4%{-PF zS|45jkfx!E@oTr1s1RrPR^Z1Vs?+dtAp67}3^;UAg8)YJl@4 zSps#gRUuK<*UnuylKWx3+60IUZH7#we)(8$YbCsPa)m7-r zC!XBd4@eDzjJfkSs#$7#HG(%0n{#tdgWMpFPJq4(&9j?@`S0j`mcf@_&D#_@8`xBv6kS>7;7&1I+^`}@%nDynF z8+!uIS7&j0lXX;b@r%&R;-tx>YPSiZvUXfdl4g%maJjnm^w`CUguJ8z?`Sjs=e3GW zZl)_+o+FT@wa24{yy7biPK7WfEjOBZ%UGx{Y&2JhHpktwp|*5czur!ebFVZ{NhBxB z*2a8j)eF4af|{5$EwT3hLCJ7G>T9TjFj>7JKjW~&);@9r9%Lff~Q5$r$ zhYjr>qD0L%wry(JvjkZA?Qw*St=J>dBWGK}t_wOoJ0!3|w;F0vvA&^w*q|tdc1c zf6~C^ndN;~jqUcMo&)6x>iQi)LQ6s0ra0CAzny=4YEj$2yW0a~9%e0_lF~AfJp#Rh z+P|-iaL6y zX>6a3*Clc$Gix2XIpIMwc&^$5Yj7)?pv2-xyl>FVipW3w+Bkz9(WA;{? zpm<&)n8o-lboIXA$H6LxNZL0g*X1V)Sq)R> zY4e>o;Dvbyacdg;LjX{k9R*D}Tb|Ubtu$Klw=-qpP($4SyXGv+Uj(B8RD)Plz1*6Y zanmjSKTM-tz@B{NKQPg?xK8Pga0w0Rw|N0QGNKGL0w_=YamNDaVxVm<{qW6MXtU;UL|1_sP5h zCwl%HcKk}jwC}$N)wOu}XFtBfd0h#WN+VK3?e{20o}dCFlF6l=Z#;jsB$xi{UaW|A ziJ$JQe+~ zzzMtGMn$M)EgzO zyW&zJ2%>%UZLhMv#yKtLc1>$~MfLYTM;53J8N|y>K<|KkIBe2Ea8&;Xc>ffaZatg! z%+2CwWu!e{&LDB|Mp2K@aQ_3-qf#R#_57z*y^<)dx)818kMW+xThrm4wBdf?u)B8& z6YZ-t5B`p`KVLoqkRq}wk*+j#bTyWF4xm8a?RGk?BpV5-eTZG`rmOgE#cwt~OBVMJ z)w@W3DSG)I?8~GN6T*bvB;%m$V2qKz@&2&Ou*W*pYIm95vK63rxaXt1XVle0 ziL(F99rKUO{-zM}6a6N1O@Py+hVux5hT*a}_H|x+SCHbBchqv-a?gRduXbKy0C=4? z;#0BW80Z zP38igzxkW={iWYgBrai)c;9xRXA{M#Q?Q=S!BUWJ^HV?GMaOm8ZuF9xDH8C7RZYmj zx9gCEL2v%c24{X+40D)p z#J0zcCZmlyOM;_&smG*iig|jn{XdE&j{Be~#Lj$_M;A>XlF}kb<|@^VhrOE6Bw#m| zZO~@o|Fs2KWG|05$Ys)oacv@85NQ2+Im2&veNsWpi~XX|>Ho6B-s|y^^S_xBMyUl4 zyL99FlZ@a|0$Yi-xTy-~_39%nnXe`Pu;8B#NayXVpz)pM;+uTD;(W>7tN|BfzFGC;T92^f6YC{`mxL_fz6uwDlLPUUsuzN`BzU|4HWEiJqp1Nf+!lGpxURhM-5Y^YRGU z%~5!%8|bXC+OWCrpElPj=6;`58eE8Un+%&1=m~PP0f54Crt=-(9$S!%0sz3kq6`4c zhYyt7bf z>MHl3?+pV4)^R<4QVS0O6x>fK))0G~@GB0!1KG1K`u*#R_-0D?8sxm|pI3yYWcr9@$daX9Es(cvlvWaE2q$6kG7i;k z%s}CV{HKDWoR*JudUs!cda+@a`~y40XLy{}1C!c$gAc7*;sv6gukez^%0G@`(wI<) z?AM%Yc@DEURR9>CwTSE++Mbtfs=KARyb_udd8SM63j{!y!N`lRudnX^zxhIJlI#%~ z@@X8rAfria@~a2-X|04E&d*TZOHbaMmbc_%Z~n(tCW-iJH2Yh}vy#VI$Qzj)q!6U` z`6Eby^>9% zefPfB{8aTBTk8UMv(D4#rDZ~8YSVWL|KwK(8!)8nqcc2FkxEmxC6hz=>J1lHsYaH< z$eqiuvdw&Yw(gou{^3dfLmtk{qC3}adfA1X55tLgj7Ylg;h%7niUwVLY*7x!Wx6{Q zERdysmaV{l=9`+3Q|^}VI(#v>p?Vl6RDZ3$ZOrECEk$5m;_5qUo8?WUD6C9dPW+n{ zuE||%6R~0SwaqBvpfdb?ysUV~`e)5v%sr7gETPSyb70V}sRJk+TOr6;N!knwFz96^ zx1QbE_#%@WwjFT}u+_quqxXaM$QV;ecpu?JI>GlHB?eSlGYVX###bFQTZ1OHV`Tx` zE8xKAf@aH?JG%@50k|}aaE+OLiRD0{a?$evt;O7|yG>EMV1d7KlF*!m|U^sPu{LZ7##X|R<`WeaB zaq=j!Ssl@Y!n3f0LltOtqbTRD4Rv}gZGLxmI*bYvGxL*JkKkN3v!MthU3I$EdDn&nNTedMLJhVu_+}TwGyQjTF}TNC?Q#+aHX$wCJ(RUyp;Vu_(i1t?z+_886TShS~}m!+|f% zJ=&W;8%3B=jUL;dn`U3@n0Wc^&XyBTGPQP9mlSdUZpSE4sY&H4Mm97%zjWm&6FZ=Z z>X^G0iMy-Z)vp9EQNvFZK}Tp3n0FHElXtGDQ^t#$S1J6JY!2camHs?)0ra*iBYHe7 z-6=oMTw`#_)}pid2D{CD1`5kBe!ov%J3 z!ks`0LX^3KAUrV|^y3s9vW={} z5MC4jvMYR{SVd3J*~e0z!LkLTirsM$q=OkcI7lJ$&P9bO|46X%-~zwKJ?j}Nkm_>` z8|3#sO$OkxnAhz2v!e=EP~%L)cMHKKF#iptKG?+=3dqz7nL*H_y9DZ)H`*8bqgvkC z;iW*rra+N^p{|V|whOo&E?*=z>Sqb|k0ze;vEUrZo}6*(-Xv3$%Oe|-kQa6EE>?iT z8W!FufKHHj3yFpt{h)*)Pw&LEa!r2&@E3LpdnRzse5%e z5r7M^V6I1?&j5JNNo~c%dTYjLx)v^Zx`rE4h`nPmam3V3ZcI^ad+q4^>0}DKH0o-( zr+?RsjfkMW3567l_}Rn>qz|qxBw>}*iespr;TMYdW=yV`&lR+Zk=aiClOsO+A$Gz+ z$cW+v<3meiKEnmS&6fHK>n(8pQmO=0Ug8O`LrrfV-04qvB;os0FX8r1SV%$Bl^JeA z?cn9FYW?nN6?`cIcx|>f4r%!X*&`-mk<~o6%Ox5dSKFOVS5FoY4pc^hlQ>3gzh$~v zH>y4yII|k7(@At^*DRQ;3+xFxpKBK&>UfU4A*Yv7GtJ4ekf4an=~N;tj7tG<);-#S z1g7EBz?&*9Coqj1SD3Pc7mWyK^fi>HV$N`?pqaJD#>c+> zGzC^}gHIj*cxXnaSMWnA?eo{lWtFRZF_GCl72T@6dqSye-@fY8g*tMN`DgBm`5t0i z|BR9JWDihgil(ePrgr)jJUK75n|YY_G3nDc)!qWzSzJWf;(bvX(W}Yx+ZpG)7V#sa zsXv1$K*38zfQZfe4~I= z!d22*#%GoT*+RpDPnw=(h^8RCp6iV2-q7j2bU9_|+3V$sQ{=3vE3!bP>FJ(<=26Fr zlrxjOI{_gDNYAg;`DIsdbAO!874~23yiF~hQxRd%gkhGHcRn^{xRPplSJtZ@JPBgk z-zGzqfk0m=C=BMiuN)OigJ|4yorn=EXfJgew4~1)8!B8gio&D;MVRay+V|)iDZP z?)+Y(VWI8nQRkT54+}|Zp|kfRGYy>m?LYe?mJ^+JB5mrQT99Obu5_i*;c+wmLAm+& zB6E=oZ?9fA^P9j4b+s)}h*NG(wSF8P*GkmT~4k>2PT_jkYuI zPmG#JKVPt_H58Kl+ zK%DVhM^Bi$)Z9lYbYZDxlOc2${o8Ef|cFMB$aPWQ#C}b(*#*pA`$@3mK z``FVvKe=H#y>a|{d(|jc@nu24SHFYDi@60R)y{`mRuGXYQc`vF5*AC}NN@R8n z{S3e48FO38$0)Z+qCKxGi4fP(Aq_1_#neT*m(idN>TrX7ebD2_;CH@f_&m+T#EEunSY zC#C!C+!^>s7G=*5v+fS+`XUmz4$H(ru?s^5M!kTb~9-Vae=v z@0baFSVT&IAHk0T(}_4_H^IYH6uG^0&(g*r1$kQTUW}R?qWppiqzsg$fyJOAuWK{y z93qr>NwviVY7DZk>Y|o&e1i5A5?cmusnvszjt90!{#qHTegys7CeD0K>f0PbHg_OX z|EaXw%VG{Ui?Lk_TmEjrS}v*l>J&36_<&)8;tBJ$v6$0ne{0!HF8_9Qf<2`p7?j8X z%o>iiM^i%S%-Bqq`!;ix;-Eltyw7xi-jiIb(;wB)8teS9Qe4#uf=}Li9+0P{({AX@ z#Y$~-^!oVx=pS`L7=NNK016M`C>2}(Q3QcyM-I(1^e)mL5A)$quvjB?y5vBK=*#W2r;F9^GI!Q~Hb@0*KoJT0O(2W)z_x)l;g6JE=CC@{x@`sduj45%w=p$K4I%& zd40Dt^HAQzGwL%S`9Aac5_6Z3gDvyL1#e&LO>D3(DVu+1&n5|M{X3q|?VOjE>}9tAPc}^` z<&B1~wQ!&k$UTmI{b&aS{xTR>1pgkJ@oxzDVGvd{V9I&D?w~06halh^=1Z|cO5!gH zTAm_noJ^h##DuT>CMYPBsj}Qey=j1|bt?&eo5nrHfxh2!Z1PJ>oys2A6QLzPp88%6 zhF3h#)^VG@8=XJdpzSxsb1|{&CTrFV3{hyjq#P3Q-nl(3UFsO(XLiYlRaHKnFEaN& zav=&2Ie|p)-5Y)L#-2twr2CD}n|bi@P~+=rF-}mazHbQ9iV`Z=U4s+Ud7yJOC^4M( ziwmmDC@hUjHQenvHak;#`Sop9CSu@J=~5>x=lL2(vm;-^yb+O))_2S6?M97QNuZM1 znpl=n66?y7R}t-6is$Dr^o+;xG`A9-y8EqXJCs#QLh>REK%H)Vs}niI#TuSt#<(@` zW^jKayZ4eYo9H3rB^df^lEi#-AGVk)wVyUc%nvQ8_(7EMTdP!8Ex#zFspzh%ULl=y z=(vJPc0cuF2~Py6YLb}lK9b^ITuF#7?eLKRRS!BD+_Ny585M=R@$&V;gRmQ8E1&aDPC#%t&;|H9v=x55ej@! zkMYIZgkL&OzWlKd)s8}gO(ES?42X_m!I=9cD^jFK9cot2m~-mW!7f27TVi)5u>){q zd%W)iSPoHYNX`DT3i(aC`ubSheNa=DIVUP!MZy4$gkRSCmxn5UiwplZl*gaE0Ql|K zyMrv1|E+v#t3hxAu3ncf7$U}s(N?w^Cc>H>|5dOJ_xn4B?2`BZz*Qlqe?IOebYD{; zL_tq;o?V4@ycl~bW)~Av>SvZjmhO&|cYFtCL%HMcrIRFl-O?THvQY+LNDVRT3X_$2 zzTg061!!B^eD?qF+(z;=ISnMPRBbn>kpTjYyZIi!Ugv15Zh?Jk)0s9%bPx!aV;dAU zoqqMt{}$$?Bht6VO0AV#G8q2JGh`!=01nAO~tQ?1zu?a>nvz{%pY$-c6sZ zYu1~Zon9+Xbk|y4=hVXeHNcv6B^(4O@5vM2J7c9o0unX}R69rL4&qWtXKuR{-g`1= zy+U{nMFIzz=$%{eP~)nkA|$Kp_N?;_O+s__%sux_w?e1IeHBR(Si9sbO;IM>rOq)p z(L!xmfQI(mBfVo>CdU-`9=>Q!K01BeVpMaPBkbqpF-%;gUmKv&5pWjeMZ8^mVLIgd zKP$)61l+{p``cy(uG{EtYv)Z!G;(=r}GTlYA%($pfa-cj?3#{)U#TnmrNX; zofTCk(%us~pTIP!U2-mRmI4_m0W^o6W{-gPRF^8E#Ki&Z+rD5q;CD`k0KkR+=(W@z c1+m9d)bG+D%q}PkzV`wQbWE?*X}QGw7cDigUjP6A literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/kona_splash_animation.png b/lottie/test/goldens/all/Tests/kona_splash_animation.png new file mode 100644 index 0000000000000000000000000000000000000000..01522d4d1208f65d3d8f6baeb9a45f0ba4c481b6 GIT binary patch literal 38527 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 AKL7v# literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/laugh4.png b/lottie/test/goldens/all/Tests/laugh4.png new file mode 100644 index 0000000000000000000000000000000000000000..6397a9558fdd2c4c5e1be5632b120c19e2237761 GIT binary patch literal 32756 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 E0PY~{1ONa4 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_0.png b/lottie/test/goldens/all/Tests/layerblend_0.png new file mode 100644 index 0000000000000000000000000000000000000000..3ea02f96a706f0cd742862eb7d22396318363319 GIT binary patch literal 9680 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_1.png b/lottie/test/goldens/all/Tests/layerblend_1.png new file mode 100644 index 0000000000000000000000000000000000000000..52eee814d7b75b65c505093f7757d83effa22d47 GIT binary patch literal 9180 zcmeHNdpy(q9{+jh2_vTnn z4FG^F+T08S0AgIhGez=e!8h2_)F#1;SSSXC1d7}KIxhGi5sE}RN(vq^k|!?%z;*y_ zcEk~P>vO+bQd-xx<}d8b?BoB$S^$Z5Rt9B7PPv8q(qEtRvS3ke?hX9QJH}3HnZ0Vf zH!0lVd;9)ooplc_@2_vpmax8_27BaU@l#e#;A#6CcjGV{6{6%Lydon;4%A@FS;VLP zJy9deBT=*?#};13?1qho0h*luy&3dB^NQMgMSG}R5R;gi0ZJ% zs5TF((&1x4Yc~}x@zU`cj38z3KzM!4yu03s^!SArxIJF>>j)ebRW*HljG(gfRqOC6 z#zioYj`A2qe85PE&O0;E-%}@SDXY zvI^+mj^sie?m2Vn!Wgx)4x5wnaAoz56Ro8`HJ*lh&sq&Glb*Rvdk`H|>5lytM4E}~ zm|C^APn~^ucc+>r=TP25#tP%A0w;BmlQ!5&d3Gyf+MtKdK9R-d9z6!;tHjQUxxVFD zkkg?@h)c0a?US9_7-hkX3Va66N?IawBUpii^n!vOzS^?S$%tmF_{?Sai&A;p^Ou|H z%zS&xI55{<^n**v4vz6V`?VUKX}F496h#aSs=n3ed_d8*Bhryp%W-1hx~M9gv>E`c z`yII+$N{ip0H9!M!~TbU&ae8GJN)R2B}NhMr;TVAkNA7mj=V;Z8-mVw&F8k!;H5@j zH(MgGV?_;C2l1wO0*Slm?jKMwoUq|qwoATmILft9X)`ZLZ|`h;_HWFtsKjd`S2yuI zskU9p>FxxV#nFiIzAD3omnLZK%?wOvVQz5X+x&o-6F8*dK?w&@jV%Y^I$U&aJ|(los5 zs!P$^`QxsJqn+8t6-<%;jd|-~{Fl9~@&wvGkLNRF`otNNt=&#_8Kde%Q&F9K5iK>$ z_HC5%!#ddqvR2*fLlt;8aIxXxD-@olD3u12_5(zd5DR=rXG3h&{ku7;jp1cgRZ;%7 zU>A16hh4{bFxE9|*7|0LzJdEXCY!ov*;#`jmY~ypxwl~aWCAOH$2dnWOWWsDr>tkZ zC}l~}X+hL(ee-tyL7qY?V^?uu{|)@*Aux<;)Pmxo_SmKD5GA6t44n9uXr>7<# zWe$3R&p}lxF82JIuTg=KY;_=|$cUPZYf1{yRFqQ3+Q!DLZ}ma6@KU15**1u0PRS(oDA}iA zZs_arX=kVj@8^|*_ZtU)PIxGtD9WiY5`2=B$Au?EWi}dt-2FrFDz5}#S0L%rt`i$m zMLQ-1K4xD)gqMH1jGVWfIIyCjY4NcNL%J>v<^V~;=yIic9P%~h?PAme(mxb#4g7KD)hM64xrNr7T6GKU4eI3I>FYkGGMeaxAHqIs8vSilvSFFb6 z+YGEz(o%wZbZw(5si5x5OrPGJI5;;$O4zfb@Zsp^1lDvJCj7|Nn}+N7M$0xD7}v94 za;&1$BB{C{9r5}s zZ_k^AW|d(Ak)C;1bW-KQD~(%g{M=&iFs5c$OYIhZt9n{zmh$%hF=Caz4=zdSTJ7)H z(t1f$S{Zx^^Zvw54PAZ~1D77gaq=J9Gyd$uIN|K7EbF}=ec?$#RR2|9T!6;veqS); zO>>^qCzumP8-2d)(kir6Vv{E{=wA$3^Zr^Yl+!T!%27<VBij^?M{y&5B zMuJbN$0H0*8jwn(kEUeh3%jL4*uTLOVgju6A09P&4U3dH^@`b)HupYd^5hoIO8VPOA3wc7tAOCkI|#n4VLAxDK=1{EFA#iz;0xRxf-ew!5%D|_`vS2q5c>kLFaOS2 zK|zCi4YkY|9{7l?iNN&ySBD@Z(o#3M*Ng2W?%B(x?Tt;>sP1ORdT+J6BcAqf(a lgu)dhB>k7F)Bi3caq38yY@6gK>!a5sC-hMpvtp!Y+@And*g^mR literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_10.png b/lottie/test/goldens/all/Tests/layerblend_10.png new file mode 100644 index 0000000000000000000000000000000000000000..9c381b237c24e87152cd8039f927979d5e8ce522 GIT binary patch literal 9710 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_12.png b/lottie/test/goldens/all/Tests/layerblend_12.png new file mode 100644 index 0000000000000000000000000000000000000000..c0afafd13f4af60bf03af087df1a1e42e67169be GIT binary patch literal 9405 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_13.png b/lottie/test/goldens/all/Tests/layerblend_13.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d5e8564bda5589ccd08db9d91bc672470edd95 GIT binary patch literal 8576 zcmcIqc{tQ--=B^r&dFBKkr5f4I+Z0vwk8uPO+$847(yjuXM~w>9HDGe3fYa_2+6*m z5>5$Y5Lre{G=oSDqtWpG()`eQ-s^h)dEdD%KbPO!%lH1=-{o_EZg-3gk%BwKcR(Nz zLDac3rVz+BCh&9jXI|jV#qzi|;MX=EQ=|^0q-!q&_~TzbIw

fzQpKuiS<}_CZi* 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_15.png b/lottie/test/goldens/all/Tests/layerblend_15.png new file mode 100644 index 0000000000000000000000000000000000000000..9c586f604cc39cb0f5ae31ad444ed5fc661849e6 GIT binary patch literal 9226 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 Tg{S!iPH%l(!}IytH}3xrhhp{L literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_16.png b/lottie/test/goldens/all/Tests/layerblend_16.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1c5c1cdfa98490348304191d020e8e3e0a7c23 GIT binary patch literal 8914 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 g%l!8^L;ue##1+5)0?Fe&DF6Tf literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_17.png b/lottie/test/goldens/all/Tests/layerblend_17.png new file mode 100644 index 0000000000000000000000000000000000000000..3ea02f96a706f0cd742862eb7d22396318363319 GIT binary patch literal 9680 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_2.png b/lottie/test/goldens/all/Tests/layerblend_2.png new file mode 100644 index 0000000000000000000000000000000000000000..42ca4e63bb0eded4de00a6c20afc14c05defecdb GIT binary patch literal 9012 zcmcJVc|6qX8~1e-9otmaqLCsYB#AKA>>uE4EoM51#p<&k2 zylO~8bASwd#~h{uUNI|+Z2^89@G#U+p(*O*nF4+}=%J!zd>Ht8eE3!v4b3SUt*gq$ z4`0uYScO^MJ=wZ2>M`l;vxI;1^t4^RXm_~rQ3*5AF!c4}z}Q>tLg(xbEwnKny#(hA zJ9QY&CuGegB6VNFMEH{MbIrW#{A_9WoRhkloug{sj$|gyw10Zt8lmNMt<<&5V{*OY z$|z(;t$$!i{*&|==88w>wXpV7xVb84=RKFPY1^)k>tn^UQBZ5bSn%#cfO|W3Eb;_} zPQnt~$Ox<3eV9mo4e-07{&2Cut*<%iGx&1v#ijr~CUNq-3S{?zT;}Rl5)9#lKTHeV zeYC=ZUx+!}`_4O55#zs9)FJk^Ki)c}v!_EE!Ed7spHEqJd35tgYkKP>)nfZ81RF(> zEZoE;ux~R;#0e#Sw2|S5BX!se#b72+JL(9)Fy!KxfbB)kA{Gg!eRnCQACw?zVHxQ* z`)0P;FJfCyu(|*66mXYd!$<2|ccaPRvpDFl#!mQgLe%N#aKHT-QcOPyt)9)k_WB>T zU3;@4&t9g+D;T;ZG81*XWnHxWS0|at64vx3KZn!zEu^t>I$zeU7~9c`;$G>KVrsLm4-b~Xaw^ncE~v+_(W6J(()WT3 zJTl#b0-&AeJdyGnL|Qq1-^oEzrd5_stkH8+qL4tLqqgr6i6U=-Pti|NqJ_%P>J$5pSohXB7utLmS4+ki z<35)d{9GEgm6nS%G&dh|5ol5IOg0+(-Ce8o zPwFIf!l6uL$6K-9Jy{kf4DIbx|2B;)*H_-SWMC5++Q8a2)Y@P#YubNDrsk0Q)O$7e1pB%&q1pRP z{4G5f)kd=W*WKl@HNGefF$wTpM1%DJJVQ6ayt~pot-VgSV(yvDjh$O*`Oj&nk$ktD zLsoL7n;Nks9lKwkd z5$eK>4`)1}g~gG*kzE5@4_`Yy=3hQ*m_g0GRp<+DLM^?&qwHNw{ATxtcQy0-H*XP+Wa89c^I3?b$W0)29Gac%;Nz0kkH8dcMRiahcA20d)FK(s) z*7h0^@K8_F$fAR%4>6f=Hpm&e^089`csv+bMRH{e?O-CDRft-f?dQm53txIm^}fGy ziTAa;H*_K}3A(=MQ@YZCSLUs{yh>So!-DPUh@CV=9ESBGp<8=x3a}-@LPplRwiaZ@ zC7FM?22Ax2iRdhRt5=J;?*02cp;-GcYP`PXL0`yzE0RyuMF(>`h;PX)bHsv)c$8pJ z7yu2NuxVPK?$U_H!H3o#=k4DavY75JRO3OEDV(2jTk^@CbB66S zpYHo;7da%BQvbG1RWCSW_HOuaBRd(@3g4@qcdO@ap+dRppVOZd8}ARA-&)_Itl&{{ zm2B@cXIg4)WY+rF>uYoFd>1@awCzt&Mn>($#(mBJZ8Vo~@(Q<9ZMF39v}qBF_erQ! z@+~hTFx3V#N@;y7MYlYK9j>rE8sp++(vZu7>oh4-gUi_meQ}Zy>*=jbSvSTRDip9c zmdxKylJ5F#Iz*a zyCF8=vVLL??pTbo8Z68F`}X|3>>ASBa%IpbTt-a(utpClJ4>-keRh=Flca0t%*uOj zr)xcCH2Jp8?-*-8zZgWpG0-&Oy%MG+>EzT{U%K8WP2NF1w7&&5*`jZ?tXNFD3oQgg z@DZCM(l*vx*IP?&P=|@Fp{Mmd1o-px_*Bz1W63y|)R>jZ%#jY1MWUg|H0;iuD-Lk2 zM00}GdYBz`sycZ<_IsIiX8C_wtp*9lZHn7&j1!0rQa`L573-DKqvb@dh_yWmc(Yaiy`tH?lT5QGhK)M->kQpNt93r@v_Uc)u**nlEz%8SV0Y3?`C88Xz#5=wIa%7$`ab0{ zp%yZL07AD=tRNNvkm4WAL{7-|@CvgHqFNz*#;DN253BL8Z|!g3yX>OSiwa|W9xceveWg(uTDCl zkPEV5U>8l(@FzOL{%%mgRafUM+`-~!l{>r?K3nFRF@X-Xx)sV`hen>7S|@gr%+2Pu z9_6x1`3O0Dzlu$nRW6ijh?EY@lp$=HfXxScCW@Ph?53WE_&Q+9+s`*8+2`jo*G*|C zU}u_E16fCN3TTxLSA=$giGtfl0>{7XbZ47xysv0@f<>IXRbthTZwEINf^Aw6YN@SJ zyyv9?v|)-_(KkQ%xGSA#;7sl^EJiT6ua4NcG+41hLjtMa+ z%)LUy*8AE)=ljfyA9|EPN9Ic>ogKGi{e_5|S?STyQ9qX^`>k|5khYDDKPySewm2=J zBi@|!F)tWz8iR{6G&S_~cF^Ap^bXb_s}p@q4pCb$Q$A4D>=usQor&e>-iWucE&h5W zqpIzP@|hSRqP{udHG_Vbjx1dyH8~8)0A!qrE6*1j>5e(Uy>SqenCZ(fnEjMuC(o90 z9k0Lv{Zid<+2X)2U1O`%JjS~(D``4^=W>Ofy`em+V7po-H#?J}Iz|{5p&huV2DU~W zh*)?n&qT8BeSP~=5=HSsM1|%~htE_|6NH!O0WYNPVHA&Do^Tvl9>E_`SYk4z_>*4$;ey|J97z_m94|hA;8~VP@ z*6fWHBGkHZKgYqzbtpdq?|FSTmSdeNhQUy{q%bxdl(#}TQ z_ti|iiZIpMMFyC#6qa@5&fA(J_-Am&+@Jh$6O~;h1;zH_k~9Orojk2IJhd|3OSa3i zY=%{JsQ1V)`9lIGu7Y!gh4QYVx-UW6>(3&W_)C~URYHj$nE=@xf0t$4QT}9KxjO>M z!#I^YD-=ogI%w{CWM92G+mTk2{lQ42#uG8z{ z9MyUp_QT!_*Yt37KV#-Cfz~@r$;FT+zWA zwU`sV4jCZF@gR)hD4p(6am`ShF!+KY0Q+esw(6+M(QK(0DHB>{c$2T;K8T2U|8f^JZAbK^;QmB6eE-AMOy^BW`y$##P;I^8%GQkw=F zxWO6j9>f|Sh;7-|uL>}4C>*i`H>{9>ponpr|0QkwKXObCr#tq1NSwsik}!K@_$eSc@N^!P^itgM|9;pgZ;x4BP~rrnkRn z4t%u9T%fMAt5e)UVdRtZRhhV{R#cF?x`^tz@f-ptXl9RHO6b&HQ&Wf$wkxObx^nyr zLFnKa|58{y+Rz_`SOx!KJIPBZ<0&(U69C^J>|eS2wU_?lB!E(peaZzthcmL7KETP5 z-r1oRB^|Wl0&yr>dOE4y4B{^%EX1)n06(W!x7h9J*VpiX)TNW0Q>|klCm6Wm1aT-l zdZ+Fvf3q^Fs+8J%f}!_^Z=yma8Ai@@)l>dr(Mqjesr5+c<-AjP)9k1GqwNZ`%1*6y zabv}W&?9WA+X)KjK}Zq%*(dnvQxUTbE7mUH+#rlzhmuX9ez`5=g(G^dYf~1YpB_ry zE9tl&#|&;&aI@U}6ket=B&Re2mEUMty%r$CzOj!UZw+~`M&?`nUS@y#o{nRTMiCtt zrO*T^SBvSsbsdB6;_P0YPHg*2qZo`XVFJ<;`U|%+Aehlkl{mP*i72@~Fw^CEO)Rm@ z2rEVoYZZRr~LcdL9ieyC#E zEpd}N$=Gyy+N~3>GOfI(;zMx#{eo*f{If<_1zjBHMB4n5#g&rzm!0gD0}S8^c(-dL z^aPgIij7#>Y*poYoroJhaC^C{Sqmo6!^@z-X>inCWMQwMuiA|yqf#8w*)I#)UhM7z9%*jlZTm8Wk4>Ve#rY3R)@J zg$_xrstP#9R^Yl3)SnF^MY>j6!v})RoWaL{`V584FZ?3EC&nypu+IGj9>--?bA|z# z1wAt1;jIW22te?(OTA2>^rPkW-x$&P5lsOfj#z}bMf^-3$%?z1gS(EJM4MK^l?}nfm&M<07jdx6L1s_PML>$t5O6=H|^Mi@Fr+b9{y~gRTAYVzD%I^mEogW&?gfUUn zQm~~D5PXhPtsM`5_M9Lj&*kDQ-s#0}2>`kaIC0=JxdG5x@hFi@8O0USBcJ< zV1voPW*E|<1^q8Bv*3@VGHNWtfiQyy5j-qU8Y}MYpOI6I8zOv!YNLa`g6me-8orw5 z+Csmwv(j7R>3FmiUjWgO9o`(tMObwCmwfOl<(jCB$QCbHj4>L!xAE%qs@owLp~QMG z#B(s}!NE>G{TOjZXCrmpSHD$_o(!{g|z;;EfTm2kbFNsLTj zBcR_E8n@|d_>-+-{1n(LorV1`10f2pG zHD3`P$DIP~AKIYsIlNnWI^Ca2$&Cr=(Ww#UJY-i31O43IYDM|M+&Q`P&PS+yNoM)n zSK(EI<&FDOU1bIv0DK|hjE9=&2X{OazWUr9Fl{JKNag(s%?Hn`Jn#$H;)OdJ@U@B@ zR>|&AZ%xuDhv)a+<*k|gh;9#8?JjEomh1?A+wR-$PTou=UpLYhG+T+B zBmqHCtb&Vx=SB&ZJe6)y)!7G{6r@t}B}Lf#knoq>;tHPDQIB zJE%HMg7V5avOnREFbVB_ceqXam26Ij{GvGkmC;1KF#?VpyZ10#-=-{2+Vz8C-`<@L zROP6K8fM?jF1sM5&izyJpgb)57lKG)x&NiGyfm8A)q5qgzbWr(F8BhScT|SDIpd(<^|Y%$eI&$w6NC(1n8rc9(r$0 z%BPCa^;t&uV0sUAPK!V7$4Yx)~boRzB& z_Ej>o91%j@;=GR38)T>(yitGD!L}tyIl@^l$>}i25RKYa%bPb3``5i2ptU+V+13oP z%1ZbkrvIKxmup- zT%nTiD9K^ujC<+!$A1dVQvrCU?%LMO-U}(gIq~WBoRD4;cZ0*3r_`eYQ2pL0=|In+ zm&Uv^La`OM7$`2l-Gf_Bel!gT9kT#*q-fO?_G~bV1SBr5WjxGzbT_t#83Y>-q&5rr z>!rRH6k|XCgny{5p z2c=<)-$=J+gV8|>F3xky-*iu+@{XZp(n!?D!x=wPYoh%yIj2{N;Ghl-O?wnqnAi&n+);1W;XlQ=x-u+*IT%Y;)HA|ViJ|og;QEJE+ zfV-0bzmg4ZwT>*jy8g;_;z@oDYSbrTCUp>BNrksNRaL!N76515@iprnneQjTazGl!E>SC)76#*_~miJ)Gon!#qkxM)lg2-AnmC%oEENv{$qLqD| zgxsF>NBLmf=8Huh`xta|>N8kw?Ew1|_gqH}BPv!2(e?foFor(6v_(`sbisJ@PWO4J}mnt)Hr96YOl-A-NN!^pMQ zAM-#5ZbLZ@c0^h8&R&A1U)uk+xUc{$Q4{+qzOBLAK#iPw& z(i;Q)Z2IkMot>8?U#-S^{R4d<4BM{!oi6kL>%QjyhABifo=Xv9x0oKC2T1X><_He) oE)Ys~+pD&59PNJ-iu#EE0T?_@Z`!UtXZPJ&YI;|TRBi_TA8|cLW&i*H literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_3.png b/lottie/test/goldens/all/Tests/layerblend_3.png new file mode 100644 index 0000000000000000000000000000000000000000..97f84f5685c4f621607e59c78017c1f7fd13c5f5 GIT binary patch literal 9167 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 QVd}SaGz_j6K>iB(KOJPRdjJ3c literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_4.png b/lottie/test/goldens/all/Tests/layerblend_4.png new file mode 100644 index 0000000000000000000000000000000000000000..36882f9903804618144df597a8cd736b9e99961f GIT binary patch literal 8949 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/layerblend_9.png b/lottie/test/goldens/all/Tests/layerblend_9.png new file mode 100644 index 0000000000000000000000000000000000000000..ac0ae4d8d6e81effb9e66ded746d515d3f71ee2d GIT binary patch literal 9029 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 KHJ^X=&3^+Fu)!q& literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/marker.png b/lottie/test/goldens/all/Tests/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..7a21b9e45ae3e1490d4f26441fabd704676ad3ea GIT binary patch literal 2254 zcmd6oX;2eq7{}ij!_wt&ItBqD5CsI(pe9ucB9N$%O)Er=BnkFkvhWU3-NYKVAY4N7I@&=D|#3W)7Sp<}<AqxQG zG-L%gGOgrAM`&&Jc81Ylk9$yc0td-TFmYC}6`NudbmMdI{^Z39*8Uk5XHQo6m}VWG zX$4Jjk6{*sTc^yg`g7`6RCz?ukpK04Uvn%r7O%YX@X2|lDm&+X`lEq#%^QjLpj-di zk{;2TX-$dUWqD)_9|pp98&3%657EDr=}u-7xiVYO4nv}Gi6cH{g4)k*0n!uO1btKh z#(o>yt0^wV+?_@uxp(6I^)JY^YxtF0b8Il%c`YMix~IB%k&5a|-O}4IB?67Wl6o}O zczL%5EXm_#-c4iT3}I#vp5oxKOl0054(bP5DG!nw1@-$TMWE?ex=GcpZ?SY3?c7iI z)OHLbkJc()J(QWIA#+4vliG|Sy&8nya?CWGimNyUHCjq^TOp=ni(2v}LPyJPO$>%J zz|64TiG%5$;F}69rGg?i2WBp*V3Thp86EuTk{!DX#xfAQxh>106cq4%*J++T?sNJT z05(?$a?{(^WkT&0ihwZer+$ovd*a4*kr*$>M}WnTDm7=6E5K}lxH z&F3w|T3H!Jf(u2uiK~^mANzM<1fQ!JF{ptVn^GJt^So3;9)c~C(wrEf=(ui{gKDA3 zz|5C69wyd}(vA{*%qD95eAHlOu2+C*PbkDQvQ4$fImQueipdQh8%W6#=#5K&!y(DdSJK~0%%OCH2Sso{7 z{RAhFeAZRG5Wh(a7v&HVuI6}^meQU&5P&9eHQ$M9{s$v!Tl@8I4mEQi5vMBE1A!H4BB{=TZ?i_;zvzEUD*UC!!Ju6 zo5(s5a*e`*NYz%j!visRedA*msIeWdkX@@4udc~VfpnPT)Krcg>lAmj4Gce3PJ(o> zdKy`Wi=4J1`eK#PPk%*c{iT6I#*Vk{r+xM2-a{uQs(Rpz>? zmg4?!RiignZb5*P3SMU1qg-MS&ExUB7VugQ-+2gpUAh zw`B(J>24GD7YGIbY1Pebkn(!|MHb#;Qe|g@?=$op?+E=P*CM!Vz->H^()rOu20Ggy z!O~!SEfVJ=((vt+OQ`~eOKJh?g$L6-U`9JUq4=#&1e(@=F!v&9oXOMW=CK{(V?5DrcA3rx0L}#};j)ZYF>8PCNK6&70HX7faR&=))4#8-d8`(|^@1E28 z>m`_fp*I8~KSY;eU?UGPXJr^m-RPbNtngFStw6i)qjNwz(wE>xvJy*}El6@n?PNQ6 zl$Ap5OhW=bbhJ4lso5f|DHu{GZrZd{8=s=;*(HW)WM#;TdY(Y`4@r9Nu>b%7 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/maska.png b/lottie/test/goldens/all/Tests/maska.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9b16242d8d7872c165ab66021a7e3b98cd3c26 GIT binary patch literal 4241 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%0D|I48&?%%D2Du@>%neyK^=x6StDhXac;r zR!LpGR99038KZb zg0N!R%!~Y*Q)JfH1C!#Q7}b}_w~0684CpJg^y|E2ZiQd$KeZV3k+kyPB_X>F%&9xF zRJ^t3mc;*M52yv`6_X7rk+kwQk*0qDkp@S<@u)HDvqXOWa5WdwmRQI?GLHY~t^1nD zF(3&06%eL@xki>$`!o59odF|gh%Lp?l6Y+3TtxFG($5Z9FgE&CLu+Y-HUH9!x8gM^ z=Pxk(Iy3PSR_`o#MwpOb1#%Ep?Yl0U@I^vkdI5T;7}Z#xt_!VHEMzt`ViWGin zdU7AG!i&}{a&EVV1#D=yB*w>r zn8+2YkuZv(jk-UzXZRGTi}c}m5L1jZS_eGdow1{Ek5G(qBr$B#sS~WCA!66HI5+(U zL`I~|E+A8F1O~j*p@a=MNgBY~OJmzT$@w_0UgWhNUKaGf(^EKELlw?o12g3(B3jU?&ZxkdjqjP zJhVHqlBMK4Awq{nmn<^np=pvB`P*jCXy+WyiPRU#X5@qMy18g=3upU6VixXo-OVZO zP*s}r#pvKs#e**5`i1gR+o4Fd%5?mwkwfCww?{i;;=6Z@lP(C?tJYUWFz*y83om}z z)n&h2w&u?Vj-N>wQAnyap%B#KK z6V3341(UNgs=qR~!Y{VFc{J|ZEY*KNLUsmpNMG#dTh1?H?I%bFXF*RS)8yR9Vo9I< zOq%`#)?$o|QN@sLAd%mG3U2^t4Vjs=d)TlsSv8%=F}DEy2Amv&R*Xm^S~rm_jI&${ ztdYDhf!1;gZvvPTh&A29RTIwMoj~hmCEtn|fzX|hED$T_%o_Z?-wjsP@gGMM zQ;aiOm9ydMjQX{0lfH;%v$B(Px`86+LX7Z)7Xq$&%--__?c?h1IM|sy4s;*JN%9#i z_)0I2CFjFQ;U2##d+^~3ad=wrX5z(Hq)6{+*TJe2=oNt7sm+UdS_ODPxD1JgcEi=( zE993Gf;N(@*aSp|CD`gwpbOjjo5`F^7C8xn}s zgAq0S&J?ryXcV5#{$o0KyrOaUE2um!6pkcDK{;ij!DD8zTb1uOsLO}HQ)HS&uAV5| zF`fi@m5By!6Sh%8Zk);l(@NF#>8H`pm`JlGq3?#7z~K9t9t3OG4t@@W*iUFza>=70 z3U7}>28zU}S`y>ElT6kFapb;@-E4Vg?@bPTKH65aV|)k1DidjLzohA4_epoexLKLB zm`JC%DVV#3vBgKRi&QeJVU=oGW12)$xr&&D3w5QAVO8=(la`67?Q*Wv5iY0nQ(b4J z={>s<4T;~B2D7mno(O{m;st5(B=bHeWz){9wRO~h__#kGFj531dl!c7NFvMV+tWN_ zVg+vvGNP-Ec^DDhy6AMu9lrx?bUSn!%(vGPP@kh z)5lk52%`1g(phFbh=nXoA;+X;5t>aTx}U;=M?#CioF2D4g5Yog*9n%1=c9M~o}KEg ze3Q)aBYYVe*Dnv%Mb?x_NEXIft{;fZLs<&H+H!sni`3nRgRmZT$>K;E-{r}jzfTqM z=4*1!Utl)7;m&niF)9KaLF^3R7@Rcle%G)OU<6^Y5Hkl7yKU(`K?3#$Tpb5VLogKJ z9OzfVbWg;{GM~z80M}96SiXLg-9E?J@M~||?BfJl0fE>U=#Yoz7ey8B!P&b8EGrf1 z=aK{62(a_f7|nu*Kek6w#O_C>kGtG)B~xy(YWKS=gd)QqMCH- z2EZ}gN4<<>9@(TG>gnLQtL+_0qpHQU1tbe#iZ_jrOBDQO_4RR1}Vvg zN|fFAUT!K=`_+}AyNM5f0>o>_T3Nb6qF)7p*u88vOlKepmU3?+nQSz~&@Dnwzp@T` zAmz0B(Rx6--A8$b5If9#oXVo0ky6p4)h}Ty(w$E~&(FR=Dw$mrx%}f}IJv!C9HWF` zjEWSFda^YKQg}IJ3JI4l^ixfuiMd9nB=MWlV9sm$j546BV{}YKGB2$iCuQV7nvj#L zy8q_`Vc%$Q&#H=RD7o|9YddR=ucdpS0deAp3tN^zass}!hCBhWr;A70$JSYt5a}>a zgXw|;$~m>k=E@3}QBg5g*v~E6+H)jov5;d2c&tTR(?>pf{%c5A&z58oh~s=>pjlyO zU$KgX*mX@y2e#JSm5}p`Gs);K3qwTnN>3AS_fH{-mrIF$0yW@`(!*!F@L&xUG z4+(<91zZihow2;Jv`ypIl4waL^iO;lGH5scfNO?umic~rAFTZlk!EKKV)O-Nr0!mD v8f{jDc+|%0x7{v2I#q<_|H((cUJ$;KdLG!=#0Zam?h4!xyuQr;i;VvOjqsiE literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/masknone.png b/lottie/test/goldens/all/Tests/masknone.png new file mode 100644 index 0000000000000000000000000000000000000000..8b37c5031a30549fc66d8d7533ae15aa82f3be2e GIT binary patch literal 2686 zcmds(drVVT9LH~01V(}#(+vb{7h80iFkWIrDHYT{1a+tZH7Jkr5JCWpv+Hi99lGck z^V%B)Cs5hQ1k(w_`k*Na5uv%`J*gBC!P!y7QnCW&S-Mkf9gb-Do15I++;h(FwJZn}G`n)VD|8-Ut`#rSRb?B$T-l5OzIo;~%TsC1xv(9T`OZhgH49XFGaRlz3j=Pmn3v&Qht zwUtTM+TQ{dzPh(+q$5g;R?M$(=&w{%RPBOQUDGr(TO!gkexho_2UI1GD;YQTry=pQ zKa8SkcTDpEDcLX?fJTye_ow91mObx?BP@ok_lyymZWZt*nc}sweD&j|-t~Qv=w8+{ z9qJ_^Wqty8Sjfw9!HPuHZdg^KM!^){n4LAIEp)_}sXFyFqn}XF3+C{~^4c9*auI3?8;9=uAJgh2loeSGE>_Z+Ptb5AK zA^w(C`z_UA;oq~saM|gEA+0KWy$x543$_#5+N_3LKRN*&+qP62E<245 zuh0eV?2VxH)e_@{w9<2LU>YEfM? zr9DlJ4E;vz9_4Q0>>gYV%HO3wna@9Dyeu)h*=zD1GIhD?9+2c#8eN|{Hg3wd*iSvN zd$o}?#cV?Uj!Dh35V;1UH%FP_ZPt5u7YX@A?4mW>swYkNDs~MX0Q+K9tb_SKy zBL37TY>!5U(K)ZzGNhx;zjo@f64PhrAoJ` zL;}2Wi=pf*ZTPE;-Q+HWBcOOO^s-vUl~Y;g)k>zgVpbPvmAVSQD7fA|sE;<3cr*wt zW$8R*{v%w6iA(DJ=v}$GaZnNU##50sbWRdw7$n&>>4PRoYD_g&`!T3=1Ew|xCr`~r z<%;{$X9BxCDk5oX3=?(MBY=mvDFmS{6_YM3PURFX|9@}=0=P0^3KBv4tCnaeYcPl9 zHN!x^b!PqAE!1z(y#fiTHrkp(fniBI+*^wS<~41;d)!@k_n3_}AHT+h$1e?ldR?aS zh>o0J;axC=%=1By?`|y+72bH(=L_7R4IHuHmQ(tah-F=zCi4Q&)@4C|YDY3D6?8p+ jj9ZiQ#%3k$ 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/mattetimestretchline.png b/lottie/test/goldens/all/Tests/mattetimestretchline.png new file mode 100644 index 0000000000000000000000000000000000000000..26739522af37af091301edc6acb8f9332a5403f5 GIT binary patch literal 1486 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3ZfwjWZ#WAE}&fBZI^OQpwjz65)xp!kvMT5wf1yhr`ZaoPVh+JPG#HAu7 zz{;v5w5XwpDKIcVAu!-Vg{vc@cUaDwy)9Fx6@2_*~`Dl_!+z>^sMMB!AaA1zn^=z>gS$$ zp=V1k%B}8F`k8F=Vt@46RnK;1^-tL3Q76ayYyP^&>y~96m2-%=_m0o{^2w8%=Wi|F z)&E#GYg<77gw5jb|Ad}jl(svgKXh%$wiRiCn`5`SUr_pAt^1v3zM_l46I48R*}ReE z=ig*xx#rbE*GYB1A7uQWz3ScmyjAZ6gOpLmz^?cZJV_-d(Y z_ng_6l0zd?er8;#R{z$wD;F4&N+;j-_E*h6axbv;+NTNIcOO1iQWSL6`LgufWB-MB z^{lFHNztD(|LV_sW}O$6pS=6==ll(6vxCdNL`>Z(?)rw;Fb8Oc(M;c@e7g9YW|pk* zhlgm7^>a&+ljX~s|6SjhzUK6`?;JD4Pm1%i|CLXAzoYB*4dsmI$Jm#z-~TE4jpYC3 zhPGi-T&?7JzuoWKn;aTk%`)}m`sLey$se!Swbkay+jkp`=gv7Iv5{}C>%ZzZysx*s zwRI{J`+4ktz@Oi&6d+#S&{(7U_X4h{I7vJ97e!jY2 z?y9BjtNo=n-@gc)zv;xW#g6Y6U$`H2+8L6&J=dPzb|TNpe*I@#TfO{!(Kahz<=I|) xyi}?FQwHz%7aJqLtT?~NXW2$`nul8H4|a1OkyAP)S2u&~@^tlcS?83{1OV*zbf*9S literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/mattetimestretchscan.png b/lottie/test/goldens/all/Tests/mattetimestretchscan.png new file mode 100644 index 0000000000000000000000000000000000000000..b265c35d1ba2dab2e25276aa733c7dd972ebd734 GIT binary patch literal 13504 zcmbVz2UJtr)-LB*@W=tg22wRDsI&t}Z%Ppq1f>@NrHMcYy#&CkGF8Y=XMSr60D(9mC3 zRnnrN`C|$EdwJ*}_{5;_RV{e?!$nI)fhM<^eF9wUcTu>ma|pbA4p|1!(43~Zu5?w$ zGk&HI;do~xVRmg+vTyyKA%F1|Ztf$*m+FsnlNHRJ8;-@%sXvS9$xx%$!ZjcHJmN1H za97tpjs375L_+#xeuzf{LxJJ>sPESeK6~Pi7ME*F$JH}v+&$_n^t5+Bo3+E0m=KYJ z(#|F4h^Vp+nGOGM&RLxfTn&9=J{wCLx+9r#>6%GnymG3Vt=HMnjWn?AaBWug4OWTBWNU{6cid<1da`qV}<>*bklxo=l_%2c7}B(P4VriIo`6c?vX+7_1Pk$O?7p477mUr z69*h><~eU(#RBh`G-0A6oq{A{krZwO;njIHv6GzlU#!(fVKzqwgR?l_XFq!M$e05= z!H-Y6k=n1G-Vs<~GN^j4VA5wyEmaGnk>0_xKvsr?#nB-Pp&Kf)va*_{N)wNiI7wc@ z!<VbB;VkL#yLi>@dDqC z6_E+ovVJ5grER=xd8%7}R0U@g<}WZjn5eHva*<+WFsGF|5m zN0NF9$1Y-ey8~og&oGiVqc4(}A+L@y{pDZ1R(<}JM!HDyt#O_)=|@l;PtbHTqVMLK zKbyr0mxSZMu`K;OKeG8@#tRF#-X$mB`&^LyBA{+~co@cxjj4l6ef$1>HDfX1Y=Q>T zvarW;yQ;RfR&$IqT`R+elrMBmBT)wZ02|6dK|Sb5OK%{D@89P&uE3e4$IruuOh$Rb_`NrkS3So zGdtdvvfRkE~ckL8KBjWjamXa@!m;^u>#X()J(vhP_Ksj8}?G|iSZ*JLsHTCa*G zXuzdByu{*sGaLzXbB;xYg(9~%Pl!H}IsU-bHnu*+@xlj%nS^>-clP@PB2wP(AIe&0 zeTqVsVwZ{Vlx*kyW;eI{=%*=#y}azACe})kx~2QcKBgSP;q~!OP6j=f#l>M9TwEAl z@y|AfT`ss17|e4xOr>hdio?OHJsE4BFIlpG^*kpM(d876U}a_X{*aY5bpSIpzhn4^ z(iRpLC%8U+Wj_2&gT+G6C~~<4ts$GBAus*UKaPr;nk|Z^T|?If{PByGt3$!vR)sx? zqhWd$jf;wkipwS@CIoVMu8}flnT|0h)q0z)nK8HDrDai;LtD?!a`Aewt!Ype(zxyy z^t=pEU3@E2o|9!NJ#bF&0cB3SVOyVQ5H%WV=TNw5o z+7QXltC-x1aA6-y5q4YN&_8(apaM8GeSY21d1+Eh>fA(w$cV)Lq8CCN&!0bMUDfF3 z8ctR#9=V;-d1hln`aUO;M{Z%#0x7H4c5f7l>xx$AJ_~_ppq4S@Y`@Vr0d<8fe)Ehx z8u6=6+~N7kN*bYG5w>iVv%`vvvP((4hK!?=Q&ZCG(_omSJknBl?PH=W{G`p-l(aNI zlS=Pp;~snWh=5@M;rtgu1UbinE6A4A&T|W`&tzN;OC0*ta&mG?zIAq5xom)q@6}D} zD^DVq6!hxQdwBxi5a*lF2lT%qo6Q*c-Q2#0E?_<20BzP{eDdV^7JbwCr>+iUFx2~-*iy`Shc3gb12 zx;A{<==7|j2l3;hefq|c%i2t6NJ&dUcAlG?+ss@^!Pm2lCUuHYT$=;5Ys@G!c(;j1 zrFQ)a*v18)SvoFgdq`HGy%t9$Jy>KYn~UAng*{0@b#L)t^ z!62;r|He8wT&$o|QX1~LpR`4k-yCEVOz)Vu zIKTRJ!nic|RR-PZOWP#I8W6RL<5je^I~px;C|>$#(WxDxxG_Kxmu@qY+X z0(wn;3N1Yt1my$>Yw3^$3^*0BEPCgti)UVlPWq(SKnOqFNcZs7wKACJ77-m1TXrEg zy4bFpv&p(Jsbi(#b{2IcaOU8J~ekiX0dr!}rbq29J*F@T=6h_(JO8VQs z8qwC-xtw#O%ZP68M*@$gTa_)9N$@mvZkJE`^o)#*f^O_%=Peo|I>PPtZ!5exyz7Z8 z!(sAE#u|PC&F#It>yF^~X+*jCDJl7JL-fa1M8(A^#OL&E+eNRIN3+(>kj>e#YoP&m zE^0IXDJy#Ua#77}tnDdkJO#Uip(B{pSB{+_sd*+YI=a*i%u$}4`TUKaLef3l3PRFx z;A0eDgOR0SS7L5%E}{`3$BCp=2JrED_N1<{)kgPw%J^}g4BiUiQKn`2aZiDCjfC~} zP!4HMrm!-5v5gI|9AU~DIC@ij4YA9gzB|Pm;*K3V#tY7=AHJhw@!5@Tw$;uqrD2VR z*s^E>i-^wfS_Gtha!AJPSlFA*$1g#qN~ZI=P;mFtbAygPhlKfK#aWORC7X}DGYM~4>Ro220;tHNUkBy%Lmk*7tolxZpK!3hP=MM zE*c&l?h#lwvbMqBux=GrT@t9O9kyj|sP~PfFxmWB*P)$r4ep&O$*9R4nW5LAkF1Kq zh1QsFk{6ivOyoEGNtXm5+(RBk(!8gS3n?FplLoIbKDjqK=H9xQS9WH%vzzc)YiPXP z&z}wtaw<}PO2Z)q0O1vX2AV50`xoSvoT+Rwn<#i%QtKZyhiIf+_dpeR zPxCDHnf!z&0`KbEb?3^CDwkgf-Fx1GV@pgL;-Md_D2r1MHCZ8f39iq|E<8)tl#etZ|q<>iQD{kg{0pJT{JWwEB?##cRvPqG6@i;u3%5-<|S z4_CgV?gjA;AEIQG%@A zJvqtV`C@O83m2M@48DpakkTYCKtvt^7hJ0fz84-9COC~^lXK_W054E`zr6>2{rO0=M})nxb1Pu;%X zO!&Y5^MYVQ@HG%=9NgH`OB@lGBD_TsG%UnzljJUBSm7tMSM_>+AauASd zM$K?7FD=PEhS?U9@9hfuX;H_PmA6co z&qw|fJnveh1z2QjYm1v)`X7*3`tlD*Ecib_;z2ur$g0YySXgk9_OG82rmkAHMS5vv zWreN0yxc6q5{?70@4j%1<0sNC)Fn8c$K@XU=`DYF;@{|vi)054C51>UdT39tzKEIuSp;?>j4+DgZ}4{5SeYSv89uSz8wmUk27)byt+W?BemLQu z+U!Qg^Sf~H1GYh`2=en7+@RZhSuRvd1xU6p3?JZDW?eSI>xZcr?ci2U?#kX7(1LpH z2T6YdjPvfXit?3YXOKqw)>|$-l7+AM5C~swkL`J*^OZ`I>o^25)s+L!C@x-(1nA%1 zflwdLGuvAUCogX6>Ba4x?u_R$GPAA5;B~3*IZ=X$#)9yTT}Xn@eWFG5c6EvIzE*-b zVMSVG7E2;>)z1Fhd?}ZKX>VN^Rz7Wk#)5<t^u$HsV zS$*Tzp})af;ngqh&&bu!1Mz4fFLQ8kFkimjT;?|ACnq6MDjcR-@hVQ~beJl>%BmqU z5flNB*1DLE|FkRib?iDryT7-m%*xVPCtyuP{m z3qTfH6&Wk590xy7DG&GIBC-+EO)Y)0xWo>E~GvtR8H?$j0Cv;7(5MN#?T#5^$0mubyMf?X~F zCoUx9G?i;o?nnB4G4x*V*PfbQ{J-Od+S-4|4F~cj87}R4ER&zHMcP$RuOUCX(BrhF za107hJ_Bht^_-3oA$>i?#YG7(IPv~hUIUm{-`M!W-A`@KNgYn{bY+_PMthqPl$r;e z>wG8LQ#sC_JxdU(y%UC^G{%U)m^DT~n9vJSHOXIOu`uG{=FZJ?t-Px8BV4PAjxp6S zY@u)t8@H5572g;CW?;yTjgIz2%jk9r{G6#I(vV|)AbDgqu&#YUT;w%ozJDO6p@E>J z>;vzL;(mfa;dS1Gg^}1yDV_(K>1f`c!K3tu6$X{>?-T&+6I`9iy6YO12d?9y&B2|) zU(d&=AKYd4K&>L^PV%V^Z?BnX=GZ-WU^whSFA==6!#3-x!#7%^ z_zZ;?zoTY$hDVwCtwj?hZeynAs-fvo=6A!)d! zva34&07SeGz|Uyo2*<+Un>NP0yM{tu^x45Sy9pLVF08o_iI7N(OdIm`nrp>pc$#g` z+W2Q{e&X#OnYznFyz(>CvtoW$a`vZ#=M@vX`6 zDESa52!d@Rhmh=&3jn7h=88T%h_u=&0f$@GtW^H^;nWvGw85B5ENSV%@rx(w!p^F2 ziq>wTxkL>kml;9fiknoy`B71Q%H_N&Ma)I=8!Apq5fkj~uY|M3#l`6lqq?&Vj|DUj zXJ+Nb#x!@KX5QMZXn4GLkgC%Hu{^5I5x~dp$ax86?mC@L*`ZpN(38vfh?2o9*^EpvXy^HOV$OIm&!CA-<4!?dybWjf9&p#hBaL_!YnX|2v zrSuOf1ri777ouqeN4sElb{k97YMgSC(`9vT5EmlUt^amw5md)bp`oG7bYwYg-eF@OF83%UWYVsZq zMSB8aQ{dre%(W9~YO2a2$ zmz>82{kb#(RB!tEid3@r2OW^S!YTO^u1?*_f`8%~zRjAI6LI8QXIGsf$HJ{i@ZkfU zhOC?iUu^BZekhCD1^1tA?aDs%veJ}(!LJtzmB?idA#`XifQtjs#+cDIaO5+4cS_^{ z*s%szS64hy8&~*Glr+HGA9-A9bnAoB%QzekHccWWx==8+noo=WDUrL8qDcFY?s8vp zCX4j}ui+29Mh^lX_da<{jR&dC#br^~I(4RebURwcRdT?z!BM+^IvurJLxak{UUqxn z3FCGR!4|(k{p0-c!+k?Tt(m&!#iDMT?<3B5(9|ui5|R2NFFfMJVH$y|x?Q0Q1D8C0 z`u^^}BWbIo8*Pj~5~#Oshpioen88Q?g5^0`fuWO=ldOO#t*=S$d`_Js0Ad-oM$jgt z5&8lHjbqzEMt+2*(pR~Xs=8a-wGAMUL}3DhR#8P`Q2Om2XYHYZHP-s1yY-6yTsp!N?QczqkmIGS%@e?OmRXnyq?Q(&27{rB(RyWq2x;t@Db zPEONFiDuc3;xZ`}(VhC8dEtuae2OCBB|N^~l3^6Vbu{D}8wb|w^GJptFGLw}^l#C-!h}8NxX%GkJva?Pc3slNXO|6;Hd6g=_g`aRg z#2cpiZlR=la4vu-;bQB^J|-FEma&)O8a_Xxv!JJ^H{;!7uh%Fh)nTfZ5e*$_wOFhf z|BBMNqlRZ7xdPAGxwsI@O2X(F0MKkKEQrg`uz;|mgfx`>@8SG!zkC=}SYcy%_wIlm z*2$ZW49H{gjtN%?Okd(?V73%tO)KMDUdO~z;HGbw>hS1iqCIZ=HsDIanQwca-YbC> z0IA-d3?o!+sY@l~lHcYifP!ageR+y&F$J3Q6Ui`=?FCuqdH-e#1MJ>7VD}OivV22+ z`&wr0X+MDgb4IeUvU2k^d<_Ut*U;Doh$XN>Q4vIeBru=$i6vFBxSON1cJ}t0t|X^R z5kV)b(vp)0v*N^{-s^AuUOxPVB=L(CiXcN{^2^INB5t5cKs0vc4*!dJx|!9YYiW6z zUcX?*c8BQOt)j>3UzR61&yFgc16)mOB)>6f3H>g1uOJ3w=b)E=V!dUvXOF3i%c36B z8k9<$kD*`$zoaNpo4tV`%#C{a%ZZ7(;~Q2Kl3V|>X#Bc)3(UN5-@bkDifqLn$(fq5 zias);*(|aFh)t=DjzB>vawYOH>V8&t@7`@COxl9Z!w$tH&>5*RAiWe%9T#Qd-V;?l z_#qq@rOwUuz3_euc`GMdY|k57{9fPG0je!<=qrmdGB$=~WMwsst|Z8KE#&r#7$SDvOJYQ`?~up(2TJ8A(YmJ_?$a%V#bf3WXLbTt9czLuRp21YtZ;cKNrG z1eg|pV$=P?k#L{MZy6TPS_lZrmY|vUM5_3xzp#{4nLC-(mpLnxy?+n0fz^JF8}p^+ z7GH=n*~g5~*5-6Id^p>v7 zww2D!!-E0=+w+irHM)M^mxAo{B%g))o4=PVZP6+>JwSN_vRUgC9kW1%sZxK_j7Y6a zjbNbs-j-{N^p8D5zICCf(<$C}L_%MJ-J!)Yt^YDGhp(0rL!?wydiq$-_V#v5a9xYi zux$(j)h)VU`_GKL&*=RHbhW>^j(6X2X~IDk++#GlUy@6En&`aYaDw3908?&{P_cT^ zz3S)k{MshEKMRY6Xsty>(i(Lfb6AUi^hNpJQ%mfE{8SD{EY zFJ^C$g3~H+hd*fW<$^$Fo?#OuiMjFf^Yii-jUNU5S`z^8#l;8cPO|fpB|-3ivvEA@ zz}{x0a^3#;C;^jRAz|SK4vWSUYa1=`l8f$xI({IEr3QREA&nGDb2B#|S_ibG>t1Q5 z^+)sE5V~5 z4SF;+enn8+O8!Krw>4ke|}s%LvCwpBb>ldw=^>HUa-;cQv*<74|V|-aqv#H^c?M;E&YbC{*KViM&x8U z`c((F&#HvV*uGeE$(v$g0tk!?L?cuu61DZOLB=n4V(x`dcTn9;({7Qzm3YckOWPZm zgIK2u!8*mCb5(ipH#+J_$Th?1D@=QbakEab=?*FRmQ5B>VqI@UaF^5n@*#XH@tiK!{8M-FxQ}0Bsg$!AHNbhX5mf!~28LxZ3EX)lL-G zjO{NwsNe2L*3@*!Gk*+!=`Z$U(b_Ux&Pk^Hv^Rd+(O&(@Np{8TA@;c3SfjDs@{9UR z2~FT@gPR7GsykG%>zV9?GN2bYZc5bxFq+tU7mLzdS!VUwDrBq4PZ^P$^`GUGEO%O) z-#BPiK1es>kOI+QhmDJVYh5fFl9|!9mYJ56A8VVC zXS;qX>*rE+%FHxhgRxon&@NZLk41yKj2ZdT5ibg0@Hs<4lVh z^_?goj+Q90XK|*z6>(|V!~uaA>tT>}B6^eut6RQpqXtMu&G_hvR<7+Kmk|mBM<&?C z0Hvj4mUCd|)44D)8tIFKc`6ZmsU)2hfW_kP$3P5z7EtQVBQ7Vm9TZ^cj03EA8&C&K zrBB(p8LD;eh1!~*aD09Tj+<%z8yWrv^CxgvqZJ#ItWG|hU?@s)#M%=u4Qv}I@ zjj69@>995IQU^y`Pa>|VY_c^(=wd@bke_l`y``Q(Gs|tnJvo~V;&#{JxNre(u6h0CnOG{zD^X#sGeYMVj;xqwSU+{Wi{+(i8UY@+j z4veQiNrmywAfcQ_uB|msC7FadO&1{iqr4X_r4s7DMQl`=*=dUo~E0`kAJ zy?toqbD8OcmpIjP)|FxO{?%tgiH#YboZ`psbft27mEQMiJ9K0}D9u13vzl$a z-L6We&(k0Imh`Z@^ecyBmco=Q5r4QFPSr_)mn%`)wPv-si`nNs-J45IfKSyb85zKD zmh#im9FZxMTDs8}`NU+OMR&C_>diK?=UjO4&A2*N>1Xxd(51YldNmKmbeL z23T^L5q+wDXQv)`WAv=j;lqEl8UDA*o3fXn-UO}6-R?zYOFn$PiDui+m2d&(E*^p^9Tm-hzjkhVae;ZobM5*rs+ z5>y9s!2u;h36LypRAgTj*&7J>F>qG%^Ye+Os2?JfQGXyoO5$K)`A)Rr*ikb9l4iBV zDc;zb63QjNopqyx+=ld9`T`_amO$J??Ue@uH-rd{f^&>Me>70$gXjDZ%$Kr3KzwL- zYg7UHl@K94ASk$P(Rc%gLL}jm)VVRhz5k5E+=_qnQ!R3_TnNAf5=NWiv?CnyGBPIA zwY9_5DRHZl`WSCugW1lh+;S45K4>Uw)1^-j8 zdC08hY{4(RNfUt3Fi;g`xUz*3UyN~TYG`maAV{BRxi%kwc0jh-tN*DFLIDl%|51JN zit^>Zs815207klSd|`;$l8?OlEkhf7I0-}9-Y~0LYFC3bQqG^^;4mqNlN~zAEP8+b zfL4b!hqtmk{W*hc+-uGAn*f{Q0)mk0;3CK~6!RBr7EF?{I3S`k10n)3-7?hTyiZ!G zi{uXKK*Ou@X2-`%-&}X@$}uJ{g5)0oOeI~aHM;Y>TsWLWkPGsKku%v)GUE$6Q z{mmxA+P7~W<%MncAls~N=#1H>rZrIhKDYy1+cDBfNhlcrxt})Li04+=eWFa?T z`bCYo8M!5lTFVTmgTC<}GLrzKG- zX*)e+>>ZR9sZPS(0^K6*XVa;M#`5cj_;vD0$=nwXM}8AD(-MrjBTNw6#?&KxM98bv zX8lVDpx(O16gG;C@4x3ey^N73Och!{q3IO29tVr*2A7T4ltBba&g%oLN)*k6N(ds* zl1e;fwjT%ZMP`V$iMzYIR~b&O0+KxRBnbyJ2|R#GGIMov^UZoyd{V0;+03O$6c${E zvyw7V>?c}_3y#ms_+sXedcrZA4JPI8TQ=3t=@CY0Wtj)5+ry;~vl*h#>(sx!-5i6B ztelPl1R^<@@1XO0`x!usaL2=+j93~YS6t~MeV(|Xn&S|WN!a?^hCQ2~Oehxo+kUTm zg7D-a(ARt{_?c~&j{_7rumAJsljUV)?mF+jLTvr&WX)i(*$v3Tnxlk|R0#|efL+wd z;D2j9YJ?JfRFraGPlRPBCnxip7Uzr}^G=PIa+{ozcAxfCQkn$)nOTvT#`?`MKm_F$ z^4WEI5oq=88<|_tfYgomE-sJL+`q=qX+=$5Tbc#UX4Ky_T8# zN-Z26=iD0#AV5mHoels>$pW%+x}bqmfaM+&ljMX%^W%z{6ND|2M^fc%)kc?Y*~%NB z6veOu<)vDr6@LMrouG|s1gz&HKe<779j!qQx%iyfvyw2#j%}$CNNtx-U=JjFKZ;)L5@~1 z^nqU0Nj?L|%Ly80y3H;CiCrbn>(Nnz*Cumtjl)W5eTg%nXS9$n>pNl0KFqg9NuY|4 zqprI03Ikfuq^!uo(sEcD_-=umB?6vLJP~c}cJO_oe>rBf;S}BJJv0c)$33)#%^Jh;o!5s(X3aU$Bh9^=h z2S8*9Mx|%=?pEF%UZqB?q9=o)^4%^#g{L;rDrhP?_Cvihmeg9g+m^Gh$#Yz0^C}fz zUB8d8Ic4VrPMoCoilRfQ=$Z#XuE^&t9;)*=yssM{D+8BpEdji9#xULJCxcM~@`5<& z0@+I~5KD}6K?1#4Pft(GT)|fG%V^W{e7APG{GhQZcqz(K_|z&xf{eh!e7)$yda(W?9Ok@>L)Hou!V7K1AtM;idIJ}|@`aDbypZIZlzV!xvJ{-p_Sq~3uhK6&Jj0Q? z;Gu^>9~uP!dd$Oa4weJ_|L23>@PEXBy4W>sjIoqUn`TEREDGV-=AJp!!Sd!04ygex zFk5%Mp^B}og!|G=$Sx?R`Y zPBY4Sx0;e=e}kLpyEaYVNo|*^gEqFduj=csBQAYr-&4?da6|)bldaU!f3_CqngJZJ z=ER{)Tmdv=(Cze?YO`7LR8#B3pZjA!r~WTJ)Wb1F(yw-6q7kcg=i{AS`e&h*;Sp+W zz9)?mWv;m=02^iC+8P9Y)r=?)x$#fWY%z+v#q{Zk*XZg$-ms6is!4P^7TvFik@it8 zZsZV17P*=rU2)0H-90qmP<1l3)(4uf9S4E-OO1U49-#YL=OhoRRyKL^cdcy1OOCC& zAx6Sh3fCy=tayd98X9*9r=jb!MMLw9s&)W1VqjhTy{7-d!>FMVYixPDJ`_Rnk0JdQ zBbKMkcxA3xaCW%(x7Z^_T>KflO^nZfA-tAdj^umw!X?%a z0e5yDipD;HI;x0n*SkOHPbwAWev^K1*kc?8Wu9r3mXb0(9>!dmJ>>&p%|BhON9vXh zX$IbAOthx!cgGffK1o9(A@5+k4;1F0eMfWXp`jw_320@eNVpf_Lwr_AVTEi_To~9~ zF&;UUiT1^*#JqBHmw~Z<~yXi zJz6;;hp4%n@G?!avFz(sU_ptHXy*kgnez5MXgVdXU+X76MY`QR`~&-_6-v7TdPMiG zQxITBM1pOe8mpKUEA~is*a>{dtw1%0zV@{e5^rx_&F>iXaLN53-t)Z6wO~X9J+rPB z8s%$FV{xhl786`!K0=wKS^PmR4JPs&V_YJWTlmJUfL@*pKAkTKV`boytI$*;t-MWy zRCNQoPjj$&BI6pNfy$Ez-`+=a<-DjODblJE`eH5647$-KKtnS!be+mxHQsW&aQsqP zZ0C|Wd*(^izn&>vv{1h_s(6rQe>BiWiFV%+5z$F#vaYl#;N$cf4zqx0t(=$Is-0Bc zr7!8cO2;~1N@tDik#qp8m%ba7b`AN(T``($);-BE`$=Nj$=o4~3gi5h)1`6h>mGq9U2e1)V?xK2+iNV?e)| z5}?! zMDf(G+Y5Lt{006;L$uInunQ}rzsf?%&*q+2Y8nk_?$w?9zcu&hyneIdfBRFQmcnRM WLy2{`Cn7{0b6r_ODOcg{F#rSV!nKq!^R-PfP;g>R*;ughl7KMyLy=Xj@6^fffCSDxn9`=+?#pnY&8L{p%q zal=Cs<(&F}@8IC@?s(+7gTHh9!GkTs+~q6(=FIC%cw*F}wujidNx-zq$34(F=Ym*%gBdSB^*(e{POEY3DI zcVA8B>EAsj0jyM2%PWMMwF^4gzoKQ9;ZrOv%!0Cc^Gi!lNqg}2Y7AT4u5v4!yxvF} z(HlpvEBVckrJn#(FrO?<#jSGaX{Ky$su`)OsiCs82mWQ;IjU*D98T!$4D|k=HMO-| z+e^B$Q6q!m`;Fo9>x)ZEU%c%hzuH}#Ar(A+28oA%g zHDbjxL6t;!=2)JRqZ3C<%glV}`lVNQ8P{P{W^vO9c+AYqY#j-nunlMZS~Zd~5>% zx%cPhJojv8sg|OyLwl0C=A)4tSx>7fs~*qtEj!xH`o6iCXg9I~=Bi2+bs&%7LjS&) z`TQWY;s4?Fbd;lS-@!NxuE_8V+d8yIMp&LRsIor-NXL%APqsr_p`-K0emfmNHU93? z(nf1!itM{4*^lxs#y!Y$eAlQ5jyAdWHoEs?QP%O z{g~E_3Ko+*r@E-gi+&iZo3GLRd zU1f(qM?0sBDoan75qz=t&3MHKC7oxYlR9oBUMmVr=YW2NE5(ajw!cK+P$%a_NBsW9&BgTW+?sJkWHm zQtRx-(r6zQq^U(IqJZY9_VdqRbTGF5hz2>CvGF?b4nui$bsJi5JQ|CiTQ2K0tTT}R zt@Z3Igv=6O%+-*O$nr{5$=(Dq<9Yvq*{K@KOGDU8>R{=uX?IDnWh-n*`cyFk;?+Y&%SLxW{CKVYWW-92txXqNN3 zO^ffksm7@8vUV*suY2y&8KM6cCgNy7{#c2Fep3SAu^tDQl8iU;K|fCR>8VaWO?ts_ ztL%B(Vx`z0+HlyU?MczV*lF-mCE16_G9UU?7qe%MN)@yZgoY4AIfaW z8w@NaE0MNn*A8%?22Uzy2)W-x`;VVsNDZq=*f!iWvzHsA!bL7Ev4r%1{0leA4-X%5 z^V0C$Jp%U*V%|*1z|IaQcS_*;d?5`)5(&f`97-=s9gE@PtJ~divC%Hp^gaChUnf<2 zJDlp1SkQ;Jc1-j~NFb+)k=^Om*4Fl=^zr|6gqg}5hZ=ituClfDK0qxI>GAGa_t)mn z>^NVy#Y`$# zBZq^X9kZR2Q$a&RiVg3#t!5$ZNTuS6)E<&C1d z#l(`j9rUbjaGEayv+=iZ98S*G*Hud;>Z-0M!ZW#An#>l77=IT-klYv={F<25bSN2_!L3_q7HTI@&f6!HSjPy4%e z45D1O7;?*uo@1l4J|&qdhOF~;Uz+L>NqVei%(`f58LehFRB3m7cYd3CO{8M{Q`hzZ zKH|W^uYt4vgq*vB$1`UT?fR!Ua)ApEa5Edh(61=|fII)yBO0VDdpoN!gSy?6y(_R> zP=4j%_dnHcCPQA?Tg?kzSSNzg8rOG6cNZGFU5}@cTK5ps3l-*8VV0gDPsm;v4 zy(`Zu)M$zSRC&rIZDUtaODmw``_nr#FYjy!*>d9rYt-*8f<~Z<*NL6KJ#1e=&i`(+ zzrF0BKaomI!L~(&EWXs=2@QG{RVH_PgJ{yZbIWLFZ*QLr(F?NGOOi&Kq_@WXf)idkCZu+bfc%M@oy?}z~Z8pzlYJ|TP<+CkBj!VVwKdrgz!h> z+sx#)j*jNmf)J-sAdI9ZUuR9EBu*$p)SItf&`jj%B&J%xW`Qv6dNxRZlYRsq4K_WNX*oc*34Axi<%aoHo&2 zS5}5GqBA=W!*Y&Vc?I~UAdu7%&EBVrtpU~HHrmWz_US1QX5ew_#3Em77USC>v~xD;-(<^vdkEuM;=*ln^rYwT{(9F6FGzujVg`o3cwb z4i2;w@dd4V-%IdKj#Yr+8!Lthv3+LsynLI2pZm}FfCj*6D*QK6I^B)Z{u5Z1L91=e zmQCkRaJCb6YcO3cgjbCVY-?*vKfRP$(R7{Q_~=KNK9z^}F9#K5wl_id1MLmp1)WZ> zJoL$d`ier_kGwdLQOB*(}?1=m0L8CMaR8S&0$xEN*VKy%)BnTS%lYnU)y-`H4C zc%U&#=IY_;x%xWt)+I!K^u>slIl3Xz3S1w9IXl`$$abCEbM>C$$P zS2qZ-nd5vvTAOj6qBuxpW?@C6B*Y8Q%MW?q<}pgCoy&brJ&-A)i!m-=oh! zQvbM~rutvI7%i5xb+PupC&l8U2>m1#B^BM709&)SNqe6ohS{w4CLEVm@}JhyyCrhe zc>5P{PCj3_hs&5CwsdnL>M?y7n&W z@VkleJQeh23SjZxg{6L#>;0?*^IQ?mS$hZ(aU!PwmW zH;heA{;-_UNP>f0s6}g>8*YT8j8OGwbICt{ZRtK48zY*<>`Q~w>F72m91s0qXgzoA1^jCDz#+vo9uOu;|3#5Za+iNe$p1?vATVs+ zH3P@NNw>~zGp@CjxdyD?K$8bLwtqw5GS(c?%IeDBB%4>TyT>vvW9Lz=#9U9qcTCJ5 ze{Aj7b^hBP{7VT!Dh{L!C$^}_v0dWCS$U^mb%QcDS7$}%k?98-7pE$Tv;t-P4WsJw zY2q6w8IaT!qDYP0l2_WbsloZkC+Mmh)xnRff_KJgZ(W)Sxlpg0xIsO@=Ht5_uv0hB zD^B(|ZEs>Zzdzw05v#LxcfZN@Xv_XRg8xvelGO-bv!niR1->GaO1C&L4ln5aeifwJ z=pLHM$2wv3=F;lbPG7o*Q&$x*kL?n1y7MUT1j1Jyvm{Mwg)n5b7pQihcIaoh(`*_y{;HW0C{bfAti- zc3Ev4a2FaU{QDZ%k2X$E||9VKDbc>9PtPyO~aJcyFxtN)J+F!hab;6v0 ztPhWMqcnaTvL{V@xdeaGgDU`zT8TRkDXBOc_>nSBT)%-)FIrhpu({PxWpaP=mV<0} zw0oG)hAWOI{b{?py+YAv&dG4FI9jk!dd}nuE#pa2Qg1Uee+Iet9O~Q*%ToJ=Mb6b^ zBXBw{)thy7+0^6p$|BFYY}i0$J#OG)8JnzdohCmu`7I&;Z~)f-4OA$p(byuL>EyFF z9yC@qU82u=qcat%epnLPx z7~D2rX_Pg`&uz7^xz#t+c^dmg6sUDh07Se@-DZbHfZYW|J*cz`L6n9V@Wm1%;8O(|2 z?P0Ia_g)KDB+-FWs1e#{e;B#ON>J09ODoE0dzzB0mGc-!lHN;{JPM_GoY zDe8##z9i&Tt z&6eKH%I{-O7d$pL_HwY}MGy`Wr>u5KT)p+K&7=|YrCkl&WP60XYL9T$bT0?;gmY8I z+)&n?t1cJ!hp25ME3pqPb-G5tBb5;|CG}q@rNNmPNo8&%cw~{MH_!Wli<#78d0nL@2Ntq1>7`9w&+9&q|mKmQ_;_qn|sr)@Vg$FFM{Q>(r-Cyo@#E3>aEOr z(nnx`KE34Zha;{J)D`RkLbmB;0})311q~0JXQ2%~MOSiiSeGzek(GgxErijN?X?_j zJGhm=*TPDrOZKL`t8OT1Si{#t>!}3%f&K3miZOqoo4J6!gz@8>6m^H8wy!Fg08A9U z?6(1idIAhZ*t<6~V0h3}u{_NH!?m4LR5Ye%rj>#LczP5qOBCz)%d4#e8D_38LnJJz zO#sRLdVk_5&CG26e-kl1{)SvMZ+=Amngo!{G~8S-Baq7~0A0scY*>Q>*4F{76E2&`XDjGYP%V8F>Is3yr^y~(`o)jQKMi4U zDz^q5r#1hvyyRqfZ&EXXRq^?mI3C+YzP(4NV^rDK>mAe1jbtLsn^i9{Mg~Qjm@OCY zp{awZX}uP9_fYUAfAH*=wfkp5dyn8sx0?7&En9AuGZ6Gp1i5y7;-NtKj3FP0ki%KI5A63L+H?J4jlAQ8P^H>=`%($=bVq3yxcq zRQicBAc~GCJRk{w)^TgxB=K#vEbu+ZdT+u_ALj#XLiBd9YJDVd<7HqmvGXBP{4>IZ zZKHWpIM22_F>TFi;`vXf;uBcvvYSxA>RXG<-Gr4SrWFVHw19t$iNAbR$U)zNCu%9% z=(7PHP{GOp1Lnpep8Y>OZ2+rBXe05N>cUN4nbFLv+jAZ&tqnlrD zE(>nBY?DV(6mvUYvu$1$OBszJL-HguNSU2$Y45m=Ry3;p)rw{WANz1dem=3)1Y_5- zS*MhAq^skwc%Yd!>|PHgd`1yFoapuDhOTmQxs@~o7p6pndvbodLPOg zpx*t&abJ~Ra}SrSnCnH3o1Lv$}TE&u#Bj;)_;LJ7LF>27YQO zfl<=i$%e4xP0?K(&cy}j<>#u_LIIF}v+WGIH$d#l8ln0)1|SKdgNac9i^{bs9vWRf zxLspr86V1MJ z=z2H1nEKuzXmRH3#wU=`2CX!OY*1lleK#mq7#G}8BBb8gdx6**^hNmKV$3LSKhs+q zri@!}f<`He86KQ(NwL{{V=pk4>%Ydwx)xYo)>S5)43Vu{CG*f6b+$8^jUpZS^d|{b zOxW!5V;6LFsFvQxQPQHdtvU+lh)T8X8}k?WP|JK4?QD#g&w0gix&ctF|yFBm!w<=4%ctgHU@ z&R72$*xkgcK~Ad*2TUFp-0+$Zfr_nGUPIl@8|N!9mQlZ*NzC7Pw)q>@o8g|ap(Ghi z7c3F{ZD6RK*ge~t-N)akYl!uHriX#zFzF?!_^)!$_6oh~uk{N2Z^y2>-;-B4zlfck z$oW+ctb0ERNNll0FDI_%eX8RZod|6LoP_|^(13;6S;f1T`4iAx-=r6x>nrl*TOAV+ z$T1_K)f$e`PEelKtQulaG8trpvrP5T*Y3GC8)F%B#ebpqFxYg}M)40Gn5x;~KC5hp zpg8@jyg2s<>X=cX9iu>40}e3!nVJzxH3p>0x9=UO8&x$?BqSP7k1Q;O=+o}Sl{f*U z>~Sq$xnO=Lx+wlEJi+6wL9B$#haiESxekvBrx>dJn~S3Ds^3=wV)XbFDXJp1bSN#^ z==N;-9v#^-Ulq|XklXr_V1%*DTtSF}@{Ziata`7Sia+W7yS=O3a#H_KKD>=PZNze( zurb5;yQjC2?wie{ls~XQ{@NnNdmuDQ7Yf%*W?!ton{f2-Rn1%uulN07WuvV(JDoF9 zTf^n{sF6r0fwgS4=INGXEzXfShyoKi9%kLVK~5N4L`i8OQs-nLzx?JcCbv{O=FAN) zHULKjgc1Xra;1L}HaKbW1;66V{OH!Fu37EpE=VCzFFmEEqt`DAryj_$taX`LQLsj5 zJ7vL0hX-Hl1bMCW*0R3-sZiLD<0@c&8*^yw@K1-$7rSo4|{+hiZ+qrgnPTZt|@lkRfMHIs;YA1@pZp`wf1u@jD%0E-LzNSsg=T?xi2Od2cgfR=FeOk2&(@@@xJRRnqR&?%o|hBI}Ls{xS(!Sq3l=U!@Q5UVzcVJCrD%KiWzP! z4*A*LdVFwAg&?=`hK$1E9Pmt-4+!{j;CA2B;&sF4ns}3;gM@8yUAb?HzbvLc zIFq3|C}==4yf}VHHLyw)VJBn>_|nbwrZh9_WS+)wiXad3*2+Y;k}$_~$yO9e1sWrr zwrQ9#c44i~3ZUmS9CBkDC;~{-? zpT(|YtbTd;rqYm69kgDUNlE}j9ov*VoU(a_mwY;M$E|s`?8i`;WNDxzMgvd&8}w|3 zV2fpVcXR3pH4)#B^-{oY{?nil@8Z|P&3H8I=aQ$$|EmQ^GB?U9K_gORKF{diUZ)fe z2n!xEN-@p&nSMfx)RO{PPnCrGR>G)b;@#haEp~X=4*VNmR~qN8w$9f0Gt2Xyc8x^I zBei|v`b$5yL#!uh;zlG^BQfsR$64fdP4^F7E}eZa?3(k4GH3Y)stf$qt#9PYVKc$D z>KIR@u9HS`RI~XF<-;BUH0{QzRrMyeL|c`8L82{(hy^We;EJaKV$ny3#73kuwx;n6 z{w2r_Rcrt=D{^(>JpY*aG?Zg=yr=Wu1D6)BHkNc2!IGhk>jn>THj%Th{J^#Xv$xX= zH*w;FFEk8i=j?8uX)?;gpof3{QHl_0pEjw%-1?%A<2i+HUZn45Sy!Hyk&ci6>9k0aj9-7OQRouOe+(lLXP?s#7)${S(~s>4!Zd%E#3t zXS3&CeNA`6;1frqniNIZBi5Fy9xC^X{X`AXGbvy=3{l2UA!4~+3JDp8K> zjPdZMeF*s(yqMeZ#op=gaN(tNz_jXRoH%WLgOd2oI*zC29GgY~zLIL?Fw3v4>&fz? znFhO`jcG;~TuuCLo>$?5L`xnKj}CcWJ)ol|cvRd@pYC}r6ozPa zOVtlEM^Q{Lgdl7evvnX;gT~|RK?Z!#?^gY zFum$dkY#)Q{?+d=?gtk=BSxC7`nQmL0p<#wocoO`XGCew;|hYVlk>8b?!&kyfap-+XRavKaLJV@tAvMo5eP6_a=rbU}(tiY@@*M5rf8B78e& z+Nz(DQ2|dJ$3|!M0P2Y590+BgmE>yIK z*mHJF0Pu;~<0O`R+0Qaa)OQy*f+%lZ5j!n7HS>|Uq*FEPvnck4JRB)jV|vs?AlPT9 z#s1vG>pcl91ioeS_eD~;6qxWNAS{aAUd>s7GASYeB!`)pE!MitrDGhr>p^(CNtf_-Brov@2tH;DS#mxy{C)lR>K&WLkh^v z)8Z2#KJz~>(C8i9R0+Ai68)UZlSXjDB(1~z#eE0WeLxkWIKdBP6-0Wvp0+%CU3j^Q zNc&{oHEF)rb^OJg?((%HMZO$SszffBPtSG%ZALb6PB zUvA{O^aM}J5CZWoE#+4!UK8cXxNX4r>iNlgv2H1{2Qc2Td$;+inFO>uf1N&ufKbBR zn;3NLO^j0$&1+YUg+LYxPew-AzNk0Vv`)wK{;4jDL=7e;*%^sKbo*6on=~04> zy?Sz(aAO?O<$5-C=~wsk9K>e|@7?(Jm+czWNt5c=guDB(b%>;<1z9es`bJY6qH{X% z;Gm{v!Do9q$(kMV>A|{t-d4mKP2z{PGEwNzrpg(uj9kLT0xH#KjAUXUzR>-w)dwbz z^kDXOtd-cJ4?kYcQH#8D^A@v+KL|7q`_% z=$=3jdHImXw{`o1>MqOE?Q5OqqZ8CK6U_$nvGD3|E?O%wWk5D~O+iBnKmYrJhr1#O zPwA)uLrHQ;3c=t?+FKo!4@00omO`hS4wrJT;C?x`R8j>38{XcEqkd~bigMPgXa7@hVup2V`H&YXp?*^Ct zQ4$t2r?j00wE0_Ox{~Y90&l|z8l=V|$3jF!8JEYQYRF|FqHad?>=Hq!n?tyf=^A%GJe8I;Wa3h!U;vi$+tPLclKRp zeYj40YvxslMw>4x_V4%mXZYHAZE~DRf0mz++Rz9-HQpzoGKBgJq{T6{cI{FGst1XH z+)21C-j9*8z0l3&V+MSNJW=U~B!F@ePJGx}@TmQ%5vj2j0Q3$9qnTadl!>c?l;VYX zlhJW>SR>zcOZ9!`e`q95=|6F-YDos4uq034ffKxXUHSgp3g|3+f-c*h0j#JU^F{$D zFWpc*L<)f$Z0tRRuq6Fvh7#W(Z+j2Wv<+VT6N<~9TaH_DZxu01*sHP-#hR+(=Mu^< zQ+G!U;^`M+dgK!!EB8~h?0`+jx+c_Xy!~q z=0lpfJi1(O<1}Ogy@yQ$O60go&!oG_U2pyX+!LC4e{cOECq}$Qvl-&8{(+zvYL&@# zEBk@$2h4#5JC#tHQh+EWH94|g>By>@Mf7qIH^M_hKPS2tF>q%olJuCn@9-?4DhH2u zHP5ynQO=tL7k+DU)^rdPB@Nj&e(B_g^U_AA$#@?B(KqY)rr^i;^)W*cpP(u8(|=0O z=x>J7Xwon`+pmx4sFwD9oqCGhhMK}1T^D7^HLtTftEfY4Iq`s5vA*M2(5-UudU_B# zogZ<+q+b*>ulzJ|f{E+@G;QhpOZq%#eL~kTqdMwRTeV@Gyl$C6u%(?4Sh%TCmpg?B z+@(LDp&+tH^MWAe^Fi@o87Gm(_GkkXp`u~sMJBELF`jZem*#GNZQOr75^EU|H>{rN zM%K5FyWj311)wBUxul?|M5IFcx)ZO{YFeND-tFOZ*!JU}8!!wmL;}-#hgJcn{2|Yz<=ULQNKaq1v3C0KxW)NGI}lg+ZR!_ExhgW-EV#Q% zM%JF{*C|;`cFpAUjqucd8o2f9HzoC7+EL}vi z=`Nj8Ue3ivUXa*sSB(L?S~JUa2ZlVWSw<)OwJzx4I6ve$y9jo%`fM?SmyD#5T2J*g z6H0L74&*&_49+Q`Q)efwGtyi^V+O}8v9pwz5x1Y}PF9k2e4j_B>QhWOhEFbqQP{ZjYrkjAOMhwjIq2n4r5iUHl1dZNWW|L( z*GCp=K~5V{33qpt&kSDA<)RX`xsGf32D%l|!?o5iOqy_;k@BgkQ9cdi2p%~em1F+x z?b{Iv&>!d<-%tp>6wWfL;?%%AFEr5b5G}p&cS(P_%}M&{*}` zXsjAS5(y(imik86@Fpc$BLq=8%W6ei4oi!jrxxs@>b4tvI0M_FDaT(}8QR5TB_9lU zuYru?oOzr zZ5!L6Izg@aM~~5qm18bBnOG&IKsb@nL+7f!;*L`*RbEk-g*YUL79b<3-x<%Pi1n2ly4i=JB-BZK?f0O>-cDQ zN|8ace_qw08TPS)^2~UWHY4A~P@c;$b9Lv-MqJ=W_aNgj%z;olBU5yRy^pOdrzHo! zz6?4~Z}+#u|Au72kJkw8c&H{aoUI{+;W0&-<(0+6l?lZNPLhR{`k;<}ypo;B5NdpO z&P2|jN?AKHeW`zm(JI>I);=lbhWtQeIrNz@w4c2|sg<-*`qmV_y>|8b=M?pR<*NGo zve)Ns*Vt&WE5(C)8+aXC{X!fWcpgi;?(YaA$qNaR3KxXkzI8--;6`a`A{5G-Pl6#| zq5ufL`4*fE6HAZZ_K8XEeoEiBE$FNI0+9?!1o2P^C1Q|ic#O->F>c7$_DV!abg_C^ zf{9>dU=;0bqF|*|@G=Xp3H7O!>eB{4k90YA!(Is=Zxp36vpS+G)O&I+b9%9EdB#&; zy}A0*>&8v3G-SV#wTPl)mN$HTjEm&MzQD4aA_C-U;YOnfY)5$GRF3xVT#-Z*$x`%8 z^e(=chO2!dlBlO#VgobO?ux8>G}(1v_Z|o-8dRL?`T51dt7@QR1Oh}^Q4$fKO3wY^ z?>GDR?o&%+VWZNhRx*Ie{q|0ieSGeMf4E^hM^n=ff6CwF?Y1Rdb4LHpKbYf85_xi3*dYQMjLZ^Z zw^%-`c=nrU7q?7lWol{v8~u&Zd*`y8|K>T^<}<_It)*Ew=$Kj$jsbpSeL~pUUY~}M zsH2p;+;wnu;Alg0ll3_{o2{?WGK}|F*1GIC+S=`bxq=(+s;>c~l4g&C<8 z%c_p{Gj!1>;lb#1sQk)0y^?hTNu5i7+$$4+9ZGhuwM;42tj;}Fk$s(yI zVd0GMn|*&@e{-kBzLWpx!^E#HcT~Y9{cj}1_x65WBKuqORl4Msg5d~1u8Tb7r5O%{0D~f|`hFGsU*--02`a`SFA${sc5(W8YgqZ)V;`242L5 z8W4;8IgLGtu=3Kb_&m{>ASC)a!`gWQjw%aap>KEy{e6;>yLXP4DwtVs;wn`o zV-l0Gu?f(ouU)cQb8+x5Igz5Qp4h2?-=HX6NdR(`2?u|VY0{^FW3^ri83SI=QHY`D zkSgx|Az&FvF`n`zQ`mKuiVy@vPV5pDw|$O_Uj86l5x|Y@>_M4O(n(huOrFqsZ3$O= zhhgCTcBq~Ufba3c;W@+)5|eB>EFhMzuU36U#-FG$QQI{7-J53cD?Hykocp(KZJV$1 z<-Cr_)ozV3Id8!A)eP~4<}-4;2#u%S*I8}BYRQ3kg+iTKikn?oTCO?4m&mh{69YrL zh)l0OeU@+W;%Nrc$gj0enB6UQTr#-=AzBB z4&N?tv(HX=1l)?yDkhm%N-3Ld538^!ZHqf3Wy0ub`_rH83IP^&f9Um@70Yn9V~r1v(d&bOl!CCvJP1c7KzjL=>UJ!bnBx# z)geA-do2*y55Ga|j>q7Pojay_SZ(3nr(5`9CQ8Pc>vxpq^89q>v)8Jj)ZY5JpzbAYYJGVg>G^fu6bax~C+ zwE3;tp*6E-^&RLg>Dq=27Y`HJn)YL$*mJCikQGe=ESGtJ*y62Z%+UQ9od0O!sX;6# z2jS@2pgLNEZ~iaTw*j9KMW>dZ^flDW=G?%Wj;b*u_S`DUU5#(pV#3+PC>JllU}%|Z zXJe5mZ2$(BFNbBrN63U}zLJCnz-2fd(^A1#ZCBy#y zc(R-}`@DWfoiHu!aP~KD$;q!q1A~?Te=0L*F#TTUb&@7X;kCo+S1%U-eF+C!1AZ`? zTx@T3zdn?G*JYM|pT{OvFdV_^aiR_@rncR;_UHE$f@B!v_aRH*;{{1H(#0cvrD&MqLiYSqzI~&2h@=K8Ng~$g~`+eA?rWuWhfOxD?shMR;HBR0lXN6l%Q=h z5rXtWbB{)WYq**LaER`##oPeRVPq4$|AD~-dxNNLTNwX#DZJK`)zW=-!(oEvYb0Jf zZ=fhgLgu5yJhBJ1yDr7A*jTUD>2j}XwhK0ODBu{d}#CysS# ziTT6Yxh$+GyH-W;kGliQqUeEXHI!VwrbiBqm1h5fIek25)!IK@y0r7!4IeoK>(nss z_&OiYP`3W^X{)oC!cH^tvwl>sYD*AuiHB&)QOfjc$M~94luRyN+0d7cK(Gaa%Qy3e z-@bRFgBXr?(@u$c=dg+%u!WN8;}|shfzned25d?Za@q?6%H@>*x-a8c$5MVMmC#+$ z@Z-DH3|eHBi`c4SXg}8TOL_|uz42Y}yN_R6Pqr|1o;-9fV2j>i3NXv_yaxHtZtTe=dl{8mgh8jK*S*|E%Y|g#Kzf zcu}rahrMVEkSq`;2>p;B^)<+ZDs84Oo00v5{8pLuTHZ4=+=(ZmQz$At2~p%HPK1*( zdc(LvFVM6uJ*V_a00Hqo1$QRpg(47A3DN~_V8@g9)8RcvFtO8pe-O9Bm!|v(=vrlmu=?dh$GhkS9m_X!@HOkX*2fC^w<+0g}+HhbzU11$7soj514mY9BHni zpgU;%${HlBS&f664dP_njT!YZ`Eo9 zO{{7WBNWo4nej?8HY$5gsVAAvfP>#Bu*pdXw5w=DzPilZ@3Xo>g#_{^bWJg4+OA!RRl=M`%)xx=2j=E#p zEx$&((**K_ADiy6NYnzBuFWXaGn(bDN$}97XCHtl9*5C`cj^Lk%)!%_f0GPa$7q|% zbh*sD7NvM5J_v=RZn2Qjv3sisWvLFA`cOso0`KAq0p8UF+xbx$weeZsLNqxAPgxFz zQorZ?xDfiG%Y2MR6}*ic*m2yXoarO>GWnsguf4r~dO#rYg}$u)!mm=ySjF?JNcsmPKhNwXw7xK?Ra>-{?_O0?WFESo);t>3M%1EFe_HCT;;)YCsc1H ziQK5R-3x_;4qfWx|4kW96I9LYyiDzbn3r^^Lw;Mq`>D<9ij7X zCXBF&_K=C{Nwn%u7r4sz$M1K$n&N5)oz?(?DN&`_2-8hM23#orJd@3dGC~^p-{WL* zUp=@#!Xmtly$&XpuJ4}ld8jm}pEJIjrL)DsbJ?o!(}7Q9dtCY0@KNW9-$=?!6sYx& z&$qo%Obp(X={|D=A{pZ;7h7N~8<=d(k96W@i)X+K8=bA<{lu2Csxx(AYc_S3{wcm> zn_H=@Te{iGWNXG0{}Uwxkx0BND^$1lX>UD^CM`Cm~J6mP9BD_&pQCup>jkh=+nCW!!D6WX|PyL*Cte z%Dz1BP?^qoyysrMi^=gy!BZUr`K^T1;=N1nuPHhw%t>8SILLvvvtf1i%>vkXa=s?~ zV_Imz9fX9%`RvX`A6L7f!Kf9B)ai4+lgjpb+^#nS*y%?_2@84`I=RjWnE3Ddcbn?I zVSVHiFsPiH(Trv>{YyFKOn$JgE{i%Az;I6U<=}pM`KwRFJm$Wm)1dTbAN_B0`zORd z;qu2KPc%$Pzv;L*u`VYih%YAL^Nw5!;LvKTnJ3cfsEj%&ZB(NL1Mi=+cxwDX9aNybf2ATgr|oYo!4O{~qQOl%AT|8wbU5Jca6Hzr zY2)fI^}EJC#~N6j>AoR9R;8jF7eZ!`)wAt1acnD_1e^{t>#PbwlEt{m%b{GiE!>lv z5f|;!6WF?IESi#%%R6EE$+Z98L4{YB9o`=W3FPZ6S$g|Z^VAYp91Q>d_p=7)s52-J zo{sHq@YJR~9JhGcbn;o|xA_)*cT?Sa)343=@2@hZT^x4EM1MIU%JG;vx1ByjtndAt zYvQsRUA=>UcilEe|VS?IZD&X(j zS3ytxb;4X^1F)2wBB$k}^knUYT&=_9!9_TyLO4`nSaEN?#jZRl=0Gt=HBfK3EF!Uv_RF|3cewQ(Hp)um!K3o7vFvr~s zqfF1;v_hBZMI>rQyCWi1YU0ktP}!dFMro3X|52K%?9L z)dIA2*l>zv-;UkMV1JkSiUdvN_-sqnNmT&~|6$ph1TZI6=lc1T%CowaE7+#wPC%qSS>6Y) zfcC6q-Lw~RPP&yy0=X9UF5`7O90suOsn%7H6_wcmy9YHoOJh4$+#&TE$ zvF9U`_V1nxkm1ng-CwhXPBrM27?S3#W64jvR`>z-e$KzHJ}$#%>2`g7z@aWgk`>H( zEe1)3beeLs_ED~$UB-Yq>uVBGghq!On7maq`u`*Eth?fPp1!@fdvMs`?rw{_2M_KN zg8SkwL4v!xLqc$OcXxMp=i&Q1=YAE>{yRIORwb6*eqK(_~pLWmV`=XoT@% z{T8~d$F6;q_UxIo9*J6$`kxV!7)I5zMS`Gv6Kz9&FKvMYCAk5=@3G*F-W$5xL?EOc zT`#)wxj|2D&jE#Z%fT%Gj}_9@;_xMbaQ&-a(jQc@JmXEeUxdKcm}+K0{*^s%mF1#Y zZ8FcK&X@ksYRXlOP-a980OmS9{wZD}b%}JDwZZQSDT&R*+lQTa3zoe>knJe@T>0At zWJE-+6*td$wI9f0()W51qORVDn6@iS^oeD$jXq1|pK857LWMn^tT(UL)=NkTz**Lq=w{eKFATlm*`kJ;^1 z-(!Y_p`_5#rDPxY3>Q7+BO?$mpK|g9-dZpbOuSk8;h-Ruc>$8BcQ`9@2(^~j+@K@} z-$Q+;9x;QS=qOPheLD>*utw&-l~=b@;PcCL8g&&TsbxV+;X?s%Zx0<,mhS8$6H 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 RzZ*zMDhe9%Rk9Yr{{v$KSIPhY literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/miterlimit.png b/lottie/test/goldens/all/Tests/miterlimit.png new file mode 100644 index 0000000000000000000000000000000000000000..ce7b64bf74e20edd6565f70d1ea705b45182da1b GIT binary patch literal 11499 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/multiline.png b/lottie/test/goldens/all/Tests/multiline.png new file mode 100644 index 0000000000000000000000000000000000000000..4429135257ee0953f2e5fb0862c79fc22b126c21 GIT binary patch literal 11138 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 XFP}|Lk4S0Wy$&}rH!Rb?a^rsi7jx&} literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/opacity_layers.png b/lottie/test/goldens/all/Tests/opacity_layers.png new file mode 100644 index 0000000000000000000000000000000000000000..a584cd8757edfeb8a7798a208632b977270232d2 GIT binary patch literal 17415 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�oV2sGy~!AwdFZi!8|4;D_vXF8;QvN&PXZRY6QGQ~8GH#rlRp654kTgf?p-flyhsLl z;yuX|Fu1d`)7@A8v@beHIMc)&NS2Cx6Q1q10v$`4BvpY<$xw_TK1z78JS!{fr!X0+ zdkmrM0_qjZSOo`%HGT5e%0-Wb@9`Im*Lj$12o`3&lk!*}+wF8HEG)DaCA;hHWxq4u zVh0{u62Dr_Qk544e4%9gi9a$SVP)Un-l&@UMEU%}J!!Xc>u<`+$k+;M-^u`d+(=*F z`(y4bTHB>c2a|->QD1j()dwdTd+dgJIsSWOHlE3_%D)B8s{Jb^duUEjEs zo|yQZsXRYlSuvw>&)(0>MNHv4)x&;H2^Z zAuY)C=B6h;cU-OKmKnH&Fyp|Fmlc(Lj|I4Q?7m0P@VIfQS%@YT`VHpTEHC#C4MjWZ z#bbYSplFxeWbA%|T+A|=ttY#Py#XxDi2o`lH7FhIwjHiehCf|Y4C`^E9Iccrh~h=j z0wtGTZbfpAUhz45w~7zW|N5_z@03hiOKb5#@h@s`J-sAshbd=un;`?yp=+HP1I}^<`rffvL$89T=MTi%&k1)I})I zNzz2k{yxUp>OLWuQ1-9A-qg~u5D}Z)k@Y@BhTDx35z!=#x@Qf~ZAqbmu+m10tBEb-dhq&Vf3X0{J^k_^ zOs&7`K&&KBmZX+jbrJJ+Ys+O$zHe@BPC8(5cB?w-!iQNE;`)=>%$*mT5GCM=qmmvU zH+%Qq;(HO?It`vvl{+g-mRtPmg$eaU25oet0;jZzIjiJvD3o+0iTLE#hhym}z;!MJ zOW(d-G%G##EBy^fg9^Z>baZrihPF#^qNE30Zd{aUz4vuaSvG+yu!t&B5RGl;qD%b= z2ZsY;altvytj&k9E*Y*&<2xi4eB38t3U3MpCG^IRpQ)FLE|hVrpOlEjalTRA*I0^-Xgrco|G`V9V>WT}pWJ&U==)aT|CTOE+ z;opJXTQ;~nW8uLti!?Pn`rdOsB_Q9#xBw+U7f_h2y!qPI6&aO6u45g0)DlE!P2T!& z;wwNB%5Dnw_Vg@2C@hyr8KYp6m71rtG#~#lsNCO31A)wOy_@0d5EgXJdl@U>M26Uxfarr)!rJxn z9L9`;<10TPZNVkRY+1!LzB)n|q+a`Ib|fQ0g*>OkEN=v;s#%pPq~2e!Z|z6AS|gES8zr~kY= zS>keM8U3z~wdiFJXXl5CaEyqVrxFl}B9{}@)YKU8Uo?NXL5Oh|0|CN3zn3r&Yxjwz zUpydF#>&-o+xZHmu3P_#l=?Yijc)#&VHaM*#qsrzK@myEF;5XdbswBO;EwIc?T770 zu@nB-ncRX`jwL2|6z0n?(1vG2iVB;(&KdYrp9$jFOerE9; zNH_roS%$hn-uf0E-u3nCS4%s0lYe;Bl(g*-b@Ubh1SWqE6&YZNIF_~BfS8IYG=`0t zxo$OSlR?PX*8xZc+_%?>p|gCc`7*#Y9e^a08(R7E(0?f3$!L(8mow#1u;Fb|__Ksd z?AQ(DYZm~x3$gV1_5Til5kUPqNcEIG4MiesbiUWRuY9{2^BvWQwGfq-5ET_I#ltc=X6+=`a_OR|){A!R|U<=6y5sWOOh4R=Rp_ zE|5GfZz!_dDKQ~5CqH3w{};qVhSG4(FD~u@$|R9QWz_GjS+x63(l?dN4c|<2bkqo7 z#@>)}4CO}}7#ZD`kde_hAFXs<9>|MjnwL3C>8V-hT-w;ssQCOj60cg@a;&ztb}KV8 zQzA+An;Z!2DopVVCvt%tfL(soX0`<=xr`XZM1iQ|-Mg&=Bjwh1KbJm>$;tU6TF184 zp^^i4Vc_3&{|!^pY7>-@xc%Nn5FV~Apx_y41{oO};|(;X?FGFIY3NWqpW$j`4i^qG+)xoA+9XvayW`M~5rDFNKva$_kXsA(GLSpyj3}F`8pWg!&J_Wv~y6JZ< zHMQ;+3Y=S2ujEUbE;uWg*3&Jmub=vGeD$CUjRXTvZMb6(KFsJbPF~!++eFd9ba<;d z=BnbVhVKkbvBT&K-*m!MA@CqzhLehmZ=ek_1@W&u{B8YC1;}~%oxJ+@jqyKG-SMI_ zw}OuQ2j6xr0J7bDw91J+9^uG8KWl_S2EoHi0C7~mT*1W(`$TugveeAGNi)DG(jtoU ztPc@!UP1f~#0B*I8xTjgq{u&e&DEi^j^6BCE|>Xm(TYQ%XcArN;4^jJZ_sJ)xM%Fo z3?$P%Jo!bs07wA3#0a8}-Fe@YqXa~wrH#TCfzqf&3|4#d3;LuG|R z(9^A>VMIsM%F@z7o#oAd37>WO}5C$$iTNeWr3Ap zZHJV(W6QuIiviWqI%r6c%p-t;>vKN)$_G5p>lVRjiZeC*K~(z9CAFS9;@_J=x;%a) z>TjS6tS)w^#2SlXwfh052!NJbF#CAK&AA#o1d+&v>zdQ{&c)JZv_K+lC6z_CrzO${JlmgXZ!0Xv2ZmVBOhy?aH)6wU)t zf->ka7j>!q=%wLGKRtOM&3Ol;80uWqds9>I&&&QM0v$b4V^aC(C>_$OhJ+~eWxguc z1@-dA#zuW*J^c3|mc2Uf{)uuJjcs}2JSH5u<#)7qu=_qvS*R2PeboOT@5R(yjZ41X zw)CRy6Og@50hyN*5^)n>*NO3)`#BdVTD+1@1t)_TcMiXw^huTYWZOgx6>&IiP6t*Y z?b>@bH~aq+z$-y5QS;6T1WpohMAa1g6joJXO2YcaRcZYOh6qa=XzY5P%x$Z#`5y=Ht)`J2z*jHEE83WP zA?f24pMy>*aVEcWtP8*TM_B6#kaP*LOF2Ke(s`5&^X*qz43Qz9;)k#&!pLl}lQi%= zRh35!7fXXFHEu<1J3BdTFzZd!QZ>^|Fl0Z(hZ>l zF76Fehk43U63Ny&O*Rg^beNlHTY)IC((Cg0`>rK{#WG++F#|l7teMAG&P|zUORcl4 zu~ES*73#5)_*n5y;8_p$?VVD2T$?4 zn@yZK;cwoCHu%iCqyo>-btzU}hEa1d_9{psDAr=Vx^JL(h(~~eiQ@tU{$HKjJR{$DBk}e-`il};F$_TJEtw|eg z*uxP8Bu%R@n@LN3`^);RZ_JELOo+?Rcn6`z%p)%Pf0@I6YeH}%n75;O_Z|M2b_)do zdVZ7rjd)AJL&=MBa}rGn!2r*cg{E*?-?}VBrJnr`?|7?&)hm%M;QA!1%O(&#S1NnV zPhmn`YswffgLc8XV1Kti;f&FBJB1UqimS1na6BRxN#F|J7aJ5Y2{>`@>Ou~5#Gc*5 z5qFt-K>`%<=x4fYfhKd0od0YcxyftUsIo<;pbUTqb%9$;lj3S|S>p?1E8Rhue4x-# zhu9I9``wLLN<~D{PXHY; z7Dk`G2}ha<*_I=tZNh8bvfEKCSU!1gq4VX$Z=9zYTTS+tFH&ild-M>F%V8ROxTy3S z$b3I)(HxS4J^-+$MYtuHl$W%}dg}7qn%YMTw5;)H&cBWBVuIoy#70D!^%VD&BY?!d zkaPwZXKA6s4aY%Rh6%BWxOa#dfF9?!&fi_ACWuFy{WCBQ3>*iycEhYG8|3wx9b-eE zF~|W)n{ep``au{E4^NDp*V7Nj$%~QQ*y}~ZVB9Oeq6EcEzs22)>lsz&;`?4bqD*_@ z7B8g7A6=TOg#7}dpy-#eXml%n)rQrL{LAR>0h#@BoFCK-bhs16Kv$nAN?7lQuURAm zx^eRF&cFW0HXrGe@KIQ<%r^!J+>%fK+_x8WPvviO`;puir!gVg?iT+vW$HRA z^&xA2nU)5wHw9}a8a7wT_18MazbsbDB=*Y&%J@p#K|a9HE8osy@39S+w$^oT2J!$P z^_Tc4a?GcH5t@sppoTvIy~kkY zXA{4H>1+FYQtO&VcN{Le?2n`as6>DAcB)*^qp80nycTbs^d0C@Nr5H6dWUj;R` zR#k)^0JN(`Fst^S9fE$FH zh0E0&ej7eO)jqEW@wjDN`1dW=3N!~md%Za;buj$dMpK66l2Gy&(B{gDRw|HVhXV3I z!&5fWMEg%|cDMp(eyef&pMq^&HmEabu9PL7a7xE(AG`Suq;=)zQfkP4Z`QL$m<%6a zSlFGV{+5F?phbtb65#?a^r1lMe0X%EQT6$={o{k*lC8p&5em-B1H9TCCBKiLQ+=Eg za3$y72&4l0I&6)CCqR2D6GEx1qcmFWVqTk>IsJ1=5&#LsEBVD~+mj+35QLv}{<{Dg zuthBvF@Cg5W48CToD|1e;+3HyP2eYEp~me0^pjP={-E-ZgvtKKY&~=Dy^Z7Ij0xvQ zxrrsI8oK*JfFRYpJI0UAp#`1=@J1V$2B!W6H+5FSOaJ64t?Z3*LbCL))5gjyRrHCr zIQ~)w|A*@L;YP;as^5)`0C&)t$_wENUID1AZ+Mt7;9xGHA9^XhI+NP~omK&Du=zh> zowf&PcX$61=UV+Y;@l?KlpV=k_5V`!YHk0m>isi~I?tv^X6?xRKyBy)N?iwQ$d~cX zdqxr2{}Rwj7#y2GIK1ogT&-MzLeQ|uSH?zAuFE?C?evAs7|sOr|EkK>e@$F6I{Sn3 z+a}#V^I$&rs#e(#6eTV0<4t(ZCRCTsy1`~SEA6Tjg6%(}GLyrfqUzSrGARA;Ww9*B z=d##N#lsi>_?;N}Ytd;D_p>NK4}?1;dFWi7F;aOlcP?AC@G=n#bUJhsb75-Mfn?WO zOF!Fz0M8YO&PHA=d2#(;%GJs5*r7L2Iy8k&aBa4`b`S$JsZsyBz%5j7%;^6?_X){S zOa(!F+haJ4F$dDus{z^-j-#~OF8~f z7FGU#Qat+l;9)EiET9PeX3rS&2 zP^L*Iwls_P=@9Ohf-dEm`BW@$q%9;N|tf_Msx&#-Z1V|FY>sNMv7J z%w)?BR3^baF=rJQpIzy>qKhpFY*JyRLdFoSbNEC8RNm;etZ>PweV$6!zu7kOAaXFO zp<8ptib1pTK=@X3w5uH$Hs8!i*JFd*O)8+|;*4sFR+A`|Il5RPMue2yyub}ug7%R? zu0QP(v;ir}=pjHQHyU5w-bj>gP*HW;DT^TMDw6j+LBha~!8$5Ob62*cO`)U!St_I! z8$ZAU@N_)nZ97FVgN(#wd0dLYCPmT@8RFs|y3y~h0zh4ConU)iRFmNEDf|1jk~)bl zd{cXcmJEZ)wHRKIH8OkVs>h-D%yuxBW!t@K?_O&{;;wC>132e4kT>$#bdK^5w5^&1 zT+nRQYd$!QN46f!xDV=*{>A{hKI|s)2>bd+mL>*Fb9>9#u{(*XXr|^RqIjdvc|oq| zBP*oH%|)7XN48$SdmG}x8(M*ytLfWW1N$8f42m;6I(Z4lI>R1y}W_k=mY&8 zwTfE_0Lv3^Uo&QHIk2BR`OMg*m^lY6H>jp(ERoRaD_YxUw&PivYj-IdoUWOZLRd>| zrRw|uM(pHl0U_U#rj9^4Nn=Okt5AnzY6C!VCtP2C?0wv0KeY%_?9nbL%9L{WHu@o0 z^#0Kt{g(7p1^3153LI(qy*nMdE$i zeZh#0Ir`}?o>u9pZK`kHy57k8M*!eOEsA|w9_m_8$tJ#8SU#a&VT1iQKE{1l*cDiT zH~Cy{_;*~_#*L9kInjLon$8%zspPg7f)V>&JPU!%%YEoshDxH1q+V7c`%VxUlkg?* z4xOdEy%s<^5UA~_RrDQoRMXjOy*bhFp^N6L(UY4q43%~0@W3igv}1E2(|RQ{f}0Ed zJ;m!q@cuPNcjpZU4f?%7K*v|nO7z$`fF@Fyr9BuB(9i!sK2=hbFjy^7BRH{GIL>gr zZ%_JG3&-xt#iE9)Lu_%G#x=Oq8(9 z+Fe)&l99|K-eQtU$$~Mp<`oGCD%Q|QxFsvAM=o3Zp65JH!lKYlyR2>9Nv@L7=9qqW z1SX&8xTBu-rHyD39wNYZlX?>2r;rH~jKUj6QJeHpxazw>eKca}M}z?}Zj{J%A;Hh* zO8reX6*?GEqb0GX7@taj0x1W%5;FE}W;~p($6iUSDSu?KXEr)IgY#oi!AfJoYy=0> zo)|(ySxIp^=jQKCh))smdQC6asm?Z@gw-?Hf+^YL6J_g}kmeu<(#Ez#+?1IDxAp64 z_RFz?%1Xhx@rAg4Yd%J$tZA70Or}I^!q|n&(=<2nkpVoM0-K6lk(S_}@5Qou2bd5o1XwSddNt4iLY;k+FP_q$o-EkBfOj_3dr3xeMRhlCkvai9EbKSOe(5 z7oCxnyz7W!tl7Z^RqJF}ChKsDS2L&f{x>^U9CKtA)*B~q;N-1~^j004dC4lM`f z0%ck6!f9f)DbU@q6xEb$Q7B#d=++yKOx$i(d7p%=X?DQ-(w9`dmkEw7Mn5ffM*w#s z@NQlwZVWz3iHT~`JBy0ps=1>3N|Tf3G{>66$5*PmbOLS@x-wS}QpE!s5uKWG{FK3# z7X?f)0uAj*ZL{{4yK;+{=W*Y3uSGo;%UbwgoKxE+u+;`18Tzmy?(!zEOH&$Qee=u< z_R>lwF_&N`zmBo#8pqcml^$&msW)Jd4!`n?;|$zO#;?$E)-xz3Bis@~pB*#Hg7eiZ z2tlO$e5v!;pL$U~^43pxOkwe(9n!#eRy~p5RauX84`{tR^-nl+l${9!=yq0kE3Iw7 znPER}p+(=Hd4CeSi)U}LNe1wU269YT4=tin1{DJ)2!nz_x}@Jis)f1D*k{&00y=6w zN@hXiqAUu`v+Euu#4ZYEaC|6K$h4R#vF%Tzuh7O|h)OaW5ho-1`dMz3cbWD#A|*Di zv+0vg5F_af$W#t5ukE*uZ3K^9srKV!&9kC(TFln4v}ebt2KryNxu5;D(tWITp-DVa zbSbgLHQ)l_a7Z;v$- zIL5G?B_f;Yb!)_|tY&}eom?99fW^z=UUrP(4|!{+4rN~L!Qz4=)8!$|5EsuZQ^i~y zIwNXz8CdZe(Pwz6r-itVnQm?nIobdAsEZKu{CUGSJLP3F`k*hIx8G)J+k8DbP}LVN zt2ta1ad}HN@x~{{Y08RJlV(T?d{nsZA%@nDbPq0?av1H*nm@qVGxJsPqT}MW-UjaH zO#cA(FAGjrR`VW?c4O0Pk8eP{-2KLH*}jEdj3Lk`u=lTi3=EOd8274RF|`R97-qi0 z+!>9xA$dLli*q32o&v`#s)8vUh?-KcWJ{1~aL7$XrV9e2 zTVqMIY=I61U1Abxt+&v5FL^&Wq#pjBB;xb4wl^*BsJJX{x?>(0-JJE<_^GP5zxo{p z)LYNlApd;%a1FK*3j1aRmdUq~C3sH~&RBk2zKFB-KS$l25R?9{YsdQY~JgHH-C&n9!Numfqiyar(@ zMv@2*r86Lrt7F{~;MEiC@WOuU#nv?3>pF7QPV|EDcd=g~x=!_1j3SY$@)))QswpZI zQ%mdBC?-d^@OPN`j_FMna0_?&x=X8(S@X(W0a*-n3pb28QhRDH?n9;d$#|B8!@8&r z0$ggWgR@6#+&}|=r{0}Xp5e}3QRkH!ET2%-cy)|zi9ok(I)KCBh?KGi6-yUO#E&*q zhAW#~1@{_IlieWzb`w-NWTN;9*=v2}Nz>UV;BS5AnEHbyS*v#p5W5q-MUyNqTGFQp zeuV&AiG*xb@xFsPgAGH$g*MU#t1+sqo-ArtQ~MoUS;)E$)+8>g3=9q1MW^!TaX_BZ z_KOW!fE+65Q2+(fA<1<6OYD?v6iBgZ_g7oci6s5K9}U^IO{HZEUpG+pS7ujo6cBLq z`;CVZ_vDVk-5bKJ=Zf6Mhr07_?kY{WMo;k)uT>X{iL3*&SsqLMazFbEE{=SADou%G z-d{dkz@WDl#j=3f{!l&^Vpk++$485pkFbv{m7FZJS?UL|IRR@=&cZjYkm9LET+PJL z4mz=-yvM3E#&ZZpUN+Hc((~~&YoPwcpXQlK6;(+%d`0;WPpOFv6OL<+TB>|>so{a` zLR9Y3m%Al;+T1qN-oI{tj`v{sse*Mc%1uZ_qEJI^DXNA9@KIk+ximP}Kst|a=0`4G z2tz}0M?jaKnO*X!8;)ixPYR0`0|m zM0{&N^$|%+K-|c;At`C@ymAZL5pF-9_te#V7*WAG7j*~RhCo<>B|;b76$XRXD(>Q6 zBm1^GE=GD#P~>?#?KsM9ivywW$< zrNe7B3mD0>OD$Lx^O*lD!+SEiPLBNVAb+I_NB%qX7((}jxK+gZME3*@k5R9@s2BkV zR8n+QWv6no*y9bmM>v671y7@pWMhCKpOTu3?cX5DHh&lKmn6FXzWYA$qXJKfSF@aw z;?9!~Uss1WO2RwmK>A&@&^w>y+gFx$D5rj1*t8xH+!io^)prH=ZVd9)xVS3pupBuj zqfpkbC(T)RMO?fvV?B#Bs^sODt8W4_2!(^IV}1BTO@JYmi~_;|CT|{u(FvElwb@7l zCdDm}Ij)GDT8U{7i-gNma0IRhaQLINPCYyWGI6PRd+*AJNCM z8ToNYQ6ot`ap_{lg+zkM zyM$R_Moz`Z5SWx9VSSp?H2b^Q0Fwog^ez1)@uGZ~m{bMziPZ0pIEX3&N+d9!h|(Gq zBe;=lh$|p-K%z`N6CaPrnO(X0{53*E??r|2!P?P#u7Q~xlVOwN*bg<-5 zPolF8DIV_c`Jn}=k4f=ai0LV*ee_trWIT~QO*K0toll9%@`^=<$m1_(sYEhH68->wn^N)Fr4lOoiURGQ%z}aLz@uxgGpe=$-uZSvUuI&w?lXWQ zZ0rx)YervJ8xRS*wROq>?1)@3KDZiTyZoQcvHlHrQB02QamHrydF`>0mSMlRx@V0_ z?%&FC)BLH}VC;o@6nM4HOqKjtw>w0JqJ`Pc}L zm^Cv;2J;)DN`-`f=wcGBz4qs32V!>pw)Z8*?Q-e(;^#Ve7c8Yu7yNQ*GkH|1-T>)3 z6`g#OkU>(H&4J&y4G;}t3~UIgX8~WX7Gb<>@p$SZ?U(JPms+3boQ7w9r2P=QdHFl6 zmk0ABMaas@iB0II@apJbo7H1%42QIV*M?jraebR)Jis1T)oVZ+6H{FvHdf<_?l15! z*?RKnuJD`h8FjU<1(TmV85OgC_EJt|g7nNp3J(f`(JWuhCnfmvB!&%L?>qJn$5<9p zp%wY`!JlilCogam(cWm8tPmDo>mKZ)Jv7)^{4_S@n&|IVeMnOFKT?AqZj;tMX1mSgD)OH&u%`g0mC28lkPoS50t#{ItEVC%NF7+5ibr!0aVzQvQ(m04qOZ9#_*0NBx$1NqM-P46PC!nB~)v}+eE=}eP+ z;tBYn+9j!Xq{GNF;%1i;sm43x{r!cGJIrkV0a6`weJUP)Hb=h6EclSh3CB$1F&`~j zVq;2SNL&4O>Mmr4ct*0F=rfaAk5*vQR?-Mj9FnY#pv>XG*@RgB6-fk@lGG*C4WcfA zTm~O;%G+&PouR6fhw_B{%*4eO{fnX#l^e|= z6WVX8E>;r_Zco)qlsjsi=BVa$QRnTNz>3VI2br#SAl~%(oB(f@u_MeLjC}}ty!|sU z=EOtbWCSgJ`u37r)&7jhksEeFT63J7ii`kkSntV3PY?pwuDMYw1$DgmSB-Xc(~Hmd zmMEaNOV&NU3GW=Gn)9x1zJvd3KU0yYKM3-FQo28#s>WL*FxTz~RgUz*nRN-g0YrM=p7q%#oOh#*%O3v!TA`|wehBl+crDY|v2@R`Wcju-Cb zTT!v~Ve3hlu^w2Tqpj5hbH*c1*L`(+C8kn-z!<*dlgtVdBX$R=b$^M0Zhe-ocwR6+ zKK96tlk=#>-U_T66Uc?O$vEFELwQ+pq&w7@*U}wS8Pli_-!xoucSYBDE!!kfW_o`} z-0|iW&v>G(Gw+O$L@be?szs+V`@QjDYO!$gCFy$cH#_69j3IL${tjAwF;h0YykWTc z9#)w2`)oh5CKxWV!VM)_4xq*oH3y&(xrzJCl>qzXpz`o)DS<4~R0wtA!8(-U*}s>* zPiIXq_iBj+aZ42mWl7k_UO>jZx4BQ2?J9n4oDEc zV5*(jvp`&0ZAra4P-{5XCbZG{>>5V?RB}$$5obd`lqkd;xq6L@vYjA~_yJ^B9m0L2 z#~mah0*C`i_+IRWUk`ja7}Cc|<@sHfS6>&8b+0%_8ROqSBuDJJZ`=s9#(-AKBARkH z`nb>7D4q+x2u|=|iIO=MMCL7qtwLRek#+1eWH<=Y$T@_z`$lJ2weefdpDCQTRXDU@ z&d1^R`-w+ASuRJ(ng1~X9#X)l`);>Y8XgkoKmlmLI-3#Dhw;NJwZRz~*QX&vw`H?+ zLqZzTs}tR3-1Wvgozf(TovBGRDs4RR(NDD(}sE3L3p;VrU#TCkhU?71t89 zf33WSmC7Jq1fMeR9Nfsxpnnrqe9dX)P_QPW_iExr53Y+DfOv{AZbB2%#=Bu+eCbB* zV~k-6w?tINrXCfxc#C_O6;>z?=-DQbjZjD;tOd>u*ZEgK4CQ|hq1PNzLIwDejY3H2 z{w{*9e71c1OjFO_(;0Keu_0QARU-;-14HQeJF3&}hRjlPeAwvIz+daoZQzy({&qxX z3wuwlioTp;s5#sLB)ZKSz9)5{K=lw~kq%dU@cLV%(Hox&gmi2i&u(#c)!$`N$MS#K z+21VrFg<@^!RBq5!z?0ALDowZ{Ftui5yG0{&rTZ2^gB{z|-2_3tzSK8yW08$%w zAsql%FiL<=e>D%f21gx1~jp0+C*?s}lqnagR)f=&*Y5(q| zkHk0W+`NtsYveGb-b7=HMN~XQ!isCwY#ju`WQMdLbw-YWyVUvWY|7O9ZOZNCAvd!| z%31cU`KS9gx;GC0N*OMlUKZDR6L?@<$cudsTZuh4t3fW$KB4lx(3YRGReN#XC2lqa zRmV~E$iD$}vQ*#|2w6M#KMT-n0}q-J@J%CDezaFtTkGW4b1%rLSeX-efld+W@@J=hva=lS}hq9%D}VAB-WBPY>YSv`@}NBu;5a=7$~MK;kE7m~q>RS_>BK)glbCDh^8N$_G*Q>o2xww}k7y%_UJP~6cx zX&v30wv|eyyl1YuzUz+gO0yfc+pP^fu@4=p@{v6kjwDwhl=6n|ssxY;g{Iwlf z;AH2RogZ($nPM)Us99Mgv3YC8$WKj)la9(x>Af9Mn7R749HsTA%*%C^e-&V~*$Wek zAEuiXlx(j`Aoi9>aaFTJYG9NiseT7unAZ}qCqrxwHsZEmX38r(BX62KrL)slv2`}p zhm|lhvtR0XX*yc{w9?(@fpKIVU^up$H&-|Ez67eOsIk8+)Cxki0kQ$b_s2ewHL`uO zuL6^5Gp9Q51T+TZlST|K{i1Iy42@Uk3luQ%>3{Af%iKSH^rovZv`FKMfB|n40081U z?F9f_zsM7Nk;+#_`_3$1w>n3N(uEa&{-mQ3>6nqe5M1YF9Sqsv(g=MceT0*Bc%aD8 z3I`g`Dx&Z@e!-am3S!eow2u4cr6pL$t5h9R4JF5(1D*i%W$GU@X3K0}R@7}_vXU_# zcDoy74M{Po;V2s6Fu~|xGjBY7Wloq_C%}VvB^m*N%Ed9-P+pR^h=_K_{u9jqa-=res&IkCj`1gIkccGdR=PcD2Jm- zCMhLJK`J|`LV(jNb7CjPToSP{6~z@1GNPLL#q4hzWeig!zAJow{IQ{Y(roJ9<3!+%=*4rksvr^pYoE;PC&1Kl09lNd@V7- zRqzf8U(lkER;+A&d^HOSL2Lzier0j3_;`UU{DNyZ&2Fe7T?mK`L=V5iN211-LIuY* z>l5z-Do#5n=B+PgeXEo;2PNI2(_E>MEvD?)?m)c*U~H)B)+l4-TD!@3;GfE1Kn}9 ztKy2Q{hfAOwIv_S)z{*h*ST8^$j5wa+#M%a^+g5}BumHqofNU@?dFiTat!C;Y5l7T zUVFdyPZ6DA*}vuVE}o<**u9eE(T?oOJ*}#dy#4UU!i05FNHRtTR+J0?iuB}rZQqGv zfh*h7ukl~aqA9CIDcZtVxjQ^h=K9-2E7INjo4)&f_Cz0k`?W(tu-rNSk;6jqJmRd9drF#~Fap9E z0XdR}fZb{fe}PALxW@D^9ci$A5BBQf@_57m8dFjA5K=!a!v77}(GVfY*{fwi;)Eiv zS+4tCXY`MY8rT0X4L;lBh###c%x5v?--u4%e;_&)|Apv`1y3z+@J;6|pS#bTuZz$N zM?1FdH-!x2?v_h3aG>F6ojcXGmED1^{1Mky`HB0wNJZSl3sJZLYIY)m+66>6>5gsUvu!0UQjG))VX&E3M1Y`H<5Z8SC z%rvQGWv;+>Cgm=*(wFLimu+zP#-jV@gkT9qS#PxpgSdemkYhfQENtCuxxBFs*V-8# z-C~Frl>a7W_0#Z06)^DtICtlj^5*)+?%Rz%)AQjkf(h^fJ}~^B5%8~BrXLRuz;Dl2;^xLNy0UoR4irFGZ%tawruelPV z$S$~(*Wb7vG9buX+haWC%)iyz(5z)mv6N|EIolAd7%Z9>GCb`LG;j-Lp7H^6Tb=RF?%ckMndfg+GG0%3rQp)DV=z-M_2Otcw%d+a^&EXmqb67^oA z#lXa0^)z2BpX`oO6b^3dR?d#XdAdHcpZI4 zf8I8koiEa4wqmu25}o8ZHaoOuHPfS^-ps$x8?zYu6ub6Zq zmFL+uptr&eWaS(XMdVX+Xn-*f&NrUmG`M&YmT+$)*znjLpjzR?_s~z6q~6lkyjnQ4 z8V{FRy4j(s7h?hZH`PUgIMT;s-NGy@dNZ&*JgTY>?NWzAMX^MYR5#E(=U3j;v0F{K z@BNQEes0hU${4<(P{MGe%V?_%?pX^mQl z_J7;+lX@Pv@PxFYJJ7QZGa9Swd5lTgi^=N!x~1S{G~9`r8X;fxTY{zl1>nRX(Y2{} z(+SrI<*!3x{6E}ztxFm_GVpnU8dFyhczm&;$G{yaF;KKnsxe+yfoVGJ7aHBcHwpR$ zG!qC+=R7_SB7OQUn@pumSeC;tMNGo1Avjr`&=74cCBN8fP4PF) z0`9hjh{VlUR6snz(OhY{pUfXuXmD!^yQO=@HDk(t49}`;0BoWbamepMu}tq_f8%R4?xnh2qP!!heR?xFpH7lVi-WxQSn|-?a@qC4wV{2+j#@;V-?>=@~r0t@1-v z0oI#&q}7RUBa0;`jEQ3ixS@PB!AwCSuvslJV384^u zdXi1QcD0JW{Qoa{j5-za0kvKTlw8JPZ zLy0kt7T@R7ZeF$1`9Vl<6856u*9@K=rNdT`=T?R>SGVK##@DEl&}*ZdC2D+Z_J1L{ z0NId8knvu~b6vk4hy5M$<05&6LE$Mx-Wu%tir{#uPYu|H~dn2CSvKb~+B=(h0n;<S=rqf}q zR3eagv&202JFi5cm+41#MU7&aaz(#~beT!tp~N=OFllNaTTWC3woFlqZ) z=MY~0+TR+yCXMj;qZy08vl;B{J(%v1W0lirvT$YrH%V=ZZvth6L!EX$T51Nmo0uuX z^VxIVi@P8YUv>x~JCi+8T&-F-H}VEx8#xDBlB<`f*vJev7>@RL`Jp%MW8Xcq;+4lz z^qq)(Eg9j8=9^CTdJ%T!i_6Q+0bW@QBTwA~nUaD~<_gF60YK})NV=1?)~*%eZW7*j z9XCOeq@d5RQpxj#=JL{5y6R_69#DKq`AFkILnLS~@4Xno?j&G!w0-v4IC#A%TfF>m z7PGgrBKRlA?6J>wwNM{9du@Gh+TTk28Th#t#7IL3t41A2auYHVEcvOu@{^rnd+wWu zM9*uz?7J+h>o~b*=&*7iht(gM|7*DIk6N7q``51Jz)f9tPoOjmH;x~CFvtI21wcVY L1^)HEq3{0zwbTRW literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/overlapshapewithopacity.png b/lottie/test/goldens/all/Tests/overlapshapewithopacity.png new file mode 100644 index 0000000000000000000000000000000000000000..588e1cebb471f35772de4dbcc173e6f26b44d570 GIT binary patch literal 3335 zcmcJR3s6&69>y=OR#q#lqlG~v)OroJ6ws&y3=ah>Mxxm2MidlF@YNtl5D5tw)D<5H z!DJ;M3R+jKt03|UkpyrN;w3!m8jQdNA)o^0LV{d@h^qVzf-V6wWX3^KJ`2m8=hQTMz{4+2USSYFiUuMxi`1wG24f9`uVrsMx zeTz95@#bNtAn5bE^fjxua4)`k(wN*Ht56QLNSBGPi$9%tf+K#W+QPnAdO(&9ls5O^Q3?k&#|;~peIWtR2Z;X1=b7`(_wjZJM${K}cOAvszB?@nN+K>Un> z&3b=kj0Ua;a)S>Zw?+n=(S_HSk^DIV z?2DPkl{Tb(F$3w$lThN3sdmteKOKS=uWB;846UA?IOP*2cEwOrQxSnfW^rlE(vwtD z{Y$GG6TRMs5Dl{SQI;y4L0ZqbT%9{pmS8w1A3B&E6pg7QF1j$+61l9dMjI}AZ6(b{ zR2JSBsrKwBw$69dxLLBStXbbnu@wivnvO1YBxi>(dzai!HaE4I}~Z@}88Ho%(jsC~;M zYF(}62-qRLaH}fBTgk7vM7Jn$E6PkB59o2&P(Hsdx94e-9^KHH%Jg34TA0we=7?H* z;5pOKwv#XH&MhA#)r}1Nd33k9A|cvQR$hcX%W3=clYD<0N$qYc$&F-pxvkVzGf(6_ zLRxx$sk_jS4-9X-kDOg9x zleFux*^Nq`3O??k^rqifxu89+*!u0@Axiuef(@xd+*U&T zUN+^;{0E0>>fy*fMd(p~WbiG)MxKN0DnKU>t_mQ~DNWaY2X-HHvT-h2dD#D!FSN@0 zm<2S=d?hsZ%NNk5#LItJW%daZ`S)!7lv+*ydJu?$w_9-LB*ydXklt)M(4B$lzN@OIP5U_%~hWZws9wO9~uU z2XK}n6ILf(3krwMc*Okz{`Rp)i&l`H_3#`l1vs3$lp=X9&2oyU2RH!X=fZ3!i+avz zrN6#zE#TNucCQ6xrH5UszH(fH3Set>P}^9UCq5d;em#x-u;D2)`+&Ziqbo7)4^&?s zcZi)F!yy!y_#&pQ?`n<62T{Dy@5Pjkuf1s1k%c2f3Qk@Nw6AR)B zOyWW#S=KI!1YWRjw0G!pj(-bxleB~%@r=#+2?Wdi zc;jhRrc)2!d<@N3fAgj9VReaqpd5rsgeoUVF?Sd)gdLqM?CM4)7RvI`E_KHaw!Q}= z7rcI#b55Z7R$?iK8^eo0YKU&}UwNj&vf}D1DFfkhkBav2D0akw)86(I$Ydt#3(v%M zD%mgHsA|QMv};Y0eMD#Su)xmd1u~TXU`vhm09{SgG+$0Ge(L5~WV)#BDUiJ7EF^>{ zZ&4 zR}fN|;88MRh!a_Q* zSRUDhW;}?--v;xRJ%#`f9cxXf{P#vnQ=2!{6KQ4&@;@+pYLPs4jvLx%slFfHxbu8S zLVn?%OB`s(-Lqry^T%-5D z$}?U@geuwNV7rMi1#9%p|KIL8t_Tmao7qN%xAKG;wHfh?klRE@M1v*Z%0cad+(&6v zTvb{){vRDwwlHK868(R;{m>$TFvrvxxo3u5!&3!e>qz~C`Ez(kNB2pS-|GM`+`oMc dBAt7N1+muqnl8mVITAF{zuUMb&u7=Me*p-~F^&KL literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/parenting.png b/lottie/test/goldens/all/Tests/parenting.png new file mode 100644 index 0000000000000000000000000000000000000000..c676031c8fe30504c223fdb60663ec0445adab19 GIT binary patch literal 10401 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 URQV>bjSr-zqV=HizSST92h(X@_y7O^ literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/precompblur.png b/lottie/test/goldens/all/Tests/precompblur.png new file mode 100644 index 0000000000000000000000000000000000000000..1e60d43172a24c3be9e99cc07173f71513fc8b18 GIT binary patch literal 44003 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 W*e9(BIsgFDCE`fJL`PgP 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 W*e4{HC5obeOa=jw1|i54kSP)-wUq!uv_+g4 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 y+515c)ZLoMES+ literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/rect1.png b/lottie/test/goldens/all/Tests/rect1.png new file mode 100644 index 0000000000000000000000000000000000000000..77a3e831cb569e10b5c6f3e465b30fa654a74d5c GIT binary patch literal 4511 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/rect5.png b/lottie/test/goldens/all/Tests/rect5.png new file mode 100644 index 0000000000000000000000000000000000000000..763afe8333a50fa38e7c5d421d3e5e024554549d GIT binary patch literal 3892 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/rect7.png b/lottie/test/goldens/all/Tests/rect7.png new file mode 100644 index 0000000000000000000000000000000000000000..30a3a1a617df7c1c93a1250de716acc109e12762 GIT binary patch literal 3459 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/remap.png b/lottie/test/goldens/all/Tests/remap.png new file mode 100644 index 0000000000000000000000000000000000000000..55eebcc876e3f5975fb8c69f8054f01f32939dba GIT binary patch literal 8505 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 Cy3bDl literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/repeater.png b/lottie/test/goldens/all/Tests/repeater.png new file mode 100644 index 0000000000000000000000000000000000000000..3432c01f6b739427f1cd319055147e6304e6d67f GIT binary patch literal 20413 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/reversedstar.png b/lottie/test/goldens/all/Tests/reversedstar.png new file mode 100644 index 0000000000000000000000000000000000000000..9fd1db34d0b98b2f5a9de7d8b1bddf6fbc112910 GIT binary patch literal 7476 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 G$NvE!@urag literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/rgb.png b/lottie/test/goldens/all/Tests/rgb.png new file mode 100644 index 0000000000000000000000000000000000000000..58df4291d91185d7719b1887fd8305bdfcbd29ac GIT binary patch literal 1746 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3Zfvv{V#WAE}&fDvbyv&9IEC)+P*dFp5O2}|ceD`p7m}t|_t!cIC-xwJB zzggKbFzoQVz^LFbiU&Ll9@JJb+_{-PKaSypJijah6U!(b6k%}f&CTWR3?Cf4?cN=6 zW^Z6{9L0kn3>r)~e}5^+aKKc~ih+e=6c36p_`~obi(6{5rPyR(y~N<@>gTe~DWM4f D(y${Y literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/rgbmarker.png b/lottie/test/goldens/all/Tests/rgbmarker.png new file mode 100644 index 0000000000000000000000000000000000000000..6ff09aa18934819ccc66872274bd982589ac5b52 GIT binary patch literal 1917 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3ZfnD9x#WAE}&fB{O*FN$RalQCjj8TwDQ}CqsS;>#W8590Qwf&mCb(yO7 zQmba$FFZg4U|>yBb=ij*KWEN-UA_LZ>9^cxbx)Y9=bVzu-grFf&BkfVt7GD7O6JbI zU0MD}p?b|xi1eZKXd-fo%_C9#V6lSd*^Pq;rL3v_lEq{b28?imE#6R;=FesU*%_C zpSg2xxjNq_P^5~1;!*xV{R;*Gg;7k^Fes=j+_wLt-2G?f`Pu!SZzSu2qwrBKBWlFK zczieJ&9ixyp0+N3@7eD+(r5o(sQ;!=4V=v^_Z_!+Q#h|S?e}ZB_5Ze&VP?U9?R*T3 zO{18qVK7}h{kQb{kGXZ9w|%qd2j@OuEZ!4?#TY96pyBP$i;scv_kPbA@tf(}esA=D pQ>X+hCP#A~9ZMG?a^4U5AN=Cl8N3^>uzUx_qo=E%%Q~loCIE*`?VkVu literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/roundedcorners.png b/lottie/test/goldens/all/Tests/roundedcorners.png new file mode 100644 index 0000000000000000000000000000000000000000..27449880340510bc4b943c9dab6da39d8e540143 GIT binary patch literal 12568 zcmeHOc{r4B_n*ZUp-m)>L{Tb9c0*E0St3ccQL<$lChIVUZ>5!1dr_3iHYNM^R5Fz@ zh%6aqGT9lsks}TC@d%`2!TL^ zjgB0&fIy&=;P)*7K5)c3?@l%N3yQHYJOIfdOZ9_)@L&!YSqgwxsKB`^5XfeT(LsI7 zpyc5Wj~jN*n}}m0>zWGch3-WjWZXjEw%xyLKlY@GwDB1w#(Tsjygb zW=CBE$#W?amy(?WUHM4AuASx8seuCV{K+ea_{%n0@2R4D^EAVi)M(}K280RxB$oOj|wxO^BbarBY?UaL=$L5j6M=PYqyP1DDho!7ZVNM%f3AV z%ago$kEciZ2DJ567RmJ?6GSN0yEbE+}DEdgYh$j(WP&3zgES_00M%gpG?yOu~YFOpoGpnaI$cb6K4Z@L09Ymy0og zc7(~k1~3JB8}ZBSf}-(5}6Ch0{W_6mYVjSAc16*(G)ILwgc7o&H;ULYr-`PjOO0LYu@m zZwHCw37d)Zc5zXIhU%-Us3buuQo%VB{MDjVev)W>N{EPuAA3#Ed}E6ka1<_G8|#kd z3>nARpAbEMNAZ6@O7^R?KUmY|A&P=I;CJUOj(X{OK0kA@V-Dzr7NhP@a#fZ+VjNgb?0M32=VXu4cK% zEMc5nj!nELRFX^VTLeU+3yg-uT8&Fvg=iitId&Z$KXygZ)#`Yzf@fRLR+ireZOSzzX2u z*A`92?NBqe`3_8T7~oza{2Jta82lU;kagt~mE?Y9LDFz8PJ1x=NkhpA|B^sn9oFZuGu54!5bt>5Y?>IxJBQm z^-xITGJ@}+!f5cuycR8oMm+Ha;uE{JhAbxEmNq9hC~DVC`=#?9S~SJyb*MH@*fV4l zXjS+)9#g-DDGT80^E%s;e@r1ds`wZC(@3-K7HyOD5+Ru!023sq0o z)$_;v&b*?iRQx-*!@4W=Hkoh{voHsX#nP}?Wm56Q&_IEz8GWGCA|!UBY6OsBmyPhJA6@UUA&$gL^b@4WOC zHHV7xcs|=)eHkyB-bpR`bA4wqp0<9ZU$z7%w>^iH<)LiI zi13UBAR~)#HQ_~_$=>dhL4U)w;J_>96)$8M?IvFKvJRQG<4S{#{Jlzy$?qDlo+)7> zM)j+_TZnoWuo_LgMLccQW&FUUae}XdT}l^i+CuxszT&Z_*A=Jov~@hp2apf_6f_w!%JJ`>Q`OA8OHc-$t5wvKQbwjEVW z_ktD{RL(g}zX~sOksb_O7=|9(p{KcGF_OUTg<^07cnF_^y~Q-l)xLKivJOPhvxGG= ziOOWMZU)s?_tZxtqYqq54#1`bW}MzgWKW#~A`!&UqPqET1fdA0LNX9t*c<9vkf81W`;COhmLufmU!06)X>XI6T9m!cDUs%`$lB(uRH2?$1k{7pAW#u>ok5GYBt(B z!b%(xi}Y5SC`$8VV+RJi3dy1d?{`HX)iE?D#s(AkD7;d_LnnHCk1YlGYT-nb`;c&! z8PZtV77v#kwHeTV!8KiU6UNQq3yL@ADAHK8Jt9*cd6*M%?~w<2?Igjxb=@@Vkw;P5 z)KtZNO_8u@^266DS_jXWA%lDdFn8|!4%7EY9%rQ*=Fu(*rKozPjp>{X&{tF+njt6R z7dn7R{ZmavibA#5b7sy`1e}G%@)&=SqUYmAg0*dnf1?yi8V(Z@wuhy*x_p*iHQ0xBASi&ZoFAIK4~L29eY6Tm67* z`FV@U$e#z^V_s+dm+``Dy>6#%8|gQ+x!KT^-p5;>6ZkpdZ}Ey$Q2qMmNew!gYmDml z5PfPXI3D}=xZV?R-1KifI4jVcWc&YEwqax~tOsfWC;Zo|_AtEC*kRfNCl6;iE7hu#Z0TO4PFZF*-(0{I z)~RhYV;aOUMTQ!kn_s9Z9F!HgI*^74D>l3e=D^`^h_Ek>va}a?e)!YbvdPZW{|oIv zZOg(g?P_Nj_PTz>XLdgSLLNnizzW#Ag61S>)O`v1JPdmtC0}AVjs%+?up=-&C;AGt z^9a(7RZ^HPaT8xDFq9ECzkOE6zkU&u7@R9MoSk1cvKn0s+zK9?ToY-xgAh~Ze-(RV z7qi}m@hG2S;4xh9WJ;u@Z1AUx{kX7#c)X)s7^(YIE02TAnaW>Xpc$6X|33pt9CJ8Y04)5awyg@it zSZXNwJMq{}1FD{BqGEO?>IRw$KbD*($lp!rLG*KW3YSFzQ^KosisfKjdi}r`GIsM{fIO%ZRJLu{Q=W^2H;cQ}B%~V~mPYQ4P~| zifhPcI9q<~)dA&Z@yVg~t>T3p7tRDEZRJ$5get_a_~gwMy$V}=Dx3lBuRlA7+qWg{ zNX}fj=#cRqj#t1Q2yCG26Hg1WPLaJ%tuOO3;GMX)eS}hKs5OZ3=89=DL52D5F58E? zrz?4eM0VEwD2w44YW8i<{1UD9sthxN=r6m2;dECuq+*}SR6SwijD(Eb=bjY-H6@`8 zO0rLqPKT$0`^HgE@-X9ewHmEBxxGVHc+q76ML3dOeO@mWdCxPe(@HJiXI%HS-6^Gw zM9EPfTEqFn8{1@WCZ{wM8Sag7nHUC;cNV>~l{pKoRnp%rBJjo^M@$wHqPXf4!(vwq z$@=(*ebi?jc~zn-{^eI-drsj#e#L_T-V;?xN*G(q%Lp_f&p#AzHDk>h)Jgop*;+No z&m*p>2p%b=J#HQ*yiy4&^iMEmxq2_IS7_*Y*aJG^BlG)W@1T4eY4cCGonz}TRJ@y1 zu-UN$n9tCz^t#irU=>k*2-tP$Y>}b;pv$i|UAfmEzeaVweY7v8 zt6c173>UdO-9u!*(UT@*_ngUq=L{$}!r@Yb6$s+#)r9<>a+CK0x#Ei_18ifJU*j<_ ztCoGEC!q4oc;~TIM7vgc5Rq5Mrm+*Z2|aW~ncHTRxUF2(V?)!TMLuS3sNY7zImQiz zeGTllE`=S#)A@856Z=vOXRM~>=9(<0|xTa|uy%_J*cZPNqmQtvU&8D*p?7$;RniBI_)M8P% zgS@Bm` zfHT7Ku|-6b|^w1J70@7+SI#M?2noFjp(TT zH>7#W6sLY1S+d|UESBH%=&G)p`0nS-+$B&O2@??vdRi?}$1{`?LVdBcx`Ja1e&pOp z?1__ChN0Bxo=pDJqFi{eN(`+JToyd*DKN8tVE!hjufL8J5VW?^zxAL~w&fZpw@K9q zjD=`DF<49rLqV<8*vd8bo(!!Xuf!|0x68NLa#XB2aXdf^v1EZ9Hm0??k-t+wlKehn`R|Jl;3n3xTX z64Pj|;H^CHbv@dHRWstO#0vD7eu-mJ5rp*dyLa(in01k7NE1-ntRr4awHxv;Q(C7% z{)*2Fk)jU`VP-e=V(usZ8)A2i!RxID5xW`R&OTpK6pOOZ3%xExD$t;bheb~v@0Z^y z!*#pBidH4sd#Kav<^lW@O`@H|s8t-xb7c|kil$y0JY#b8m9pcgeSb9Z*9%W>a|=xS&j|6Fj@st1D!c%eM{!p>egO3C-9 z&v&T>dFM@)-rOKMvXeH7zYg=xoVg#kh1M2bxqzfK2~JD`yEj0rM8u+)$xbGyhrNWXUQ8 zTHlZn>$$85{}Pj%(DFG0}b)2~8v<)X*@1m<7qALTBzY90D$*JfgdF8|R#)v&If zrNoAeTw5C3=4b?1)+##;G9MP^-RFkUfOJr+t~t~XhR8qY|65!LRPTJoBu0h7HOBnzWAVvyMR45x@9`6C zbH4wr$Mqy=PTPMhD><(#7vT?-M$AXR^YnVxOFSDf&P(8Wt%^sg zq4!HLLr|lT_L3}AR9ZJCl7l-%2M>yWOanL%YtFK;Cz`3&5~x&R(F8m4xnlzH`4@Y zYaDe6ub`Qqw5HR!qEY{~9Y|>N+&5bD-C3zSa4!Kh{WL1F zDpzRaTucCuCeMRgxA|KVi%pVr_F?bu4VXpf z(6@KAR#mjU*n4OB+jeZ}_OZ?iwJP?SjD|3dfa+ELX#8+P=sfk6(=tJ@Ob{#+1j_`$ zGC}Z*ty?Ate(lTug9L$!m1YS9vZ{dnSpYVbuuK;GJ^%-i_A*(pOcpGY1g8YB@bw-Kj#Zy z{dHORAk}QMnaVvik0lV--xYOrJzPC*_MCt9ihbYlaQ^j->({9Uh@z3P=^z5jvBG<( z)zLPDz?se#)Cbr`@;U?preJY#G|xYzMD>;%#fI!bzCz1I$YYb?WItLiHmPn^S=~gv z&u#dl9+Ncqqp%6swQhyQ<_@Y3+L&KZC()ahV2~wf)hwT&e=qz2JSNG4I7u z{94|NM=#)6$Tw=~N|thM@-R&&`5v3M-!>&1%X!IpxdVMyx-SKbUK72m;=%onYuDZX zhQ)#8T4CaM&zxGj82d*#LQnLOgzJRTkDzvu(;B;fGqxa>O*4acNq(n?Wirf=HTq7P znB^$pMq#yKQc;qNf_-$gVRC=+rer_zZEfOxpCDz_@92KIAod7wkv(>;v$io8qqXOA zKiMmJmnmw()ydscV)aqH7Q||8Pt9}E%}vmTL)^YBSgUn=4Xl%8M=AvV!qsU6a7MFm zUdRG?pv=NlTqLxiF2!^r4_B?9ZD>8#3n8qXMDdRj>{@ehc%5w8lwmC2WzYG&cvO6 zYY$eI!j&X%v<$Is2O!X)V0-^-zZotp}l&rEFIoWmbhixhzH7za(&HH zOmm85)z&D4eM1dU5gp()b(mGoDtDL6&$?IUcD>xo?n63j~^ZI zh%Y{Wpzhdtd>2zjQa?UnK=5rEZ}Wi)mHHwh@;t)%T6X0Rd}~Q zelR=Z;Iz9!H4J;|rZ$h(=v|lf=7xUV``L!4m)#Lpx>cMF`?%|{pUM!KIL z>oL*H?&JE2o?gajD?3kPPAzPMax2az!os0)!Z+=e$d~tlpF}TX`{Rz}GNz|&wI}(h zW5?-R=|ls%OEKn> z6Fx&SscG;?et#V~_)G^@2RkAr*dCYLU3Cm~D z1N1D!^`w_R-3JTrHF+9#mah3NSE=IopQ5?im8jeze!SD=F7{>JYy(r94)Kn+z*Y|2 z36Tx+TxR&283KBSF8yZ9N)mz9kpbTv=F^mDvg7KL*Bgcf)!V0Bt{nH3O^8;7`cw{G zfY^|^b=Lyhe6W0Ds?;`-f#UXi>liCQ8^y7m1{XP?dYo;)eRlk!Mzw_Ja$d@c&6C_W zwsUV6k84i}mbKpdb*}d{;cqmp5-0BbI?v7Y)6Jyff(6DHDmS1%ypVWA-1*ZDNvZ=1 z-y8TOM76;VS%XF`R&A%lIavI%SUpyY%#MJ^>b2NIbA~S>y0*_P0A**+3PlU?G8!LG*?=OTL+`M6OEm4x!SkCO37e014tB4)($Gc8Vk zCI5`1zu8)qge%mjchAjk+Q>VkAaSEXQFB;1lCL*~j=kNF)g34V`sksRb-<)!NeKRc zw50dI%^dy#a_Bg!u95u>i2Y3*UY+SjI*~rw8>A~WCkEep4{3C0TpxmHkA9DWAeUqO zO4m3FH_ z>!-nx3m4b@o`l;`9Wue7kCvfZ)3kbm#AOd$S@*@YrZ~o)H*;BydHSGf{a#cQ<+DP2 zBh)g&8V_eKX%cz+*OKP22iMdhmMtA_!+EVYIH?H1uO=p(U&;x0xB;$^+2VvhiSI=f z>JHRDK^^JaiLj2r9^kAdVu2dA1!fodBCiagEw=5}U1c}r`0ePuO?&_Dhtdyole!~e z4{+fS!ZL^c4rUCN0xklML7Lc$;(QFQm>_y_&VAcbjn~cYj%%AR!$eTp4&-zapzaay zAuU-b-@#R=CDgsro1L745r+rSekAA^v>elB2l*k-bCT=KN+1$7M zxdA$62D54`JA9TrM9nKBE!A|h73;MzFE`Fm8y7VyCMfwTd_TRYabwa%dq7`o6gVgjTP8sKuSvc*f1+eKm-vT%=J4O=Hx#dQzEd4|KCR zGnsB2s*+e1@Y?y@mpR?DFfu_ zD~982H`kCwctv+sM4^JFOVWk9C6j*Wy3*;fIH2$4`fQ#!TEU>!t3iyZ$L+@dRxjtE zjB(;BKHv0J=ng28b;;MYi81-nK{AhT)^TbCBIQG-4kt`w(SO!aspH1YPb9gohgCFl zC;jSX-q4=BrjzdvEC7WXkd+Pb`2JQji?YON{$#Yr7zXzPB*#%M` z*+(KM`fC0@oo5XO9jQUJqyl~vwTd(<$7?7x$4ngS)2@at^dC&+4`2u3hk|JVb+^C-QTWs) zLxzw&q44R8aHfsbY_irO(4;v1WmFyC{iyAuvD6|UnMS92LD~LWGLcn_=Tg-Z zOimQ#bJ1dSJS8n_vAr^+IVQLB`>{({-}a@k&e)zj15wCi48tH+X2kIGfie2N>-wzK zb)52m&QO)et-JAmXY-xFQX$^RWITXDkcWel@Onx5g{=Yr48$SlV!U#FdS6lwI~=D@(+*BVKp6Q{thPhN-7~o?20?mP(TYtY}!ru&J5HrUEwyj+X@uwVsM#@M2e-|kTs4%9x@uarTv(Mb@RRXkB& z$g1+`GN3VcpouyS;$=*$lBQ>DlN;A(BIa##LGGJ*_aj{zzpZ1CiX?<-rW|+lm2o^v@b0-H4LZtR;|%BNm5^DF zh&xXWm(wOHPsW4T9ASG^HXO%{BiWz(KrXiXwt#?78bj_n`t^E$UbnJ@on5tm4^eqFsdE)HpvgI_S>GnmxcCvN~yI z@aD(#d~p#KdjKnFe&u%x!1K3(?GSC5ao?9mMw@Ww0&AIo~!`^H&r1P#%-0$I+Cpk>2gFB56r4 z$L>Y#qrgcJ!WxGNOSOn~5Mxj%i0d?>Ry41cn!|)uY-Ko<4O>Ceb4H)MhtfB4Ykj>? z!`alw&2o~-Jkb@zt0K26>CO04-bea5?WeRT`Q!Z{A(zUk;Bk_c?g!(08@;QvRRGg13$3{;P=&GMDL>RAeD4EC}_23TRZWlQf9?{Jnh-+IZ3+3M+A^P8A zuA6ch?2E4Y`pn~S&ShMX8oexc$O9A`!Jwsg$yANa(R+rw1x|OrIGfg3uXLxxLUR3^ zT3xI#5g;o_iHy1AK>&g>t>n(Hew#z>f*7yH?4X<-a_YB%w2x}+BObkE%Vr9{x(zz^ z*UMVgp!@2rc2LEba<4`U35k#d)$famN|T=z6Qbotb1CD+n?mIA3b2+b5HroW$*O10 zkU~vmmC1-$!*-0KM#Vd#mT=#k#XP7>qLEA4?KCpY4Gg?bWY%v3l=Wo9DpZ$i>$160 z@Nm;-8aRewOU>%W>ebKdPt%gh;)?sKHiRThma2}Eih%dq>ns~#1A_&9PZUE?~af7stF*;B{as2%}qK%T~_rk z&!Y4%JCs-QY{#!h|YTgQ&^;}1=cA74A+z`7s_>b0lwgNEZ-uw;xpN`s35R4<}G2yT-# zlh!1yF-5Vqk3N@q{G1skfikqHZM@<;kI()IO(2Z8q@SPLPVGf`Q>N7-R54$v%ZBr4 zx{>K81XJPbrG>RwcJZDO#vX*J-mDj>$f?b}?%=ognkr?bGW>r`txz zCuod4PN{|8!hs_4{gIHx-j`%6&+inqy3i-3!N|dMoRwaERe`c?Yh-D26m~afq%<5$ zm1oBLd2+wJt~3pk?f5)U?r7aC0sJ3h-Fi}iX+IMF|5BG`$2~@x5ksyA63mGYfXm%u zrCt<;Iue1PGeAnQW`r5crE0+!4=#Xf@iJgf;q>hcA~c}sEa$?1UoYbmb8Nny0U6m= z95NknsQ+G6KeUNyN&KTSaG4oq8>Nt{HTYK+%-oR^%M8RX6~E^JhteOtk~6lzyzy05 z*@rsApT1JGwI;UBwkI!0GW^%rD8y%Vi>aY=CK^5?bmu8xwTF9VXDx53w0`ID%^d21 zmNjc*PEZ8)QIy>e0eJ|AMRI0jEl@=6BPccyuTrg#%MELL^g5Q)CI@lt-N}9Yo0zQwYk<1~6P@~h^gnjvw)o6fz**s-P?o?MZFd70CT)4~GOXAa zg)pVl`kUh1f9Ne%0bvU3nhzEK2XeHS@jzLT?qbKVGikp!uRonILt+FAvT(?dLXB)K zU~<8JAidXzZ92}LX;&1!4S>yKxZ+CJ8P6Z(<;3lr1b*opm7Nm-V&ng!>Mkcu)0$4s z)o4(dcBx0tu%w(j%Y(g2@mP*8-YJG65q;Jt!qGi?R~_L>rwtbkQMAD3hu4 z%7sdTW)dOS>BHKoxzm?lAo_am9`)04tcBrc2VYknS3R~cV_0Ju(~3gH0dSv_*xGg-km-`A=h~x(KeUy_{ zEvL9v*klW7g;)6G&!A-dYl}ajJ&ZeFBglc95swF0jSi^${h?;=a5rENXCjWL&M|J@`H~b(@S8TO}9s2azu=a)CUhcbO>d3XoL(Q;I zX*mv>$h6?G=$mIO36WTWsATqIFU9B^xfD(?%b}7uGN@CAnCcF6`fzJ;9|s=+t30{o z;8C0X>r-%S@e_$T&p|LBzod{Ryax=|SQ?cAB?^R=Xvl@O*m+9ILHIGG+V`-4uN++? zXX>*py7gheM9%?Kw@PS#UbCbnZ(gQ4w+v^fltL^9E_ zByQZb6W?oXO3?a@fZ&%#g9obVmc%o_zh0DQ>Vx3%>`^fV=1*j*N1vwbR#2cF=Ki&6 z%cVPj2ZTz{`bbhAdUOGvC7#6{EE_|1CGOeDu3+#2L9pm9z%8$(>|H)1D$gSbU;H3w zO(!Y|f>h1yfboutM;vTBo-}etb426h(!WmoP&TQ--o&*j94IRR4k(0d%A!SBVGfQu zhJdT5jo93!Zs<5++A5ZNa_iYE&adfq_}IoaZvP{v;3u8KE(t@pQSH!kIr7c`bihTrM;8 zZmlQ%wiowL_BYftw&-YUKU&S-8+B-udO~t#0X%1WY$&M6V4F2Y-pr}v;n)_JY=$P) zxY2+iIr!R0|9Ul9T`aF1RNfO6qO?&HbCmD+?4_H_7DwI+7|#;GlZ`WILKS8P5e~$*d>$N{y^H0-i(}3X`oLaFupb-==)7d4w_;K z8l>kat)nhmj_ly~zVM(8twcmulgK&jfE0K|n11Fn$& zp|PTX_sU$9{i4Rv2x@eqzoze|n<D+ejmt#1S}lJpZxlAZhf zY=$zs35;#B8Ya8X;fJnmcw8$_gihL`JkfPah|7r;n>vKE_c@v$T~i9<2KA zWOoY$PtRgjGn5*jzF7&+@66lL>C~6itzvrfjYV@_-X1A-P}?7!)akSAsqH!=+x+DLCvw z16~#`4XSYh&WY1?D(jz~+DV~>s*JtP2%JmRhcJjHSW2$HFSWvWTzfxw2k2o(W-*FS z;YSTj+Cwz4>%}4S6D<#bK&nfuTiLi>+YAemaUnWq;?x66AB}P9GgBaV!qP+ewuTk2oD8Pt<2n4k*8y z7QTemaS3TT8MeIVdcr|$7`9j{tF@LOz|%ZZvewLM%t(qwzMX89Q#1!PlVAm#h_uOH zCn2)rQ1RrZCoi>cpFUHwOnf~;jC%XH`8X13DOxAHcfnZGN79jE(02+QFL z$m{h5^W~`}`2Z2;M_TH#HnTD(e2I)uL7>HgkX*a~4lm=Hlz62LZ|3ugjMItxI9RXU0n~*j?BCRf3jlbQdMng9QhncvUIr@Lrr!0^lx@G`dCj;-#$mu?Qg{SQGM!Ic02 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/roundedwithalreadyroundedcorners.png b/lottie/test/goldens/all/Tests/roundedwithalreadyroundedcorners.png new file mode 100644 index 0000000000000000000000000000000000000000..0bf368fda5d31aa5dc448c50ccd0a8e3719270d1 GIT binary patch literal 18479 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/scale0.png b/lottie/test/goldens/all/Tests/scale0.png new file mode 100644 index 0000000000000000000000000000000000000000..fe756412af6c62860ccebd0ca188c0af45467a61 GIT binary patch literal 2171 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3ZfkV~P#WAE}&f7b--Lk0+Z4c8^{;qnXvdnXqg9Gc)V@e4QzZ0e#%@z2= zXl9o6m_Oj+sY`yBZ%5o{6M30q=G&2KW#6^YpfS}_JNul@`*X(ES(jU+^B+F!S6F=S zuLsaN28IS!ANToZPV#%|^~~Pv*}v?`vvvAA52Wtjls%SJEL*DcfSydKZ{lNMWszmz;;>>6v9Ngh z`<=?p@?+7r_D+3r%;|cO{kQE;{#Jy|_d6-xY_5~#XXpFr<_p;kuFH9U`3HacE1AF2 zOnti;Psi_#%Uj>GA1LU%!?>Vf0kZ?6BYOiAve5!13>peA7y=wFj4B`)4h03LzQ@j; z{5pNl(z{nx*FUX$lY8b#JEvwlW76r}`ySNs6h8WU3s`2S28m=%x%Zy*zNfk73+|6IR+9-kh)kd^*;e99i1DwYGAKX5{`EXbV? z(qBBk|8f5O|8t&PcZ|Lj-;lb8@zMpP2U5}pJzL*^)`Oo3+ z{;OZkur1rK&Z8*tOJ8rLiK_X0yU0)PFEHL%S3WsL$~GxkPNw#e{ZU5L;_b&$3x;!- z=Bj*m>yOyEebOBXTc!ry8IuoN&Mddd>%F(FthnfP%lo$vFMbCGD6LAx2MJ#o8qy8b z*Q@L_t~!3~&WuUN7rSqmy?{CUtJ5T)%Wlkg?#}-p1ztY8zdI0h);g|w#*^)g(NeLV zMTK8D{QNI8Zk<)O=iB2cH8u&}b1i>roqT)I+QQcT9Zd^v3kh3>2a-V7{4VgjC$VAa z#i}o-ID#CZSknC$viGyVJP!m-b2h#qK$0?k{F9FmhxM%k+{{-)UFH zK1UqxJLLQgs@N#c%^){6WQ9L}^6Q15cKKJ6{8{Jf*cskFdtz{M=|yX^X9uUm)crbw ioLQhX9VC$**#D1l(aXA)zx?V&AQ4YjKbLh*2~7a+aiTQ< literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/shapes.png b/lottie/test/goldens/all/Tests/shapes.png new file mode 100644 index 0000000000000000000000000000000000000000..70c57e2d733f72170e9f09a0372d93299692c2fd GIT binary patch literal 15436 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 z z(k1-CfFF4nK6#V|lOT@1k1Ydfxs`A>vZPj`4_U%pj!eiB*nS68YM3=RfT)lXd*~D< z%t|49lt|)4wqxp^v6gf1Xbp!wLw(j|;IC8ocir=M9fD(1MQBMJXA*#41cTI6w5}8> HS%v;z7sXA< literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/shapetypes.png b/lottie/test/goldens/all/Tests/shapetypes.png new file mode 100644 index 0000000000000000000000000000000000000000..b34684dafe67689269ddae51bdfc0a2f56078e09 GIT binary patch literal 8789 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 stYF${COz_qDvQ_iMTDTU(k435p9s5F})J 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/splitpathtransform.png b/lottie/test/goldens/all/Tests/splitpathtransform.png new file mode 100644 index 0000000000000000000000000000000000000000..b3a5b3020ec527c373b4cef32e3a4a655326e8d5 GIT binary patch literal 2245 zcmd6odrVVz6vuziVrvl@2*n2ll>!RrG8n?dcEA)`L>>ZC1C$$ML>&X9JjxI)R~H3A z*7BI;jSoP9(ufKOmNq813I!ZvR;gfJ2SrPPf?$Ecu1-ugmu!Ey#9wmn&Hd*5a?d%R z@9*4<06%X7+*%v}z<^5GxfcMPDdhSdy9`li4V-r5p~Kkg?Fo2Y<|D`pn&C+e#vL7wQJH`Bl|;h5iSF3eo;<vxUMvFGccu3;t0+&Fr?}3Iva}T6K_cy)rYBZsG6Q8AU-2p`-E~qG>#cdt zbxF@Z*748fLVcBrnjlBh@cNpC$MV7D+xbZ$WmWQT+8i>=QSK-h$?}yl6r7jkwN^mW z6YTj)DA@>2U|Bg^S8?WRq1id=z&?HpHm3P)^ioZ%rS0zo!-D;Mc5y8k1ztS0{ny5i ziyY&Q#B6zWa#GouD#R_{9uBi*`_q=O7Vm9I{u{ONi>}aUm$f!gr0&%#8gE4tXgAr% zFVC*vqyLiE(_|$uzu9K1-78YpmO`WVntJ5S!wB_t-x%9@y`maN>rd@(*CZwpbMUH|)8(ju(IH}^nMzQv_>l7ys3NACbUd0kW2Vw| zzgl8I8tcd{9_V32c4okm5H6?DMtfK^W#+Asz!9uE{?+n^@KD?43TVa~LFm*sPbyg> z-lNxo(7cx$PM%RyEJ{;z6O9vS1umx1f+mQO9pk6rHhWho3fMBzjQX*!IGf5tJfWg2 z1n}p+M2`H*0j}bAy_UfrJ>e6zvj7O?%iqqg4+j7BxOq1(mi(fMen$1yWT@ysxMG`e z0)8}%N)O|w3ZPZc*Vx&DHRA77bcbG3y`pZDXx;frHsYQMVAH#C34oqX6<8pGTekQ()M_wCJSD5ZVQkMB?*@hEx5|D)nb2KQfQP9kE#*DBbGS|H-xIQHBw~s(4#6Zjqrp;Q-ijl zM>;{Q-z>dz9b(k+Br!h^C;6k(+IUonOLf_~^2lqcx#6Ep4n2xm%vOy^hq`q^bm3CJ z-vjW!2&!O9$k5P6ny7f#Ou|q43OWAPDWcAXoGisO*9Dp3EYzH>(~MUM;~4Y$YrNE5emi-d5c~&!Ui(u3 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/squares.png b/lottie/test/goldens/all/Tests/squares.png new file mode 100644 index 0000000000000000000000000000000000000000..0b3f48db99489ec87fbd77f3b1664bf3ad0462d5 GIT binary patch literal 16583 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 MH_WfsK<+*LKZJtwbpQYW literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/starskew.png b/lottie/test/goldens/all/Tests/starskew.png new file mode 100644 index 0000000000000000000000000000000000000000..4d01d5a33e2e104ef68104803de5b6685e885226 GIT binary patch literal 22200 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/startendframe.png b/lottie/test/goldens/all/Tests/startendframe.png new file mode 100644 index 0000000000000000000000000000000000000000..14de220ea8bba2bebb1a6c1f7ecf7623e3ab0469 GIT binary patch literal 3129 zcmdUxc~DbX7Ka~8v50_3Iao-<8M_)9Ow!FFBPbBDwE^mc)zmFTx?vJ=r}QLyvT80eU^-BeQ0R> zETpF(oOvxU!t44&+x#YzN&gBksOXg5c>G@~#=6FnsS!&99p8{p3_*3*-L&<%0+^;k#~4xck!-dYrdSQcN@0%m7#$65mbIU~;m(9(qg+6JzG?jZtTa6$qc z^5kiq$f4_a0x10);OF^4Zq2ZE5-FEKe(Bj@P<{tQBJlwgf#7MNEB{YMd)u_rWwr2d z$nrFG`M};GE7@Y9_!#ZF@EOlX+QIs_W4Q^CUW`9k0e0!!rSE<`}qvnIENIyxzbE#UKvf_S30b{uu0;xNssd!K8?K$ z7o;5~0JASgch|sn277?I?lF3Qf{Id@d`J)FjY4->%k&gKKs!x8-ZVQcmaU6aH;(qHRR4%HVU?1gP5pudyHS*0Rs^WP`8}1l@ z@t(-fdSitAZr3q(vXi3Zl!x2Ro$Lm~=zeuCMX!;a3oS z@Ao0d{iujdXQQMZD-X%`sWbWht&H|jKEnwGl?%elMoDNEv?!WU##O_0z8jgG(GrT zzhW*7lshtGr=UGwb7TP3uorc@6LH>o>pk<(Rn<(QH-ugulHD9E(vR z04HBxeab%zjKxjm(F`(avni+yPrQR~!$vgVg^|h)wvLG{35h`~5uT0lEA)w5Yz5B? z_ZUV(vsrPnc$D?`<2pLxEi5aMFZ?XyrZRr%@0gz4L@4|Hj-l;{;cCZ5>iVX;n!rzA zZSGFinL13!xl?@nsBO0E;#ZiSY|2y!PI)A3vePfq9I~W2Th_;|O=EhV5AFEFS=9?1 z8XjTZo66@)(>5Hwv{G+H8Ojw(q>Kxi1g_69k z>oK^-c%>dWR<_9&PFy)&;V~@5&KA;j4%QVx;}JAig|JmEL()0!NeMvcvYyY%R0c&yi&@siR^cVDS-p_uCt#7HR89&QEXKRo#V4_~S^&Hb zp1;5Gc3V8REuvBMYPU*7CH6Bi1%xVRvKflfM+usE5dACBp;5$e4b1Wq%aG$WZoSm? z@&-SsDvr9M3S-J!F;kj>M&0peP+_4qEg^*VE@6Msh(9oD(`0Gr)nzP80Ta1{sl@8jgtTX literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/staticshadow.png b/lottie/test/goldens/all/Tests/staticshadow.png new file mode 100644 index 0000000000000000000000000000000000000000..dd7a9b8be29dd736d89ca08814f21612addfb187 GIT binary patch literal 8762 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 b;8;04`1*s&Sta26A1oH9txpx1xJ3UKp4$xC literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/stroke.png b/lottie/test/goldens/all/Tests/stroke.png new file mode 100644 index 0000000000000000000000000000000000000000..ac1da2290b4b38f3b4d2fafd737a30d282a20ac7 GIT binary patch literal 7182 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

_%8q0`f(P<;zz7(i|5yZB6sG@Yu^kO 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 KY@zhym;WFBqg&Mg literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/telegramalphacompat.png b/lottie/test/goldens/all/Tests/telegramalphacompat.png new file mode 100644 index 0000000000000000000000000000000000000000..c30831ab35cf94ebe04bd3d985890e803edd6391 GIT binary patch literal 1488 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8a6FAs_A`zP>9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3Zfwjuh#WAE}&fBXSdyg0hupDe{3h9}yYTs1-T19ZJR)b!z?BaBwHX=ZS z_u84oXV*;Md;W6y|6_918;{4m*(hH9=UU;_;|vFCS!5ZQMhGS%u!vRC;656tkc2~Q uh!LS~G*DqVk%+(|R>^3fk`$=_zOzS}PuVf)m~#dwggssTT-G@yGywpgB$49) literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/text.png b/lottie/test/goldens/all/Tests/text.png new file mode 100644 index 0000000000000000000000000000000000000000..ec3382e062c3f24a1a013a19984c6f1743e27e74 GIT binary patch literal 16924 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/textbaseline.png b/lottie/test/goldens/all/Tests/textbaseline.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d17ba6fb93e89083a2a61b424db800b3ee5434 GIT binary patch literal 8734 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 mg7|u+JVq7#-xn5X)jR2IO0d}@9~en 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 Y@GUi7!=Zh^n=}x(_MKZLn)jam4@Aq;@c;k- literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/textwithpsleft.png b/lottie/test/goldens/all/Tests/textwithpsleft.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed24a9e4a416c573ae5e8d9e1cefd00f1d0b712 GIT binary patch literal 2137 zcmcgtX;70#7!IupBOaxW+<}?W!#c`<7F0A)5hqe9DCB@ZI1+^tu4?>1&ZuptGC<-0 zg_J|AR*-K=B1ZxSIVzf16ez~!h)`N1ARj}R0FeZc6s*kXe};EvXJ>bI-gozTpXb@k z6TZaF8?86uaJbFh$GrS;IHQ@Ram8fA(oSG)u54*CV*3+4al%g9v8Ba2wx>7AWGT{2 zPF=>~Og{AXI!roWGSTM;xY4$)nuI9sr=b^z^LKdX?pZt)aX6^&SkTVce1F$YC2Lm` z&b%Fbl>3Q!{`$|p+-T|@nft3#aZJP?KbEN6)7*+g}$Uo(5M4^4IDGHW392P*IBYgD_dyln{1=lp!#5|C zALWUhrq|1N{eBu2VRZ5MHiN;%J&776o2_MDpZ7>;o@OuZe0wrlKb-oww_v`U)zxRM zcPcL*0>;c|FP`%y1r!_EeG+m_N+sASp60UT`;#8jLxJ!pv!EVU zvl7HjDfHJt0#PK|1~ajAB&npaRvAVIBPdYK-oX+PX-X*G>f|dj70rVqtR%5uuELEh zuUWWz*rqq4dzbkgyA4#|>{dxD2&sdt~!J{GaNoXaP+iG5xurMK-F&9_um^ea;z1 zJCZUw!+u(6N=q6~uRJ?Mny?CXu$MiZN!5nO7Khj>dY-V__|;i)j86mZL(; zygp4eekws*l|pN(>d6TQa?Mt71lq%!Soa~pJ7n9sis-LtDs#}!Ixb!ydYIglzj&j* zM}C8<`edoP8_Up2+$a+Q2~`9h3yJ)3)7w1{zJ9~OWzsa?du(A_d!>LJgC;?t--4l6H$X47 z8tUR^sttGbon3mc;sC>ilg?qm>SC0@jCs+0A+szuxMq%KyJJ^&7JKd;9YWemDSh7$mUw?^d{-lQWtyZYi zW*Q9EWsP93YQEpO`*qpAA^ic)_7w+Mm?DhCJW3A`N5$r(Sq3O3;SbeuXV3Tq9|xP6 z4Akw!Ah6>_v%JO3l17FPLoQEz*aB;@Xl)H`-z9;a+@op>nL{c>iPLrOl5Lg1zaW~n X*F{M6Y=Uvea!T)`zFtDl@Js&z0}b}Z literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/tgswithoutopacity.png b/lottie/test/goldens/all/Tests/tgswithoutopacity.png new file mode 100644 index 0000000000000000000000000000000000000000..b56f1ae727a24487838c319a8d1102d7dddd5045 GIT binary patch literal 40435 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/thumb.png b/lottie/test/goldens/all/Tests/thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9ecd8b3d3462e6e131e9412dd1cbf6b1305905 GIT binary patch literal 4437 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/timeremapandstartoffset.png b/lottie/test/goldens/all/Tests/timeremapandstartoffset.png new file mode 100644 index 0000000000000000000000000000000000000000..c22297fc9ce4501403e7aec1f5e00b26ab9cd1e6 GIT binary patch literal 14863 zcmdUWbx@Si`!9`>(nzY5bV-+rfC~spcM3?ylEM;;w16(sC9-sP!=i-JEZxf@-Q93s z{NCT(KX1(3nS0L+y!-CJIq#|GJfC@m+62wy4Q(#sfFFZq(cN5s_?-EsX7A^r=gtfr7TgDTKN< z;0iCF5uF&-5=G3_N42&SS4?P3sOfvKU>4-IMRY9EONL&!C$rjZlyo?>fHL)|!kcgq zc=cdVD!0oJv|9K++pd~QyIIs<@^DO>ou^f))EPbWe&#>Ki2BbKI8vkhb7Yk-dbi-t0aS-=&NJ(hO8E^UalSY$l zleGCGqvi<#t)imHTn8|Z-DlpQzPFC@k=#MNQd3v&WyP)hz|xcB0*#8MA3{=c6YATV zLEQ3?Xc9JY;qRr!hx7=UzYVNX5*hm614=?gM7j@`)u*dO918qX+P#9nQd8109aNCQ zdb2Hf()@T*!SLg$g!+o&7u<`BJlSFEhvz8&?|7)a5!8+AUjOZ;o1Xk_t2BWFUy@;I zar_V25?*;}EQhAvr)TqnW*^q2z-49|WC#GI3;y2Rbi+*|muM22aX9QC( zb+&$WBCLJRS1WM%@cA%KcI&eqm#F^rdGPKsn0s;B*E}j+xphE7`0~(2K3x>gX|KH- zZC|H3R;HDyT0-&}<%t4cGTrAe#ldGb-N2o?H$3__J5D=a44hzmf&A$A0{=r_r#fyJ zwy^(+%-P7Y%i$PXlbj^SWVNf?)w_1gr^(E!>K-#4-lpX=dt`_Xr9}=gYQ7-%#jk~S zt*`eUeBsv}U!ELC@O7r=8b`&+NsVz2CQkGD`uQ_@|8?@-lGU@^<};C@WfCCApgCf5 z<=V4Hjh{pl%g0kc!#Xm-wC?|;Ng9~mI=XD{SSl@siLDW$6gZ7;sIS))X?#z*pI*x^ zHr4o64Ed|c{~c~ORuODy@W&GZ$>*AUrI~RSGN^;wmTB8WuR!6dhRMZ&l{5b5n&4TA z7ZV(-+nV-0opA)752R<$l*F$eoUKCGnoPg;cgEDoF_)c?TVf0bnpTTpQngW+r@*Ns zH+F&&=tsMr42p`t zYBNb$Hfz$(hsTOGZFga6U&C@?{q_0HH*qXX|45D zvtIOYS&H1w;+zx3kKuP4%_AcUOPNMbP!LK;2i~6;5EUaD+c@V^BdHLvpocz0yh1Jh z2ESSQyG9*_VtU%p&?U_VvS4^$K>SeWQILWs378t1?H4i`yWhF8)S-6<~Rvx zdFKziYLx!DwE9@yammSca`gb!Re_eE+?rnfp4VQ;F(z%0w@}>pL#xQSrLl<({$r8p z7Wo;+oXB&@VAN*bPs7`gTYIlV)$l`M+wGbyic`Pi8iO@=Z}yU|fk+9&unpCC%cRfy ztS{AMJmV}<-N2#5w~`ZGI;@<%`K%sdn5&bGbu+Io$gG8JDqH#Xw|evUxlmM;kKlKn zti+%Wf=08%8%TXJI{GrXx|Dlhk6}{(b{>K{4B?f>Vj39DFQQL(_|rn;;=x|BdBU9E znp}OOy7hDYu;6(ps_9TVmyUgJ=kchs*DG92JrkQq4_DT&P2iyyqVRBrDy>3#Fi&~wn=gAw z1j0Hz?umHuFL*v~aVvG&xr+CaNRsG7r&hc9+{;z?Jdv)IGVHoo4VehBV?V(CNL;%cF*y-75lt41wbV+w^`6sKlU?*m7va&-?6dV|zCIl)tVceccDUJwqw6rgt1(Y+Qc4q<7-FKfN0OA~vK?PQP3S4BNn zXNinO6TRhU9XR++u!zE?EAwTMSEI-S|coray0HsjL5@$GAL%aDwOnnQ>u&bM#h)Kupx<`LY?~d zGH<-0m@r4Zf&WqccMeK0O!j50w2i1*j8xKXdCWqhw?GFJy5g5n=26EncZ73nYm7BJ z`YnoMrY@GDI7oXejnt1y&rB%W%z#V0sY2pL?*u_*woolAhHnDOnRJ+i>zNIs``(tw zyWq5oc4l`pJQv<88*eaL&x7+yC0F|s5cRHD%o{iz%U7Fg2@Aba9P*E@v%zh1>`{1P z@23kz@8;`LIUrBIq(C;bCQ?@O(UB3`_Py?A4ov>ivNUmVDlP78x4y`WTUtHO%_~cx~7h?;Z}C)ll5F8T!al`bXDB<^%?8BsJ|1kZmO*Q}&6_cO;XoKkR*IZsOqT~re zZr*~zIB0qSup}FgwqUnpBj&$>YXGJ0PU!?{2u(41g+-3hwU8dlM8Q-vl8zL2p{DE4Q@I`deJeU ze2A>a9jRi6GP$V_r(m96o;^oS!9v;62Z5eaYgPm@bJ)hA7s`03&l0I+ri+C@bVgUR zXD3gEH#1lvReD3tAjv3wFIL;vVZIp?s=(wWCqtBBCtCui?+@X^z}-}ymXX-ijfLQC z>IAV^l@kc*32WuI&4E|_gUzs`SNp%0e#5J@3O%K?uYrXCOdThviQ1;IEX6%RnQc7_ ztv1$v*L?slv#xibHL~g1?$GVOGX1(RK`Ygr1lT`@FJXAfA4|O7T)TqC?nYF&N*#op zkm9kZe1S~v>-#9l&u8BI6C4<68gQ>U-i1lHifJ%br`qbJ2HqsWZ^b*H2s8qeDyy9O zFMSLkL)N=?cx-zQMUEuD)6u56Klo2OI*HZUtb^DB|M~0X1-AfqL%-6)2*e3Ogv?bP zne4D1T{>b`gPfiuzf}X4CB1~6J^W*ZzB17uep!w|@}#(g8-QK4?v7R)-8fJ?J2VTY zpCBWNe%50Z?k%?N7jNgDj5;*#=%U4u zYASD(?{O1}~|^41xY_8?}Ye21nxTjcP~jjOi|; ztJY>)ZYB9>lHd3ocw3XMsi?uPt4&jX_CFfV~nIy)n&^g$O2?ht-x6MDfCBslw682W~hn~^342T#q#W6ZLYnn$h zo1*uE?_+(a0R+EZ_&c8rgTEYRYk)$Y@dVaR-{@MCBk^&KWOA%TbD9tL3y48tE!Cl> zKT+N-L+xb2VJp=5M`Rd1QZfyNj|1*usOzTJ&RgVkCAG+YoC@TK?TdNs<4p++LaYlt z5bd$gxZ~lJ;9k0VtY<{pjq1)fxTDUs#*4yk0QzVu<8oDyH#p@w!+t(y^f6v|*UfZ@ z=|0$CU*sg`gO-6jHVO2n&5v8I zy*hjI-t;DhT05pzP!^&tfzwXm;yrtDJvoq@^(D_Kber+Lt$)RKtC~>j7wL>C|Gm6Q z>O`y@jj`5bu`bAEqAJ-i@d8d7DXce-nX~vEmpD2*`~+SKY{wV4{G=5>=N8x>hRHM8r>htP z(2d=@S#Q>n)2^qJ6DJYlYTIkb<>{<1cOQ=o?#{S=)l`)SpD%{9Zk@(B#~Z%WiJ>MK zXj2vSV{8J-(n?q*7i4;6nkb+9$y>8M2Jv`m_KL;dP*TX2k!ZG_);P7WP$JiZuN%vz zFQuO=qoe*Px^TpxK-vbg+hcf}>VN^3&OrJuiCFH@SX3O4PlPS27)YE|K#PL-)L?;7!b?a;$jIeTTVV<(4!&>YY~|O7h3VhW8{~0I1~1d*CdtLH zw*bU;ak?Dj0Cq6EfyY~F8KizX6K%J~{1sI-!vRBQv@*LcO-@)?BOh}2=S!Bv14%9- zx7D%4H@|Fnhs+PVLb%;7yc8w?2jFq~SmrJP37%bGGS1**lSfHIrz~9`Z3>$e zCv3sXQ|zRfQQsvDY)>M6|KzLN_dbv!b5Ip{AP4~IXkJ%e?dWmr5vHe%Wk*&Ku09a~!LX(ae_n#k9%{;HS0&k z;P(?N)!OguK0p7jda8oQC4GH2&3es=&AF4aG!?`yIOvPyYaf=lafSOz+wV?*jt@)= zi%j#!>40SiHK9dVe6OzFaHa^`Ugu@$r29KL{Gpnt)BAl#20tg1Lng#G~IT(fscrH!NYll|pCjh(yZueUjzrCf?GdIf^a&4j;dp&p`vr1QxO8Or-L_eU&r zd|;>2#PT9;Kvr0`5pavScdUu}{Szt8jcH?z{K&3Z#M?vL)SUv1+KB=L zU_<-h9vtm@kBluQr^(y;;m2!hlILFsRU$e-$<;fI6zaCt=i>x$8EuI}N)+C~)0`lb|)BNlI~#y;jKq`?KNEzN;M%o0m5Pe zAS{GzcK)2KjYM^Y@{aLq7MUu!SQRv-T#yEWOG7hfF=n<%5Elg~(_>o?i2R}3k7BVF zuN*2S+d3~-G7DwhYs?Ja=DobNmgY(B8S+8CsxMURY#HQR*hj=?8ceykL>qQ}3(gs* z%Y6?_w+ki;d$>Be!?nql=!2C{n%2NBGXG&hoy?IIGPvF zrVh~+{tA!~q@q;*>X0QO@0x=660%C=t3lm$o970QP05*BFhQ$KGuK0kzM@)wmTfJXT0e z0Si;{O=WL%`}uaK@1Mj?3pKCQf;c(>iE zn%RZ7XeIp}S${RGrfQqs`x}ruqI$)xI{{`){0n=hK!-_qDRrM!I`MZ8zN@lwspAwg zRZYGO9^Ls2p1AR6s2shosxu?B^mZQKI;=W3{}Qgx;p-SP&U+I_+LzuwN{v$KWq>5F zIpJRCA!fFt!q~Vqvr{X1UEd-lxQy9LY%y1BWp+PmMb|3h=4tpLdR}&1!q48-O7QKt zH}O`eM(;eX=S_|3<>d1ll}u#DkMetBrdcMz;IkREZ|ws+0RVAnrbsG<6dxhLs&48= zsNkCNNr=-LYIhdMtoLcxajjV*>D&$Za(NYXt0G|q!{<{8;!T#9zuOI1wEHKp6fw0C z9AsB5cDVjtGaY-_p$S1324i9(N}Am#q1B#LX@m}hhZ*COFZTq{btX0~S33_WwgY`~UNkjxFmp&pHUC$vVc74nW<$gh05jh$$H9L(LZNjsZXw zC$5Ekdr;BqX|{&fKp#&EUeocc3xarIqP(?lo-$Qresyn+DU2gAv$h^*ROrw$Ya;0{ zaz87(Qze~QOL*7qVLGoRqkvnW=v%?Gc-NnSvhRST^;{a93zYgg5?(b4W!-+4_Tbd~ zPSPu;kE;%a-%>|)5yCD2khv09od7R}_x^)!b4l=}>hCgf1MhoD`FSj@$05=SJDd85 zXCMz)D0|YM1d3Kg;M?febl61r>=@2i>KNdlH&4*Z@I#>esXSKOGS9pPFF=O$aF%^3 zCcK%;s*TBk0e*sx{HL@2draU#6In~x*9~EwYLZdBuaS>HBWyBB?$pAbz!X8#0_zOc)={js`EY+2-&5+-eE?%tsduZir931P zlz1YGcR`ct_sMBI09{n|kI4!yI13|=4?Z>+3p1we+cduRqNTKEfYEr{+w=FThR zV@CF`PG10GLsFg0&99Vk1NbG;Rp`rglzyS@FA!$!94{&{2!%P4SBt- zrY{042Vmfp_E!&pN#Tlze>q|VWdl>to45hT)>E(x@KTU%XQ(X)J*N;5S${<3V2IK{ zwIOI=B$jt0&<A2K`2yXN8&oCR8{Zy zvpQ+)ZPE4tTG?#ry{2yHKV3N(>zPz1*h?+aYsPsnD(agJgNwWyXUQ9RgFKNHbRKAR zZT*P_6n-6Kj^HH|th3Dg8cZ15&|+!lJs0R?2Iw#l8}OA_!7eihvgFn?y79cjc}50Q z_)YgELl#QNEY5+C3%$U>3FIJ^UUCEH@2O`zCy$^VRM&-POGi`18ruCuh|J0can`JS zs%-OoBmv#@fLTFg_YeM9Q9vrk{#-hodyaY-AlevqQOy^Dif{m5u>txupJq18H;ew< z6+j1j`0*<2PIf@V>X;J7NHX4>av25K(qKbR*)DL7)JlC z&;DzAr`$bHy!pNr^r6*#J#*HQ>x;JJtEyc=o1VjOjcTdd+zU}$F}N`to#9*X`ntY% z++9G(%`S|jcoPb+JY@ujRuniTAY4(p1)i8yO6P<8+sx+bp+?5tH4@=xOhwBIwGJKTW<1(PZF(Ff#-*{G>zu24tsvf{~ zWU`*Tb3YHNWP58`M0ntH!T=WEs*y7~y5wt;W8^*vcHmPZ_hVa_UJmO?cz*q0?8Y8z z0(01fmT2uG({YUMt4hY*wI)gI z)PIP00;KPB1g-b3NWObWHhtq*{Q2>SOcJqXu$@e!>wYXxHfyZiZ@!cfE7p@*S~;3m zBairn0YHq?=-^*!(A&$4pAg)U!osNmxi~AEh3M)P0MkFxJN?G|Ya|w-(}ZBl^O(Li zuBp@<`St~d@Q-KL=5f=;S@QI4QF;AGFeaJ~HzGc6=v^N^ECAHsXV=qv)EP z4Kh=)V=;r(Tkqi!hcGkXGDC)JPm?(-=IRr?Yg-k&;ZPAeu`hV0Ep`@r1{oPbQPh9$6@dU(y+(PZXjZ zUvsmZQIsQVe?l+1q%)bGGT8V7pteJ{Zp27pOGhr8{& z3w%6zoxp#1l)=WM))lBLztEbzd;oJH^nSDps&28%w7rRN5bcvkSKG)-Gm>y}sh9C= zbR)lOrM~tqg_+JTOtB9#mSTK5&rvU!iH7dSp##!A{)}!gho^_`VqEKn-e9Ay>lQ22 zJk8loKG;QECU*H=6qEC>vEbW3FEHd&%n^Bpnhk6T9ITmnMzz1{=kn{!NR`iYx@YKZ zHa0LID<_VZL?ewQC09fh0TJdSL2{>1Vds8@RT`1NJLO!K+vO=bNzIv%l1BaZ6Ihbl zEdB$4B86DJ`T|!5~e;zc6q`v4CW|YM3 z_i;s?8A;bYn;$$V&eG{d#x8hCBL_y;?m=Nn-8F`YYU(5j>_D2)o*PFS$(0sG*8@HT zS7tCj^ZiUeEU_E6_6c&;C~3>exa=kMLiBrN3P$meWa6-wYINOG2A3;SL`c**IWqyt zhn~*#ZTcu1k6pXV%b@O`boTAbHvG?SSfFJ#sY~O7H%3v>Jy2pp9WAu5Ef3?$p$q*f(;4#~zR-_$a z&Plc6_9|nQo}+t4Wl83U^3I3SP~}Zp|0Ff)&Jo}uJIIT$>4Jr|CO;kl{lVc>9{c zVB_8o@9FCzgcFVwmOZ6dOJF_w40)TLqO)TI(5#x-h+pJafM0q=Af+JZoJus7+!9djuYt4-_R!AkNBNPt&1Y24kYTBpWk zbS2-b0>Tr$cG0mWx(tz!(?vA69>EdWjnRi z;n)$#P6ia=CJlklZM=C&5aDMTw@mZKt&`QIF)QZkFoJnS45A0KuPOc86NQ#oyf4hp zIu}q4-K#W*fD@t5!=w*0lACSb;L0-UgejzoHPNf4aW%jsD7zIOz}&aKjzMqaHj9(6 zDf!E0wXa6D*-VDy;iD%WLrNQs0d4W$J=DyDlHzHaE3!{3RrFn_Z+HX9_Le=PIC=i| zPb}_fnqNQOQ*0uQK%D~mY%FRqH(?Us&dUOqRF3IS!+s80?iigNU-{JDg4$ox91gN~ z*l+vmGQv?T2S$Y7n(?nziUCo$(@ChtVlNAW#Jw=iJ*T21OF#>tl4Jo_6Q z65$BBY(ESkgffHDW{qQO6JMcEvx<^lv`+zyTza9&);($c!rO1FW-qB*-5(kG^)#>4 zX;`Q;r}K+2Ke+);&e#k1q;Y$Hj-(nS%VlFDCKaU{@{m-Rj6-Z09qxv=vp5f0eu(|0 zzwS6vjw&nlxsg}<$T0DS3JIrPwMbu^ersV= zWGC(QOYO+$Dqdg&hK~ZTr`hj`%Fygu8U8RqKm9&JC2N}YtSo6ENnNm-g9_Z(E8-sE zr^%VA@Qb(?#eEd)K9--M4LDS&|!&?a2c5)uR5DnqAPLT5$92;ZQ=$yf53l=Z*zVAi-L@Ba~rM}fwqxtPk zN3RJQ7vi2S3J^imtrR{t!B6~OQO2lEQ_LE(4FHBp(nPlWnl}$5?w?5x)e4POJ>KcX z7kjq+<8LyRp{U}RZHX2)K6$6eWalj9?CxMEvMwO~A{HP=0o7AS8K~No(z#?Rgp!`X z$@7I5U*M+uJpM=kq*{Wpxw7R&l8ii zA@_#@G)c5%V2Vhq@wt9A$v^-}^5VkOzCL?_oVu&VFcAI%maFnn;10K0tEd1j-urr_ zdStW-?q8JI3d-O!kWm|J>&ysv2`jO(q!J)CYr4Y5X8uc=ENJw06pg#Xp#RF|Ya|{l zCcfJL4l)Cnh%)Lt&6DuP4{+iF0%x3Z+OpH!$ahad#$#O3*W$6j(?AShA3=?6-k)UE zU|ypA0M=K6z0^pD|3l{c{6(Y|EZu3`uX8`C78|_w^+^ofPeVE z$`q2NAQQgH*21=q{x64ebs2TF>zx$ZCmW?~+`Odlyt7OW$3*>K^St*#EUf9=wnhJh z+5f8MfB)*C`4u20Hks~xNX%s&Oa;=v4)@#&BlGU$!T*Wo`N2Kf?toMAktp^!ds4pi zEs%P;f^2@_&h=r?Atep>jK2qjz2V1h+mcE*jRm$E)}3MjSU|;6-S&&#BTpQNfg>Xq z%+P)s6fdl4Vvh-7<+*QefrPpeG3)t47Nhkm(=0WTP6hqQK@W#;lFiPdX_ zNc8GF3B@mXey=XJ)S*mC-6h|@ZjHYzEcC(CW6|j2^<85seO&SxW&M5E)AUozNib&7 zPtw>BQpvWp3VW`>PviQknBz*z*U4I{FPM$9-xz9sCK{$WV`Y|>Zk1qim;u;PU(}B| zy!F*Pqv89J6V zUJNenP-1%Az%0d>^ABy`8aMv(ZIjD(zT+qcH`;cd!136J8Zn>a-y5k&N1ZVtII2+T zVyN&D)V!fe>{oHF8S?H2Y4ay40|^=XaTXS`w2zZc(5&L-L}^!4NoODaJdUjy$l*(k z;-`={;n}IB6j^z~U4g$hoNj4;!r^key?4>3LgK@I;7~BXMRL_NtF$K5_&v68IPtY0 z*<{xHJQSi~&pDz5;{dI)+^5HBLE`m*XaUfqI6L0d26>2a&6&27Jw72<)f6aB)8|&G zW#a?k`eO11G!ya3Qn^vk>~MJNm0N167~y|$jESN$N_hU4$=Q#OeQ>?MJaAXdeleJa z!(-Yp0d?iTSKDT3*Nppx^yKSWa~*{J4X(5tv zfC4B|{`xMmGDCl>A`VR#YG>48%lE6SL%d zhh0WS>1NfDB86)9IR+0OmKQi1ZZb*E){4@8)!pN9u>`1ZRY}u2-nIW6-6sS1^h%4& zyV&g`EvT|PL#VDLyGyuy!&Gn)5@q=P<45yaTjzCJ5$~d%1WM>|i`bd4kTJxw@ zIUt@(XXYgUc2+C3Jp}s3!uGYjZo7J*qwWm@9Bba!chMi34TPLjs|RgLJw#*HI*aBi&oXEL?jem1!zubkd-1d#7qCApOm(Rm#MZoNmb{$UJG(BQ zH#_TBAUq`&uNR~VFyV6kAW^5DzTuQfNtj++q`o;CxQkunDYT`ABAqh2vUP3kzT*hO zb{}~$1ZgoF!yiY{ zYPF*x@MG;4G8UH5XYHHe-K|BRd*E0GJUIcLQE_Xsur;%Tl914N8>jPf{Lw zTO zo>|mE<@4LqRcip)+Zm=ox2;%-8M0;P72^#IAG=4rD|m{e9XZ{T#OkE<&c~HSQp~RfTo=sC2jRHZc|&M2~pWmQgqK^V_}F@kxf*cy6%z zD9|7BIxPNt8Y!{6d=)8){j@>xweLAYx?===Z*mJqVcFQ9$Nn+m z5&)?D?lQh{i^aEPH;W(!WJLl~6{FOR!H8(}uI^>fT$L5FF&35QXk&X?plNKMA%|he z=jP(lorW695GTzt>~kYMvy=7CFR~yJSaCVq(KX*;pl#l7UfC`zJXh&%1?F-B(0D+# zY#UV#deLT2%bPw{7-;g5cna=n5$Khu^Y0jF2`*Ss7FQE|zQkq_bH-E-eJyQZnmxRH z&k$2IMq>7B!LW!i6*zGBy7=vAthnR6jimyVUPz>|pvd(EFi%+7Rht4fWNPicfFu0L zRr|eQ?kM@->}SC?fZ%;7l(W6A5pH;w#sb!W5}%BO$UtduPq1CVvRb! z31SD8i635&Qnj|3X;6-T-9a9aqB;o8Hs?@tb&=8NvESgeA6?d|mdc_u6e$@|r_^J0 zNChfOvh-QRvjr(<#NM{~>2OHdYIF$4TEAS+gDQ<9wxJ)A#Cjzz3GWBCe*U02e6`HO zq)pAqhaa<6*qgG6=zHkW*-(Bl9l}`hqy1bu>>G=9$XaR-IPZH!kq24r>_gGQ;MCGj zyI0;OhcpN1(hEA?N>3j3#$RL?_}b`R;HjN14cFnv`-#nj`2Rt8ADoQ+4HT{~Rbt=9gWh=G;nBR7|299aeX1sQ3BPPuo*& z0GXGl>T^RiX7Qwv+L>Mp&}m*&lqD)1H?Onh?N}6(hm->l?Cjh>z+cw{yzHN^F=(RW zBXoWKCkU+#6{hwAe9{>g)uqZMzd5(d4uMrmTTglBMGWx`4T4vMG|( zslQVy-AR4(Q=o7lzx(7-+k?c@DDy%u+_F>hGp;-v}ED1qv_ zt#4g#>P5BZy^0z$Pbz7tQZ^eiW* qAT5|jh-+pD?rg1{eU&VbsN#>jlKfFB{wugkezthG?XKZ&igEo@*g3c6uh-VS~c z4Z-L83*w=l?E6c>J!tDeBj?-2KNU0JJ&ep^7_48vyv~2V=L&wrqT$Qp!NUF%CLC)# zf|^y;8q%9|W6^MX#oBF;ERCH3MOmyWFb6ZnHnE7+j>h)wVRvTGwNqZwn=!TNm30H! zfGFga!upIer%P!;f*fS6YjC2!DJtLc_wsP!j|M0M5|-Ajw-Z~$lDN29ffBz?hbd46 zLW}Psj{$&rSiB;j{--Kpj#Q94Tp?MWJ62<;dCW-~LsxERc01>5@%(?N#b z*7jhMBE%91x8;Ipay!vNbrok&^tEj0WHNrypiojKZ_7Q8=*Qlbj$}xO1jAM312b)t z#*tfE>@PcOFqCG|!SL*3lTCtr=2$&~bJ4W+wMFM2LO8cE(aoVN`_%!<&xHUNg#1sO z@zAV^$c6cNFH-K@cG*tVQ!^8QW>=6>6L+8JfL#V z)MoSiXv|6k|57;6>R@^afgSBaPO&QM_mb)G=OL#@C4(`BormafkPr9MaBkYv%X1c@B&(r$^=LcewbMrf zSr8z>%vdM~0FJJ^oZ3OHIlk%7?V@6)E0lcEx~?MKSa4ODW)<%$>#XIxiW&E)%Uzim zinEUK^4w=rMbNV~L-N858n4^lYGu_R#u$f_)sT`K>QuuVk`t2gA9Cuy-0f2T^vA`x zy4dj+8)kIk%Z`hu%!0c042WmgMFZNRDTpP^&T2dRv)HN1`l8+%zEyzVa^vwzt3+BW zX=kshs)Pql#UQCNc6d6cGVRnIEKgD&j}UL7EO8n1X= zh8ultLcyTtQ5)}#>8Ok|Hg)vI3!H_ZN1B)Q)ie3&ha9J~aNd~MXW!qw;fn;H*uJx# z0=3#pR3srKyax7M)!C^7Cdpgn=7{_ClbdXfL|T-83s~L9h?4WPdo%8Iky14uS7U8q zm_ddI!l1vV&n5rY4sEXHY{BT$Go6yFZ9{r{R-L(*3ewSW8x7Y7rl}n+ba=a?JLa!5 zVoWqZC>i{xap&V?d{hQ{Yu%yo8}6ll{*Q{Y=3I zv~!l)@kYTC_=*u1(iR);44)GS{43I@$_P}6uVdB(@QZ@J;|N~JfMoRDf#LG|`S9p2 z?bQ2y>F~g2cMX|cy}^ieF7}MLdPq&p`MWn?9TS5RpfY>j+P}gEXdIw=`tXN}{LbHw z{*Q!#J(@8UJt;|J8CH0u8fo+0`+axHuoN&h=rIFg*}NyR_ZoX6ccrp^X>O}68V1BG zGDsQdqb|!r8mHyStKYhnX#}_Vrwf_6ji$W2bAeT7Q_HfuU!+N6fpN$H_PMsj9 zLQlf1Ss1poWzx-QR6OdLK6PA1Xpda^P1FmvCa;M<8XV%UO(u7?L?!_+jAjA?079qU zEA{SM_MUg|EA%^$FfMSxDqrw)sF_U-;wKyB1LNz-ht9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc%h#{p0E47*a9k?d{Wk(t!f57n478w6t>^@%Z!qzG16li^9~#YKCdTtSono z_Fh|2`qc4e^t4mDi1$%-pQ_`2{$t#}Gt!JVSf|SL&1+mT>930Yq(3sY z+<0^jQmOd!NnaQa+zu(4^W?hH%8Q%NM5?lT`c3-dSG4?iMDe?g_EiiIzGnTsYwJ-I zcJgpZ&3+F#_I@+>)9Kf>ZQCw0$E}`}s``BK^BIf1_FX^b6nC;xRs8X?S?iUXc zvhQ(Jt=@XCiQoOak@?h^>!;(Dt9X{U>sP&*pxG1O?&}jTbo;&f>L<%4?bUr=#j^k+ zbL!;_%V#UD)mz=Pxt!eKwQgJOyQ-drP`OX`ai^?TJy|j7wAVSab6+JK`s2R5NY%3~ z`?PUu=IUS5z9w7yd(IO(`S!)mXBoTZmRi{wEN}%VOskezUS2G2TXk{qbj$BI&%Z`uT?o?-Fxwqj~C2*<^u{4R}ism z(&k$c7Fw3;pCsK0`MeYu0N_wC2{~E1_s+JUlW}XeuRB~g`Rru5y)Q0ygNOiC^Qmug zE#q%)vzw137(R7Qo@IQl_4DMH5Ov*hyrD%QCsS3^rJt`pdt0l<2IL^1t7dxlPwQX% z_jJkcCndky{}oPJuHxVQr0h#hF(}sQ6A8N?^Dn$*wf*q4kkz1&^>p=fS?83{1OOlQ BDIWj; literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/timestretchmask.png b/lottie/test/goldens/all/Tests/timestretchmask.png new file mode 100644 index 0000000000000000000000000000000000000000..1ea160bf494a8bfdfd85f4365b36d97a2f3283ad GIT binary patch literal 4209 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 TO23u@T8sUDM- literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/timestretchprecomp.png b/lottie/test/goldens/all/Tests/timestretchprecomp.png new file mode 100644 index 0000000000000000000000000000000000000000..175a22b8ca765f80374ceab1b939b720720e9bff GIT binary patch literal 3655 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 YD1DZ5s9RpH~#X;^)4C~IxyaaMsik&<| zIDnvrBc+3Zfqjmri(^Q|oVV8vjX4>*3GOPcPhAQTy}e%d-DDPd&fi`g--}QzJcpzW4f%iweuW zT{eHcX4n3I?`-&L%6HwZFR3Ul-V@1i;J@nyMg@maJm6vQ;NUIhuDZGB_Rm}X^knS( z_-P*}Z+6$;Z}o1~?_9~Y_s=uG_urE|{_yeS&40JMOPAL7*8lojGOx`4{f~QRfl>a! zW448X-s7h>Z}skf>i8US{&D3kTe}_QkGW+Tm{>;f;0S}ivIc#pr+?lO{Vel))?3{@ z8+8tU-fDhe}h_V@p1v5xEw45N5Zgh4~$TgKAQ`tmgvIcECr ze*6IEw-b{qa_5z;Z%eHBFwK3=ajs{p?=C-VVe`9t|D5BefYJNefam?+!rEPTvrkwj s%saPVqU~vM{0jyFg;6{x!r+7SalTC7;wi6Nf%P_nr>mdKI;Vst0K8Wvpa1{> literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/trackmattes.png b/lottie/test/goldens/all/Tests/trackmattes.png new file mode 100644 index 0000000000000000000000000000000000000000..72780e78d453ecd53b5bed1d005824df6e3885a8 GIT binary patch literal 7241 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 kemQFMD@l$NPnhBln+`@YMJEF)tJm1N&$ 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/trimpathwraparound.png b/lottie/test/goldens/all/Tests/trimpathwraparound.png new file mode 100644 index 0000000000000000000000000000000000000000..7fa570aec0f7b67fa4ce901154fd3458fd58b226 GIT binary patch literal 21787 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

-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 TTt+BWIMUj}?#ScAZjt{1mK_`? literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Tests/weaccept.png b/lottie/test/goldens/all/Tests/weaccept.png new file mode 100644 index 0000000000000000000000000000000000000000..2ef4a3c1a98f072e96e83559762e7fe3a8dc5cde GIT binary patch literal 201432 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

7O_rVGv!|nd|@l>-22}C3{!IIfv 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 I`8n`^0Z&-H`v3p{ literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/apostrophe.png b/lottie/test/goldens/all/Mobilo/apostrophe.png new file mode 100644 index 0000000000000000000000000000000000000000..77a071bab2c1a140d71edf4c4ff2e5971b398998 GIT binary patch literal 5821 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/b.png b/lottie/test/goldens/all/Mobilo/b.png new file mode 100644 index 0000000000000000000000000000000000000000..5eae13f2cc70e290f3da0b3b7e934ea04897449b GIT binary patch literal 17742 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 Iy#4sU05T<6ApigX literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/colon.png b/lottie/test/goldens/all/Mobilo/colon.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4998f3ab21de8db69fc90b0d0caf25dc9426f2 GIT binary patch literal 6600 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 literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/e.png b/lottie/test/goldens/all/Mobilo/e.png new file mode 100644 index 0000000000000000000000000000000000000000..5f1c81fdce9ab6a84582f2db20d9154d68f92377 GIT binary patch literal 10669 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 AjsO4v literal 0 HcmV?d00001 diff --git a/lottie/test/goldens/all/Mobilo/f.png b/lottie/test/goldens/all/Mobilo/f.png new file mode 100644 index 0000000000000000000000000000000000000000..80b044b2184a2b4365e83649a7499ec12aa1aa48 GIT binary patch literal 16253 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