diff --git a/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.cpp b/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.cpp index 7c8adc2e67..93a207f234 100644 --- a/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.cpp +++ b/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.cpp @@ -32,7 +32,9 @@ const EVP_MD *createDigestAlgorithm(JSContext *cx, JS::HandleObject key) { } std::string_view name(name_chars.get(), name_length); - if (name == "SHA-1") { + if (name == "MD5") { + return EVP_md5(); + } else if (name == "SHA-1") { return EVP_sha1(); } else if (name == "SHA-224") { return EVP_sha224(); @@ -282,62 +284,6 @@ std::unique_ptr createRSAPrivateKeyFromJWK(JSContext *cx return privateKeyComponents; } -const char *algorithmName(CryptoAlgorithmIdentifier algorithm) { - switch (algorithm) { - case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5: { - return "RSASSA-PKCS1-v1_5"; - } - case CryptoAlgorithmIdentifier::RSA_PSS: { - return "RSA-PSS"; - } - case CryptoAlgorithmIdentifier::RSA_OAEP: { - return "RSA-OAEP"; - } - case CryptoAlgorithmIdentifier::ECDSA: { - return "ECDSA"; - } - case CryptoAlgorithmIdentifier::ECDH: { - return "ECDH"; - } - case CryptoAlgorithmIdentifier::AES_CTR: { - return "AES-CTR"; - } - case CryptoAlgorithmIdentifier::AES_CBC: { - return "AES-CBC"; - } - case CryptoAlgorithmIdentifier::AES_GCM: { - return "AES-GCM"; - } - case CryptoAlgorithmIdentifier::AES_KW: { - return "AES-KW"; - } - case CryptoAlgorithmIdentifier::HMAC: { - return "HMAC"; - } - case CryptoAlgorithmIdentifier::SHA_1: { - return "SHA-1"; - } - case CryptoAlgorithmIdentifier::SHA_256: { - return "SHA-256"; - } - case CryptoAlgorithmIdentifier::SHA_384: { - return "SHA-384"; - } - case CryptoAlgorithmIdentifier::SHA_512: { - return "SHA-512"; - } - case CryptoAlgorithmIdentifier::HKDF: { - return "HKDF"; - } - case CryptoAlgorithmIdentifier::PBKDF2: { - return "PBKDF2"; - } - default: { - MOZ_ASSERT_UNREACHABLE("Unknown `CryptoAlgorithmIdentifier` value"); - } - } -} - // Web Crypto API uses DOMExceptions to indicate errors // We are adding the fields which are tested for in Web Platform Tests // TODO: Implement DOMExceptions class and use that instead of duck-typing on an Error instance @@ -445,6 +391,8 @@ JS::Result normalizeIdentifier(JSContext *cx, JS::Han return CryptoAlgorithmIdentifier::AES_KW; } else if (algorithm == "HMAC") { return CryptoAlgorithmIdentifier::HMAC; + } else if (algorithm == "MD5") { + return CryptoAlgorithmIdentifier::MD5; } else if (algorithm == "SHA-1") { return CryptoAlgorithmIdentifier::SHA_1; } else if (algorithm == "SHA-256") { @@ -465,6 +413,65 @@ JS::Result normalizeIdentifier(JSContext *cx, JS::Han } } // namespace +const char *algorithmName(CryptoAlgorithmIdentifier algorithm) { + switch (algorithm) { + case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5: { + return "RSASSA-PKCS1-v1_5"; + } + case CryptoAlgorithmIdentifier::RSA_PSS: { + return "RSA-PSS"; + } + case CryptoAlgorithmIdentifier::RSA_OAEP: { + return "RSA-OAEP"; + } + case CryptoAlgorithmIdentifier::ECDSA: { + return "ECDSA"; + } + case CryptoAlgorithmIdentifier::ECDH: { + return "ECDH"; + } + case CryptoAlgorithmIdentifier::AES_CTR: { + return "AES-CTR"; + } + case CryptoAlgorithmIdentifier::AES_CBC: { + return "AES-CBC"; + } + case CryptoAlgorithmIdentifier::AES_GCM: { + return "AES-GCM"; + } + case CryptoAlgorithmIdentifier::AES_KW: { + return "AES-KW"; + } + case CryptoAlgorithmIdentifier::HMAC: { + return "HMAC"; + } + case CryptoAlgorithmIdentifier::MD5: { + return "MD5"; + } + case CryptoAlgorithmIdentifier::SHA_1: { + return "SHA-1"; + } + case CryptoAlgorithmIdentifier::SHA_256: { + return "SHA-256"; + } + case CryptoAlgorithmIdentifier::SHA_384: { + return "SHA-384"; + } + case CryptoAlgorithmIdentifier::SHA_512: { + return "SHA-512"; + } + case CryptoAlgorithmIdentifier::HKDF: { + return "HKDF"; + } + case CryptoAlgorithmIdentifier::PBKDF2: { + return "PBKDF2"; + } + default: { + MOZ_ASSERT_UNREACHABLE("Unknown `CryptoAlgorithmIdentifier` value"); + } + } +} + // clang-format off /// This table is from https://w3c.github.io/webcrypto/#h-note-15 // | Algorithm | encrypt | decrypt | sign | verify | digest | generateKey | deriveKey | deriveBits | importKey | exportKey | wrapKey | unwrapKey | @@ -499,9 +506,13 @@ std::unique_ptr CryptoAlgorithmDigest::normalize(JSContex // The table listed at https://w3c.github.io/webcrypto/#h-note-15 is what defines which algorithms support which operations // SHA-1, SHA-256, SHA-384, and SHA-512 are the only algorithms which support the digest operation + // We also support MD5 as an extra implementor defined algorithm // Note: The specification states that none of the SHA algorithms take any parameters -- https://w3c.github.io/webcrypto/#sha-registration switch (identifier) { + case CryptoAlgorithmIdentifier::MD5: { + return std::make_unique(); + } case CryptoAlgorithmIdentifier::SHA_1: { return std::make_unique(); } @@ -991,7 +1002,7 @@ JSObject *CryptoAlgorithmRSASSA_PKCS1_v1_5_Import::toObject(JSContext *cx) { // Set the hash attribute of algorithm to the hash member of normalizedAlgorithm. JS::RootedObject hash(cx, JS_NewObject(cx, nullptr)); - auto hash_name = JS_NewStringCopyZ(cx, algorithmName(this->hashIdentifier)); + auto hash_name = JS_NewStringCopyZ(cx, builtins::algorithmName(this->hashIdentifier)); if (!hash_name) { return nullptr; } @@ -1006,6 +1017,9 @@ JSObject *CryptoAlgorithmRSASSA_PKCS1_v1_5_Import::toObject(JSContext *cx) { return algorithm; } +JSObject *CryptoAlgorithmMD5::digest(JSContext *cx, std::span data) { + return ::builtins::digest(cx, data, EVP_md5(), MD5_DIGEST_LENGTH); +} JSObject *CryptoAlgorithmSHA1::digest(JSContext *cx, std::span data) { return ::builtins::digest(cx, data, EVP_sha1(), SHA_DIGEST_LENGTH); } diff --git a/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.h b/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.h index 58fa933cca..6496eb7bb1 100644 --- a/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.h +++ b/c-dependencies/js-compute-runtime/builtins/crypto-algorithm.h @@ -6,6 +6,7 @@ #include "crypto-key.h" #include "json-web-key.h" #include "openssl/evp.h" +#include namespace builtins { @@ -22,6 +23,7 @@ enum class CryptoAlgorithmIdentifier : uint8_t { AES_GCM, AES_KW, HMAC, + MD5, SHA_1, SHA_256, SHA_384, @@ -30,6 +32,8 @@ enum class CryptoAlgorithmIdentifier : uint8_t { PBKDF2 }; +const char *algorithmName(CryptoAlgorithmIdentifier algorithm); + /// The base class that all algorithm implementations should derive from. class CryptoAlgorithm { public: @@ -104,6 +108,13 @@ class CryptoAlgorithmDigest : public CryptoAlgorithm { static std::unique_ptr normalize(JSContext *cx, JS::HandleValue value); }; +class CryptoAlgorithmMD5 final : public CryptoAlgorithmDigest { +public: + const char *name() const noexcept override { return "MD5"; }; + CryptoAlgorithmIdentifier identifier() override { return CryptoAlgorithmIdentifier::MD5; }; + JSObject *digest(JSContext *cx, std::span) override; +}; + class CryptoAlgorithmSHA1 final : public CryptoAlgorithmDigest { public: const char *name() const noexcept override { return "SHA-1"; }; diff --git a/c-dependencies/js-compute-runtime/builtins/crypto-key.cpp b/c-dependencies/js-compute-runtime/builtins/crypto-key.cpp index 575182cd91..fecd152fab 100644 --- a/c-dependencies/js-compute-runtime/builtins/crypto-key.cpp +++ b/c-dependencies/js-compute-runtime/builtins/crypto-key.cpp @@ -6,82 +6,6 @@ namespace builtins { -namespace { -const char *algorithmName(CryptoAlgorithmIdentifier algorithm) { - const char *result = nullptr; - switch (algorithm) { - case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5: { - result = "RSASSA-PKCS1-v1_5"; - break; - } - case CryptoAlgorithmIdentifier::RSA_PSS: { - result = "RSA-PSS"; - break; - } - case CryptoAlgorithmIdentifier::RSA_OAEP: { - result = "RSA-OAEP"; - break; - } - case CryptoAlgorithmIdentifier::ECDSA: { - result = "ECDSA"; - break; - } - case CryptoAlgorithmIdentifier::ECDH: { - result = "ECDH"; - break; - } - case CryptoAlgorithmIdentifier::AES_CTR: { - result = "AES-CTR"; - break; - } - case CryptoAlgorithmIdentifier::AES_CBC: { - result = "AES-CBC"; - break; - } - case CryptoAlgorithmIdentifier::AES_GCM: { - result = "AES-GCM"; - break; - } - case CryptoAlgorithmIdentifier::AES_KW: { - result = "AES-KW"; - break; - } - case CryptoAlgorithmIdentifier::HMAC: { - result = "HMAC"; - break; - } - case CryptoAlgorithmIdentifier::SHA_1: { - result = "SHA-1"; - break; - } - case CryptoAlgorithmIdentifier::SHA_256: { - result = "SHA-256"; - break; - } - case CryptoAlgorithmIdentifier::SHA_384: { - result = "SHA-384"; - break; - } - case CryptoAlgorithmIdentifier::SHA_512: { - result = "SHA-512"; - break; - } - case CryptoAlgorithmIdentifier::HKDF: { - result = "HKDF"; - break; - } - case CryptoAlgorithmIdentifier::PBKDF2: { - result = "PBKDF2"; - break; - } - default: { - MOZ_ASSERT_UNREACHABLE("Unknown `CryptoAlgorithmIdentifier` value"); - } - } - return result; -} -} // namespace - CryptoKeyUsages::CryptoKeyUsages(uint8_t mask) { this->mask = mask; }; CryptoKeyUsages::CryptoKeyUsages(bool encrypt, bool decrypt, bool sign, bool verify, bool derive_key, bool derive_bits, bool wrap_key, diff --git a/documentation/docs/globals/SubtleCrypto/prototype/digest.mdx b/documentation/docs/globals/SubtleCrypto/prototype/digest.mdx index 10af5c85e9..4a937ea702 100644 --- a/documentation/docs/globals/SubtleCrypto/prototype/digest.mdx +++ b/documentation/docs/globals/SubtleCrypto/prototype/digest.mdx @@ -25,6 +25,7 @@ digest(algorithm, data) - `algorithm` - : This may be a string or an object with a single property `name` that is a string. The string names the hash function to use. Supported values are: + - `"MD5"` (but don't use this in cryptographic applications) - `"SHA-1"` (but don't use this in cryptographic applications) - `"SHA-256"` - `"SHA-384"` diff --git a/integration-tests/js-compute/fixtures/crypto/bin/index.js b/integration-tests/js-compute/fixtures/crypto/bin/index.js index 49d36ad344..f9e85004c9 100644 --- a/integration-tests/js-compute/fixtures/crypto/bin/index.js +++ b/integration-tests/js-compute/fixtures/crypto/bin/index.js @@ -562,6 +562,14 @@ routes.set("/crypto.subtle", async () => { } // happy paths { + // "MD5" + routes.set("/crypto.subtle.digest/md5", async () => { + const result = new Uint8Array(await crypto.subtle.digest("md5", new Uint8Array)); + const expected = new Uint8Array([212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126]); + error = assert(result, expected, "result deep equals expected"); + if (error) { return error; } + return pass(); + }); // "SHA-1" routes.set("/crypto.subtle.digest/sha-1", async () => { const result = new Uint8Array(await crypto.subtle.digest("sha-1", new Uint8Array)); diff --git a/integration-tests/js-compute/fixtures/decoder/bin/index.js b/integration-tests/js-compute/fixtures/decoder/bin/index.js new file mode 100644 index 0000000000..2f7d630a2a --- /dev/null +++ b/integration-tests/js-compute/fixtures/decoder/bin/index.js @@ -0,0 +1,8207 @@ +let array = [99, + 97, + 102, + 54, + 48, + 99, + 48, + 53, + 53, + 50, + 57, + 97, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 51, + 48, + 48, + 58, + 49, + 54, + 57, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 51, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 34, + 32, + 115, + 114, + 99, + 115, + 101, + 116, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 102, + 55, + 97, + 54, + 53, + 49, + 99, + 45, + 101, + 55, + 56, + 52, + 45, + 52, + 52, + 55, + 53, + 45, + 57, + 99, + 52, + 54, + 45, + 99, + 97, + 102, + 54, + 48, + 99, + 48, + 53, + 53, + 50, + 57, + 97, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 50, + 50, + 55, + 58, + 49, + 50, + 56, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 50, + 50, + 55, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 50, + 50, + 55, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 102, + 55, + 97, + 54, + 53, + 49, + 99, + 45, + 101, + 55, + 56, + 52, + 45, + 52, + 52, + 55, + 53, + 45, + 57, + 99, + 52, + 54, + 45, + 99, + 97, + 102, + 54, + 48, + 99, + 48, + 53, + 53, + 50, + 57, + 97, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 51, + 48, + 48, + 58, + 49, + 54, + 57, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 51, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 51, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 102, + 55, + 97, + 54, + 53, + 49, + 99, + 45, + 101, + 55, + 56, + 52, + 45, + 52, + 52, + 55, + 53, + 45, + 57, + 99, + 52, + 54, + 45, + 99, + 97, + 102, + 54, + 48, + 99, + 48, + 53, + 53, + 50, + 57, + 97, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 52, + 53, + 52, + 58, + 50, + 53, + 54, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 52, + 53, + 52, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 52, + 53, + 52, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 102, + 55, + 97, + 54, + 53, + 49, + 99, + 45, + 101, + 55, + 56, + 52, + 45, + 52, + 52, + 55, + 53, + 45, + 57, + 99, + 52, + 54, + 45, + 99, + 97, + 102, + 54, + 48, + 99, + 48, + 53, + 53, + 50, + 57, + 97, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 54, + 48, + 48, + 58, + 51, + 51, + 56, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 54, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 54, + 48, + 48, + 119, + 34, + 32, + 115, + 105, + 122, + 101, + 115, + 61, + 34, + 40, + 109, + 105, + 110, + 45, + 119, + 105, + 100, + 116, + 104, + 58, + 32, + 49, + 51, + 52, + 48, + 112, + 120, + 41, + 32, + 50, + 50, + 55, + 112, + 120, + 44, + 32, + 40, + 109, + 97, + 120, + 45, + 119, + 105, + 100, + 116, + 104, + 58, + 32, + 49, + 49, + 48, + 48, + 112, + 120, + 41, + 32, + 99, + 97, + 108, + 99, + 40, + 40, + 49, + 48, + 48, + 118, + 119, + 32, + 45, + 32, + 51, + 50, + 48, + 112, + 120, + 41, + 32, + 42, + 32, + 48, + 46, + 51, + 53, + 41, + 44, + 32, + 99, + 97, + 108, + 99, + 40, + 40, + 49, + 48, + 48, + 118, + 119, + 32, + 45, + 32, + 54, + 54, + 48, + 112, + 120, + 41, + 32, + 42, + 32, + 48, + 46, + 51, + 53, + 41, + 34, + 32, + 97, + 108, + 116, + 61, + 34, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 102, + 105, + 103, + 99, + 97, + 112, + 116, + 105, + 111, + 110, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 99, + 97, + 112, + 116, + 105, + 111, + 110, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 109, + 111, + 98, + 105, + 108, + 101, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 70, + 111, + 116, + 111, + 58, + 32, + 84, + 111, + 109, + 32, + 75, + 105, + 114, + 107, + 112, + 97, + 116, + 114, + 105, + 99, + 107, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 102, + 105, + 103, + 99, + 97, + 112, + 116, + 105, + 111, + 110, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 112, + 114, + 101, + 109, + 105, + 117, + 109, + 45, + 109, + 97, + 114, + 107, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 115, + 118, + 103, + 32, + 119, + 105, + 100, + 116, + 104, + 61, + 34, + 49, + 54, + 34, + 32, + 104, + 101, + 105, + 103, + 104, + 116, + 61, + 34, + 50, + 48, + 34, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 105, + 99, + 111, + 110, + 32, + 105, + 99, + 111, + 110, + 45, + 45, + 117, + 115, + 101, + 114, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 117, + 115, + 101, + 32, + 120, + 108, + 105, + 110, + 107, + 58, + 104, + 114, + 101, + 102, + 61, + 34, + 35, + 117, + 115, + 101, + 114, + 34, + 62, + 60, + 47, + 117, + 115, + 101, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 115, + 118, + 103, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 102, + 105, + 103, + 117, + 114, + 101, + 62, + 10, + 10, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 99, + 111, + 110, + 116, + 101, + 110, + 116, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 60, + 104, + 50, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 116, + 105, + 116, + 108, + 101, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 69, + 110, + 32, + 115, + 117, + 118, + 32, + 115, + 111, + 109, + 32, + 98, + 97, + 114, + 97, + 32, + 115, + 108, + 195, + 164, + 112, + 112, + 101, + 114, + 32, + 117, + 116, + 32, + 118, + 97, + 116, + 116, + 101, + 110, + 195, + 165, + 110, + 103, + 97, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 104, + 50, + 62, + 10, + 10, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 60, + 47, + 97, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 10, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 101, + 115, + 105, + 58, + 99, + 104, + 111, + 111, + 115, + 101, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 101, + 115, + 105, + 58, + 119, + 104, + 101, + 110, + 32, + 116, + 101, + 115, + 116, + 61, + 34, + 36, + 40, + 101, + 110, + 116, + 105, + 116, + 108, + 101, + 100, + 95, + 97, + 110, + 110, + 111, + 110, + 115, + 102, + 114, + 105, + 41, + 61, + 61, + 39, + 116, + 114, + 117, + 101, + 39, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 101, + 115, + 105, + 58, + 119, + 104, + 101, + 110, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 101, + 115, + 105, + 58, + 111, + 116, + 104, + 101, + 114, + 119, + 105, + 115, + 101, + 62, + 10, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 97, + 100, + 32, + 97, + 100, + 45, + 45, + 109, + 111, + 98, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 116, + 97, + 98, + 108, + 101, + 116, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 100, + 101, + 115, + 107, + 116, + 111, + 112, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 100, + 97, + 116, + 97, + 45, + 115, + 108, + 111, + 116, + 45, + 110, + 97, + 109, + 101, + 61, + 34, + 109, + 111, + 98, + 34, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 98, + 97, + 109, + 45, + 97, + 100, + 45, + 115, + 108, + 111, + 116, + 34, + 62, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 101, + 115, + 105, + 58, + 111, + 116, + 104, + 101, + 114, + 119, + 105, + 115, + 101, + 62, + 10, + 32, + 32, + 60, + 47, + 101, + 115, + 105, + 58, + 99, + 104, + 111, + 111, + 115, + 101, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 10, + 10, + 10, + 10, + 10, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 112, + 97, + 99, + 107, + 97, + 103, + 101, + 32, + 116, + 104, + 45, + 98, + 111, + 114, + 100, + 101, + 114, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 60, + 97, + 32, + 104, + 114, + 101, + 102, + 61, + 34, + 47, + 109, + 97, + 116, + 45, + 100, + 114, + 121, + 99, + 107, + 47, + 34, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 112, + 97, + 99, + 107, + 97, + 103, + 101, + 95, + 95, + 118, + 105, + 103, + 110, + 101, + 116, + 116, + 101, + 32, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 112, + 97, + 99, + 107, + 97, + 103, + 101, + 95, + 95, + 118, + 105, + 103, + 110, + 101, + 116, + 116, + 101, + 45, + 45, + 108, + 105, + 110, + 107, + 32, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 112, + 97, + 99, + 107, + 97, + 103, + 101, + 95, + 95, + 118, + 105, + 103, + 110, + 101, + 116, + 116, + 101, + 45, + 45, + 115, + 116, + 97, + 110, + 100, + 97, + 114, + 100, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 115, + 112, + 97, + 110, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 112, + 97, + 99, + 107, + 97, + 103, + 101, + 95, + 95, + 118, + 105, + 103, + 110, + 101, + 116, + 116, + 101, + 45, + 116, + 101, + 120, + 116, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 77, + 97, + 116, + 32, + 38, + 97, + 109, + 112, + 59, + 32, + 68, + 114, + 121, + 99, + 107, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 115, + 118, + 103, + 32, + 119, + 105, + 100, + 116, + 104, + 61, + 34, + 49, + 48, + 34, + 32, + 104, + 101, + 105, + 103, + 104, + 116, + 61, + 34, + 49, + 54, + 34, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 105, + 99, + 111, + 110, + 32, + 105, + 99, + 111, + 110, + 45, + 45, + 97, + 114, + 114, + 111, + 119, + 45, + 114, + 105, + 103, + 104, + 116, + 45, + 115, + 109, + 97, + 108, + 108, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 117, + 115, + 101, + 32, + 120, + 108, + 105, + 110, + 107, + 58, + 104, + 114, + 101, + 102, + 61, + 34, + 35, + 97, + 114, + 114, + 111, + 119, + 45, + 114, + 105, + 103, + 104, + 116, + 45, + 115, + 109, + 97, + 108, + 108, + 34, + 62, + 60, + 47, + 117, + 115, + 101, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 115, + 118, + 103, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 115, + 112, + 97, + 110, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 97, + 62, + 10, + 10, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 112, + 97, + 99, + 107, + 97, + 103, + 101, + 95, + 95, + 99, + 111, + 110, + 116, + 101, + 110, + 116, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 10, + 10, + 10, + 10, + 60, + 97, + 32, + 104, + 114, + 101, + 102, + 61, + 34, + 47, + 109, + 97, + 116, + 45, + 100, + 114, + 121, + 99, + 107, + 47, + 118, + 105, + 110, + 45, + 109, + 101, + 100, + 45, + 97, + 100, + 114, + 101, + 115, + 115, + 45, + 100, + 97, + 114, + 102, + 111, + 114, + 45, + 97, + 114, + 45, + 100, + 101, + 110, + 45, + 115, + 116, + 111, + 114, + 97, + 45, + 114, + 101, + 103, + 105, + 111, + 110, + 101, + 110, + 45, + 108, + 97, + 110, + 103, + 117, + 101, + 100, + 111, + 99, + 45, + 114, + 111, + 117, + 115, + 115, + 105, + 108, + 108, + 111, + 110, + 45, + 111, + 118, + 97, + 110, + 116, + 97, + 116, + 45, + 111, + 107, + 97, + 110, + 100, + 47, + 34, + 32, + 100, + 97, + 116, + 97, + 45, + 105, + 100, + 61, + 34, + 100, + 110, + 46, + 107, + 108, + 97, + 114, + 97, + 46, + 115, + 117, + 117, + 103, + 81, + 82, + 98, + 97, + 111, + 53, + 57, + 103, + 75, + 83, + 84, + 71, + 85, + 51, + 76, + 74, + 107, + 87, + 34, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 32, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 45, + 108, + 97, + 114, + 103, + 101, + 32, + 32, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 45, + 102, + 105, + 114, + 115, + 116, + 32, + 116, + 101, + 97, + 115, + 101, + 114, + 45, + 45, + 108, + 97, + 115, + 116, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 60, + 102, + 105, + 103, + 117, + 114, + 101, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 105, + 109, + 103, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 32, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 45, + 45, + 112, + 108, + 97, + 99, + 101, + 104, + 111, + 108, + 100, + 101, + 114, + 32, + 32, + 108, + 97, + 122, + 121, + 45, + 105, + 109, + 97, + 103, + 101, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 116, + 97, + 98, + 108, + 101, + 116, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 100, + 101, + 115, + 107, + 116, + 111, + 112, + 34, + 32, + 115, + 116, + 121, + 108, + 101, + 61, + 34, + 112, + 97, + 100, + 100, + 105, + 110, + 103, + 45, + 98, + 111, + 116, + 116, + 111, + 109, + 58, + 53, + 54, + 46, + 50, + 53, + 37, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 105, + 109, + 103, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 95, + 95, + 105, + 109, + 103, + 34, + 32, + 115, + 114, + 99, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 52, + 50, + 53, + 58, + 50, + 52, + 48, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 52, + 50, + 53, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 34, + 32, + 115, + 114, + 99, + 115, + 101, + 116, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 51, + 48, + 48, + 58, + 49, + 54, + 57, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 51, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 51, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 51, + 53, + 53, + 58, + 50, + 48, + 48, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 51, + 53, + 53, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 51, + 53, + 53, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 52, + 50, + 53, + 58, + 50, + 52, + 48, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 52, + 50, + 53, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 52, + 50, + 53, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 54, + 48, + 48, + 58, + 51, + 51, + 56, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 54, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 54, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 55, + 49, + 48, + 58, + 52, + 48, + 48, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 55, + 49, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 55, + 49, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 56, + 53, + 48, + 58, + 52, + 55, + 57, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 56, + 53, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 56, + 53, + 48, + 119, + 34, + 32, + 115, + 105, + 122, + 101, + 115, + 61, + 34, + 99, + 97, + 108, + 99, + 40, + 49, + 48, + 48, + 118, + 119, + 32, + 45, + 32, + 50, + 48, + 112, + 120, + 41, + 34, + 32, + 97, + 108, + 116, + 61, + 34, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 32, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 45, + 45, + 112, + 108, + 97, + 99, + 101, + 104, + 111, + 108, + 100, + 101, + 114, + 32, + 32, + 108, + 97, + 122, + 121, + 45, + 105, + 109, + 97, + 103, + 101, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 109, + 111, + 98, + 105, + 108, + 101, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 100, + 101, + 115, + 107, + 116, + 111, + 112, + 34, + 32, + 115, + 116, + 121, + 108, + 101, + 61, + 34, + 112, + 97, + 100, + 100, + 105, + 110, + 103, + 45, + 98, + 111, + 116, + 116, + 111, + 109, + 58, + 53, + 54, + 46, + 50, + 53, + 37, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 105, + 109, + 103, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 95, + 95, + 105, + 109, + 103, + 34, + 32, + 115, + 114, + 99, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 55, + 48, + 48, + 58, + 51, + 57, + 52, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 55, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 34, + 32, + 115, + 114, + 99, + 115, + 101, + 116, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 53, + 48, + 48, + 58, + 50, + 56, + 50, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 53, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 53, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 54, + 48, + 48, + 58, + 51, + 51, + 56, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 54, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 54, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 55, + 48, + 48, + 58, + 51, + 57, + 52, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 55, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 55, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 49, + 48, + 48, + 48, + 58, + 53, + 54, + 51, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 49, + 48, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 49, + 48, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 49, + 50, + 48, + 48, + 58, + 54, + 55, + 53, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 49, + 50, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 49, + 50, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 49, + 52, + 48, + 48, + 58, + 55, + 56, + 56, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 49, + 52, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 49, + 52, + 48, + 48, + 119, + 34, + 32, + 115, + 105, + 122, + 101, + 115, + 61, + 34, + 54, + 54, + 118, + 119, + 34, + 32, + 97, + 108, + 116, + 61, + 34, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 32, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 45, + 45, + 112, + 108, + 97, + 99, + 101, + 104, + 111, + 108, + 100, + 101, + 114, + 32, + 32, + 108, + 97, + 122, + 121, + 45, + 105, + 109, + 97, + 103, + 101, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 109, + 111, + 98, + 105, + 108, + 101, + 32, + 104, + 105, + 100, + 100, + 101, + 110, + 45, + 116, + 97, + 98, + 108, + 101, + 116, + 34, + 32, + 115, + 116, + 121, + 108, + 101, + 61, + 34, + 112, + 97, + 100, + 100, + 105, + 110, + 103, + 45, + 98, + 111, + 116, + 116, + 111, + 109, + 58, + 53, + 54, + 46, + 50, + 53, + 37, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 105, + 109, + 103, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 112, + 105, + 99, + 116, + 117, + 114, + 101, + 95, + 95, + 105, + 109, + 103, + 34, + 32, + 115, + 114, + 99, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 54, + 52, + 57, + 58, + 51, + 54, + 54, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 54, + 52, + 57, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 34, + 32, + 115, + 114, + 99, + 115, + 101, + 116, + 61, + 34, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 52, + 52, + 48, + 58, + 50, + 52, + 56, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 52, + 52, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 52, + 52, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 53, + 53, + 48, + 58, + 51, + 49, + 48, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 53, + 53, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 53, + 53, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 54, + 52, + 57, + 58, + 51, + 54, + 54, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 54, + 52, + 57, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 56, + 48, + 32, + 54, + 52, + 57, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 56, + 56, + 48, + 58, + 52, + 57, + 53, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 56, + 56, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 56, + 56, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 49, + 49, + 48, + 48, + 58, + 54, + 49, + 57, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 49, + 49, + 48, + 48, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 49, + 49, + 48, + 48, + 119, + 44, + 32, + 104, + 116, + 116, + 112, + 115, + 58, + 47, + 47, + 99, + 97, + 99, + 104, + 101, + 100, + 45, + 105, + 109, + 97, + 103, + 101, + 115, + 46, + 98, + 111, + 110, + 110, + 105, + 101, + 114, + 46, + 110, + 101, + 119, + 115, + 47, + 103, + 99, + 115, + 47, + 98, + 105, + 108, + 100, + 101, + 114, + 47, + 100, + 110, + 45, + 109, + 108, + 121, + 47, + 99, + 50, + 53, + 99, + 101, + 53, + 57, + 102, + 45, + 97, + 97, + 48, + 48, + 45, + 52, + 100, + 57, + 99, + 45, + 56, + 56, + 100, + 100, + 45, + 56, + 57, + 53, + 56, + 55, + 55, + 51, + 51, + 51, + 49, + 54, + 52, + 46, + 106, + 112, + 101, + 103, + 63, + 105, + 110, + 116, + 101, + 114, + 112, + 111, + 108, + 97, + 116, + 105, + 111, + 110, + 61, + 108, + 97, + 110, + 99, + 122, + 111, + 115, + 45, + 110, + 111, + 110, + 101, + 38, + 97, + 109, + 112, + 59, + 102, + 105, + 116, + 61, + 97, + 114, + 111, + 117, + 110, + 100, + 37, + 55, + 67, + 49, + 50, + 57, + 56, + 58, + 55, + 51, + 49, + 38, + 97, + 109, + 112, + 59, + 99, + 114, + 111, + 112, + 61, + 49, + 50, + 57, + 56, + 58, + 104, + 59, + 99, + 101, + 110, + 116, + 101, + 114, + 44, + 116, + 111, + 112, + 38, + 97, + 109, + 112, + 59, + 111, + 117, + 116, + 112, + 117, + 116, + 45, + 113, + 117, + 97, + 108, + 105, + 116, + 121, + 61, + 54, + 48, + 32, + 49, + 50, + 57, + 56, + 119, + 34, + 32, + 115, + 105, + 122, + 101, + 115, + 61, + 34, + 40, + 109, + 105, + 110, + 45, + 119, + 105, + 100, + 116, + 104, + 58, + 32, + 49, + 51, + 52, + 48, + 112, + 120, + 41, + 32, + 54, + 52, + 57, + 112, + 120, + 44, + 32, + 40, + 109, + 97, + 120, + 45, + 119, + 105, + 100, + 116, + 104, + 58, + 32, + 49, + 49, + 48, + 48, + 112, + 120, + 41, + 32, + 99, + 97, + 108, + 99, + 40, + 49, + 48, + 48, + 118, + 119, + 32, + 45, + 32, + 51, + 50, + 48, + 112, + 120, + 41, + 44, + 32, + 99, + 97, + 108, + 99, + 40, + 49, + 48, + 48, + 118, + 119, + 32, + 45, + 32, + 54, + 57, + 48, + 112, + 120, + 41, + 34, + 32, + 97, + 108, + 116, + 61, + 34, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 110, + 111, + 115, + 99, + 114, + 105, + 112, + 116, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 102, + 105, + 103, + 99, + 97, + 112, + 116, + 105, + 111, + 110, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 99, + 97, + 112, + 116, + 105, + 111, + 110, + 34, + 32, + 97, + 114, + 105, + 97, + 45, + 104, + 105, + 100, + 100, + 101, + 110, + 61, + 34, + 116, + 114, + 117, + 101, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 70, + 111, + 116, + 111, + 58, + 32, + 77, + 105, + 99, + 107, + 97, + 110, + 32, + 80, + 97, + 108, + 109, + 113, + 118, + 105, + 115, + 116, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 47, + 102, + 105, + 103, + 99, + 97, + 112, + 116, + 105, + 111, + 110, + 62, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 102, + 105, + 103, + 117, + 114, + 101, + 62, + 10, + 10, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 99, + 111, + 110, + 116, + 101, + 110, + 116, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 100, + 105, + 118, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 118, + 105, + 103, + 110, + 101, + 116, + 116, + 101, + 32, + 116, + 104, + 45, + 116, + 101, + 120, + 116, + 34, + 62, + 86, + 73, + 78, + 83, + 75, + 79, + 76, + 65, + 78, + 60, + 47, + 100, + 105, + 118, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 60, + 104, + 50, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 116, + 105, + 116, + 108, + 101, + 32, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 116, + 105, + 116, + 108, + 101, + 45, + 45, + 108, + 97, + 114, + 103, + 101, + 34, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 68, + 195, + 164, + 114, + 102, + 195, + 182, + 114, + 32, + 195, + 164, + 114, + 32, + 100, + 101, + 110, + 32, + 115, + 116, + 111, + 114, + 97, + 32, + 114, + 101, + 103, + 105, + 111, + 110, + 101, + 110, + 32, + 111, + 118, + 195, + 164, + 110, + 116, + 97, + 116, + 32, + 111, + 107, + 195, + 164, + 110, + 100, + 10, + 32, + 32, + 32, + 32, + 60, + 47, + 104, + 50, + 62, + 10, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 60, + 112, + 62, + 10, + 32, + 32, + 60, + 115, + 112, + 97, + 110, + 32, + 99, + 108, + 97, + 115, + 115, + 61, + 34, + 116, + 101, + 97, + 115, + 101, + 114, + 95, + 95, + 100, + 111, + 116, + 32, + 116, + 104, + 45, + 98, + 103, + 34, + 62, + 60, + 47, + 115, + 112, + 97, + 110, + 62, + 10, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 83, + 116, + 195, + 165, + 114, + 32, + 102, + 195, + 182, + 114, + 32, + 110, + 195, + 164, + 115, + 116, + 97, + 110, + 32, + 104, + 195, + 164, + 108, + 102, + 116, + 101, + 110, + 32, + 97, + 118, + 32, + 70, + 114, + 97, + 110, + 107, + 114, + 105, + 107, + 101, + 115, + 32, + 118, + 105, + 110, + 112, + 114, + 111, + 100, + 117, + 107, + 116, + 105, + 111, + 110, + 32, + 226, + 128 +]; + +addEventListener("fetch", + event => { + let utf8decoder = new TextDecoder('utf-8', {fatal: false, ignoreBOM: false}); // default 'utf-8' or 'utf8' + let u8arr = new Uint8Array(array); + let i = 10000; + while (i--) { + console.log(i) + console.log(u8arr.length); + console.log(utf8decoder.decode(u8arr).length); + } + + event.respondWith(new Response('meow')); +}); \ No newline at end of file diff --git a/integration-tests/js-compute/fixtures/decoder/fastly.toml.in b/integration-tests/js-compute/fixtures/decoder/fastly.toml.in new file mode 100644 index 0000000000..35b8e93389 --- /dev/null +++ b/integration-tests/js-compute/fixtures/decoder/fastly.toml.in @@ -0,0 +1,12 @@ +# This file describes a Fastly Compute@Edge package. To learn more visit: +# https://developer.fastly.com/reference/fastly-toml/ + +authors = ["jchampion@fastly.com"] +description = "" +language = "other" +manifest_version = 3 +name = "array" +service_id = "" + +[scripts] + build = "node ../../../../js-compute-runtime-cli.js" diff --git a/integration-tests/js-compute/fixtures/decoder/tests.json b/integration-tests/js-compute/fixtures/decoder/tests.json new file mode 100644 index 0000000000..fcbc662a53 --- /dev/null +++ b/integration-tests/js-compute/fixtures/decoder/tests.json @@ -0,0 +1,56 @@ +{ + "GET /": { + "environments": ["viceroy"], + "downstream_request": { + "method": "GET", + "pathname": "/" + }, + "downstream_response": { + "status": 200 + }, + "logs": [ + "stdout :: Log: Happy birthday Aki and Yuki!", + "stdout :: Log: Map: Map(2) { { a: 1, b: { c: 2 } } => 2, [Function foo] => {} }", + "stdout :: Log: Set: Set(3) { { a: 1, b: { c: 2 } }, 2, 3 }", + "stdout :: Log: Array: [1, 2, 3, [], 5]", + "stdout :: Log: Object: { a: 1, b: 2, c: 3, d: [Function d], f: [Getter], g: [Function bar] }", + "stdout :: Log: function: [Function]", + "stdout :: Log: boolean: true", + "stdout :: Log: undefined: undefined", + "stdout :: Log: null: null", + "stdout :: Log: proxy: { a: 21 }", + "stdout :: Log: Infinity: Infinity", + "stdout :: Log: NaN: NaN", + "stdout :: Log: Symbol: Symbol(\"wow\")", + "stdout :: Log: Error: (new Error(\"uh oh\", \"\", 40))", + "stdout :: Log: Number: 1", + "stdout :: Log: Number: 1.111", + "stdout :: Log: BigInt: 10n", + "stdout :: Log: Date: new Date(1660816667120)", + "stdout :: Log: string: cake", + "stdout :: Log: RegExp: /magic/", + "stdout :: Log: Int8Array: Int8Array [1, 3, 4, 2, 5, 6, -97]", + "stdout :: Log: Uint8Array: Uint8Array [1, 3, 4, 2, 5, 6, 159]", + "stdout :: Log: Uint8ClampedArray: Uint8ClampedArray [1, 3, 4, 2, 5, 6, 255]", + "stdout :: Log: Int16Array: Int16Array [1, 3, 4, 2, 5, 6, -31073]", + "stdout :: Log: Uint16Array: Uint16Array [1, 3, 4, 2, 5, 6, 34463]", + "stdout :: Log: Int32Array: Int32Array [1, 3, 4, 2, 5, 6, 99999]", + "stdout :: Log: Uint32Array: Uint32Array [1, 3, 4, 2, 5, 6, 99999]", + "stdout :: Log: Float32Array: Float32Array [1, 3, 4, 2, 5, 6, 99999]", + "stdout :: Log: Float64Array: Float64Array [1, 3, 4, 2, 5, 6, 99999]", + "stdout :: Log: BigInt64Array: BigInt64Array [1n, 3n, 4n, 2n, 5n, 6n, 99999n]", + "stdout :: Log: BigUint64Array: BigUint64Array [1n, 3n, 4n, 2n, 5n, 6n, 99999n]", + "stdout :: Log: WeakMap: WeakMap { }", + "stdout :: Log: WeakSet: WeakSet { }", + "stdout :: Log: Promise: Promise { }", + "stdout :: Log: resolved promise: Promise { 9 }", + "stdout :: Log: rejected promise: Promise { (new Error(\"oops\", \"\", 85)) }", + "stdout :: Log: Response: Response { type: \"default\", url: \"\", status: 200, ok: true, statusText: \"\", version: 2, headers: Headers {}, body: ReadableStream { locked: false }, bodyUsed: false }", + "stdout :: Log: Request: Request { method: \"POST\", url: \"https://www.fastly.com/\", version: 2, headers: Headers {}, body: null, bodyUsed: false }", + "stdout :: Log: ReadableStream: ReadableStream { locked: false }", + "stdout :: Log: TransformStream: TransformStream { readable: ReadableStream { locked: false }, writable: WritableStream {} }", + "stdout :: Log: WritableStream: WritableStream {}", + "stdout :: Log: URL: URL { hash: \"\", host: \"www.test.com:123\", hostname: \"www.test.com\", href: \"https://www.test.com:123/asdf?some¶ms=val\", origin: \"https://www.test.com:123\", password: \"\", pathname: \"/asdf\", port: \"123\", protocol: \"https:\", search: \"?some¶ms=val\", searchParams: URLSearchParams {}, username: \"\" }" + ] + } +}